Upgrade to Pro — share decks privately, control downloads, hide ads and more …

はてなにおけるモダンiOSアプリ開発入門

Avatar for cockscomb cockscomb
November 27, 2013

 はてなにおけるモダンiOSアプリ開発入門

Hatena Engineer Seminar #2 で発表した際のスライドです。
はてなにおけるiOSアプリ開発を説明しました。

Avatar for cockscomb

cockscomb

November 27, 2013
Tweet

More Decks by cockscomb

Other Decks in Programming

Transcript

  1. ࣮ફతͳαϯϓϧίʔυ CocoaPods AFNetworking UIStoryboard Auto Layout NSLayoutConstraint Key Value Observation

    blocks UITableViewController NSNotification Center isEqual: overriding appledoc …
  2. @property (weak, nonatomic) IBOutlet UITextView *textView; ! ! ! -

    (void)keyboardWillChangeFrame:(NSNotification *)notification { CGRect keyboardRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; keyboardRect = [self.view convertRect:keyboardRect fromView:nil]; double animationDuration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; ! CGFloat keyboardHeight = self.view.bounds.size.height - keyboardRect.origin.y; CGRect newRect = self.view.bounds; newRect.size.height -= keyboardHeight; ! [UIView animateWithDuration:animationDuration animations:^{ self.textView.frame = newRect; }]; } Before
  3. @property (weak, nonatomic) IBOutlet NSLayoutConstraint *keyboardHeight; ! ! ! -

    (void)keyboardWillChangeFrame:(NSNotification *)notification { ... ! CGFloat keyboardHeight = self.view.bounds.size.height - keyboardRect.origin.y; self.keyboardHeight.constant = -keyboardHeight; ! [UIView animateWithDuration:animationDuration animations:^{ [self.view layoutIfNeeded]; }]; } After
  4. TableViewController [[IBKMBookmarkManager sharedManager] reloadBookmarksWithBlock:^(NSError *error) { if (error) { NSLog(@"Error:

    %@", error); } [self.tableView reloadData]; }]; खͰஸೡʹUITableViewʹ൓өͤ͞ΔͷΛ΍Ί͍ͨ
  5. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if

    (object == [IBKMBookmarkManager sharedManager] && [keyPath isEqualToString:@"bookmarks"]) { NSIndexSet *indexSet = change[NSKeyValueChangeIndexesKey]; NSKeyValueChange changeKind = (NSKeyValueChange)[change[NSKeyValueChangeKindKey] integerValue]; ! NSMutableArray *indexPaths = [NSMutableArray array]; [indexSet enumerateIndexesUsingBlock:^(NSUInteger index, BOOL *stop) { [indexPaths addObject:[NSIndexPath indexPathForRow:index inSection:0]]; }]; ! [self.tableView beginUpdates]; if (changeKind == NSKeyValueChangeInsertion) { [self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic]; } else if (changeKind == NSKeyValueChangeRemoval) { [self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic]; } else if (changeKind == NSKeyValueChangeReplacement) { [self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic]; } [self.tableView endUpdates]; } }
  6. context(@"Fetching service data", ^{ it(@"should receive data within one second",

    ^{ __block NSData *fetchData = nil; NSURLRequest *request = [NSURLRequest requestWithURL: [NSURL URLWithString:@"http://www.hatena.ne.jp/"]]; ! [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { fetchData = data; } ]; [[expectFutureValue(fetchData) shouldEventually] beNonNil]; }); });