Slide 1

Slide 1 text

Macoun ⌘ Vorbereitung: 1. Demos, Files im Finder anordnen. 2. Alle Programme die man für Demos benötigt vorher(!) starten. Bpsw: Xcode, Terminal, Refelection. 3. Präsentation starten und auf Zeichen oder Signal warten. Samstag, 5. Oktober 13

Slide 2

Slide 2 text

Schlanke View Controller Chris Eidhof Den Titel der Session und darunter den eigenen Namen eintragen. Logo links oben anstatt dem Platzhalter. Nur auf diesem Slide! Samstag, 5. Oktober 13

Slide 3

Slide 3 text

WERBUNG Verkaufe Gouda im Wohnwagen Samstag, 5. Oktober 13

Slide 4

Slide 4 text

UITabellenAnzeigerAbgeordnete Samstag, 5. Oktober 13

Slide 5

Slide 5 text

Was ist die größte Datei in deinem Projekt? Samstag, 5. Oktober 13

Slide 6

Slide 6 text

Was ist die größte Datei in deinem Projekt? 0 200 400 600 800 Samstag, 5. Oktober 13

Slide 7

Slide 7 text

(image by Manu Cornet) Samstag, 5. Oktober 13

Slide 8

Slide 8 text

(image by Manu Cornet) Samstag, 5. Oktober 13

Slide 9

Slide 9 text

View Controller sind nicht wiederverwendbar Samstag, 5. Oktober 13

Slide 10

Slide 10 text

find . -name "*.m" -exec wc -l "{}" \; | sort -n Samstag, 5. Oktober 13

Slide 11

Slide 11 text

154 ./ViewControllers/THUserPrioritiesViewController.m 154 ./ViewControllers/THZoomingNavigationController.m 155 ./Extensions/NSArray+Extensions.m 155 ./Extensions/UIView+Extensions.m 168 ./Controllers/THPriorityTimelineCollectionController.m 179 ./Controllers/THUserScreenInstancesController.m 183 ./ViewControllers/THRootViewController.m 183 ./ViewControllers/THScreenInstanceViewController.m 185 ./Model/User+Extensions.m 192 ./ViewControllers/THEditPriorityViewController.m 221 ./ViewControllers/THScreeningBarViewController.m 243 ./Views/THTimeLineView.m 263 ./ViewControllers/THCardsViewController.m 279 ./Views/THSkillboxView.m Samstag, 5. Oktober 13

Slide 12

Slide 12 text

154 ./ViewControllers/THUserPrioritiesViewController.m 154 ./ViewControllers/THZoomingNavigationController.m 155 ./Extensions/NSArray+Extensions.m 155 ./Extensions/UIView+Extensions.m 168 ./Controllers/THPriorityTimelineCollectionController.m 179 ./Controllers/THUserScreenInstancesController.m 183 ./ViewControllers/THRootViewController.m 183 ./ViewControllers/THScreenInstanceViewController.m 185 ./Model/User+Extensions.m 192 ./ViewControllers/THEditPriorityViewController.m 221 ./ViewControllers/THScreeningBarViewController.m 243 ./Views/THTimeLineView.m 263 ./ViewControllers/THCardsViewController.m 279 ./Views/THSkillboxView.m Samstag, 5. Oktober 13

Slide 13

Slide 13 text

512 ./Classes/LessonResultViewController.m 514 ./Classes/Libs/ASIHTTPRequest/ASIDownloadCache.m 598 ./Classes/MainViewController.m 605 ./Classes/GameStartViewController.m 803 ./Classes/ResultViewController.m 818 ./Classes/RootViewController.m 1000 ./Classes/RankingViewController.m 1465 ./Classes/QuestionViewController.m 1590 ./Classes/REDACTEDAppDelegate.m 5125 ./Classes/Libs/ASIHTTPRequest/ASIHTTPRequest.m Samstag, 5. Oktober 13

Slide 14

Slide 14 text

... na gut, aber das ist ein wichtiger View Controller... Samstag, 5. Oktober 13

Slide 15

Slide 15 text

STEPS Project Komplettes Betriebssystem in < 20K Zeilen Samstag, 5. Oktober 13

Slide 16

Slide 16 text

Was können wir tun? Samstag, 5. Oktober 13

Slide 17

Slide 17 text

Ein View Controller vermittelt zwischen Modell und View Samstag, 5. Oktober 13

Slide 18

Slide 18 text

Modelllogik Samstag, 5. Oktober 13

Slide 19

Slide 19 text

Viewlogik Samstag, 5. Oktober 13

Slide 20

Slide 20 text

Layout Samstag, 5. Oktober 13

Slide 21

Slide 21 text

Webservice Samstag, 5. Oktober 13

Slide 22

Slide 22 text

View Controller Modell Child View Controller Webservice Samstag, 5. Oktober 13

Slide 23

Slide 23 text

Demo Samstag, 5. Oktober 13

Slide 24

Slide 24 text

View Controller Modell Child View Controller Webservice Samstag, 5. Oktober 13

Slide 25

Slide 25 text

View Controller Modell Child View Controller Webservice Samstag, 5. Oktober 13

Slide 26

Slide 26 text

View Controller Modell Child View Controller Webservice Samstag, 5. Oktober 13

Slide 27

Slide 27 text

Modelllogik Entweder im Modell oder in einer separaten Klasse Samstag, 5. Oktober 13

Slide 28

Slide 28 text

18 ./NestedTodoList/main.m 30 ./Item.m 31 ./NestedTodoList/Store.m 49 ./NestedTodoList/PersistentStack.m 52 ./NestedTodoList/AppDelegate.m 255 ./NestedTodoList/ItemViewController.m Beispielprojekt Samstag, 5. Oktober 13

Slide 29

Slide 29 text

18 ./NestedTodoList/main.m 30 ./Item.m 31 ./NestedTodoList/Store.m 49 ./NestedTodoList/PersistentStack.m 52 ./NestedTodoList/AppDelegate.m 255 ./NestedTodoList/ItemViewController.m Beispielprojekt Samstag, 5. Oktober 13

Slide 30

Slide 30 text

Verantwortlichkeiten •Views konfigurieren •Table View Delegate •Table View Datasource •Fetched Results Controller Delegate •Items hinzufügen •Items löschen Samstag, 5. Oktober 13

Slide 31

Slide 31 text

} Separate Klasse Verantwortlichkeiten •Views konfigurieren •Table View Delegate •Table View Datasource •Fetched Results Controller Delegate •Items hinzufügen •Items löschen Samstag, 5. Oktober 13

Slide 32

Slide 32 text

} Separate Klasse Verantwortlichkeiten •Views konfigurieren •Table View Delegate •Table View Datasource •Fetched Results Controller Delegate •Items hinzufügen •Items löschen } Modell Samstag, 5. Oktober 13

Slide 33

Slide 33 text

- (BOOL)textFieldShouldReturn:(UITextField*)t { NSString* title = t.text; NSUInteger order = self.parent.children.count; Item* item = [NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext:self.moc]; item.title = title; item.parent = self.parent; item.order = @(order); ... } Modell Samstag, 5. Oktober 13

Slide 34

Slide 34 text

- (BOOL)textFieldShouldReturn:(UITextField*)t { NSString* title = t.text; NSUInteger order = self.parent.children.count; [Item insertItemWithTitle:title parent:self.parent inManagedObjectContext:self.moc]; ... } Modell Samstag, 5. Oktober 13

Slide 35

Slide 35 text

- (void)deleteItem:(id)object { Item* item = object; NSSet* siblings = item.parent.children; NSPredicate* predicate = [NSPredicate predicateWithFormat:@"order > %@", item.order]; NSSet* itemsAfterSelf = [siblings filteredSetUsingPredicate:predicate]; [itemsAfterSelf enumerateObjectsUsingBlock:^(Item* sibling, BOOL* stop) { sibling.order = @(sibling.order.integerValue - 1); }]; [item.moc deleteObject:item]; } Samstag, 5. Oktober 13

Slide 36

Slide 36 text

- (void)deleteItem:(id)object { Item* item = object; NSSet* siblings = item.parent.children; NSPredicate* predicate = [NSPredicate predicateWithFormat:@"order > %@", item.order]; NSSet* itemsAfterSelf = [siblings filteredSetUsingPredicate:predicate]; [itemsAfterSelf enumerateObjectsUsingBlock:^(Item* sibling, BOOL* stop) { sibling.order = @(sibling.order.integerValue - 1); }]; [item.moc deleteObject:item]; } Samstag, 5. Oktober 13

Slide 37

Slide 37 text

- (void)prepareForDeletion { NSSet* siblings = self.parent.children; NSPredicate* p = [NSPredicate predicateWithFormat:@"order > %@", self.order]; NSSet* itemsAfterSelf = [siblings filteredSetUsingPredicate:p]; [itemsAfterSelf enumerateObjectsUsingBlock: ^(Item* sibling, BOOL* stop) { sibling.order = @(sibling.order.integerValue - 1); }]; } Samstag, 5. Oktober 13

Slide 38

Slide 38 text

18 ./NestedTodoList/main.m 31 ./NestedTodoList/Store.m 49 ./NestedTodoList/PersistentStack.m 52 ./NestedTodoList/AppDelegate.m 54 ./Item.m 241 ./NestedTodoList/ItemViewController.m Beispielprojekt Samstag, 5. Oktober 13

Slide 39

Slide 39 text

18 ./NestedTodoList/main.m 31 ./NestedTodoList/Store.m 49 ./NestedTodoList/PersistentStack.m 52 ./NestedTodoList/AppDelegate.m 54 ./Item.m 241 ./NestedTodoList/ItemViewController.m Beispielprojekt Samstag, 5. Oktober 13

Slide 40

Slide 40 text

View Controller Modell Child View Controller Webservice UITableViewDS Samstag, 5. Oktober 13

Slide 41

Slide 41 text

View Controller Modell Child View Controller Webservice UITableViewDS Samstag, 5. Oktober 13

Slide 42

Slide 42 text

@interface FetchedResultsControllerDataSource : NSObject Samstag, 5. Oktober 13

Slide 43

Slide 43 text

- (NSInteger)numberOfSectionsInTableView:(UITableView*)t { return self.fetchedResultsController.sections.count; } Samstag, 5. Oktober 13

Slide 44

Slide 44 text

- (NSInteger)tableView:(UITableView*)t numberOfRowsInSection:(NSInteger)s { id section = self.fetchedResultsController.sections[s]; return section.numberOfObjects; } Samstag, 5. Oktober 13

Slide 45

Slide 45 text

- (UITableViewCell*)tableView:(UITableView*)t cellForRowAtIndexPath:(NSIndexPath*)ip ? Samstag, 5. Oktober 13

Slide 46

Slide 46 text

#pragma mark NSFetchedResultsControllerDelegate Samstag, 5. Oktober 13

Slide 47

Slide 47 text

- (void)controller:(NSFetchedResultsController*)c didChangeObject:(id)anObject atIndexPath:(NSIndexPath*)indexPath forChangeType:(NSFetchedResultsChangeType)ct newIndexPath:(NSIndexPath*)newIndexPath Samstag, 5. Oktober 13

Slide 48

Slide 48 text

@property (nonatomic, weak) id delegate; Samstag, 5. Oktober 13

Slide 49

Slide 49 text

- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath { id object = [self.frc objectAtIndexPath:indexPath]; id cell = [tableView dequeueReusableCellWithIdentifier:self.reuseIdentifier forIndexPath:indexPath]; [self.delegate configureCell:cell withObject:object]; return cell; } Samstag, 5. Oktober 13

Slide 50

Slide 50 text

- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath { id object = [self.frc objectAtIndexPath:indexPath]; id cell = [tableView dequeueReusableCellWithIdentifier:self.reuseIdentifier forIndexPath:indexPath]; [self.delegate configureCell:cell withObject:object]; return cell; } Samstag, 5. Oktober 13

Slide 51

Slide 51 text

Demo Samstag, 5. Oktober 13

Slide 52

Slide 52 text

25 ./NestedTodoList/Store.m 49 ./NestedTodoList/PersistentStack.m 52 ./NestedTodoList/AppDelegate.m 64 ./Item.m 111 ./NestedTodoList/FRCDataSource.m 162 ./NestedTodoList/ItemViewController.m Beispielprojekt Samstag, 5. Oktober 13

Slide 53

Slide 53 text

25 ./NestedTodoList/Store.m 49 ./NestedTodoList/PersistentStack.m 52 ./NestedTodoList/AppDelegate.m 64 ./Item.m 111 ./NestedTodoList/FRCDataSource.m 162 ./NestedTodoList/ItemViewController.m Beispielprojekt Samstag, 5. Oktober 13

Slide 54

Slide 54 text

Wiederverwendbarkeit Samstag, 5. Oktober 13

Slide 55

Slide 55 text

Oder eine Oberklasse? Samstag, 5. Oktober 13

Slide 56

Slide 56 text

Nachteile von Oberklassen Es gibt nur eine Oberklasse Schwerer zu wechseln, z.B. von UITableView nach UICollectionView Fehleranfälliger: z.B. super calls vergessen Samstag, 5. Oktober 13

Slide 57

Slide 57 text

Andere Kandidaten UICollectionViewDataSource UIPageViewControllerDataSource UIPickerViewDataSource Samstag, 5. Oktober 13

Slide 58

Slide 58 text

Mehr Kandidaten UICollectionViewDelegate UIScrollViewDelegate UITableViewDelegate UITableViewDelegate UITextFieldDelegate UINavigationControllerDelegate Samstag, 5. Oktober 13

Slide 59

Slide 59 text

View Controller Modell Child View Controller Webservice Samstag, 5. Oktober 13

Slide 60

Slide 60 text

View Controller Modell Child View Controller Webservice Samstag, 5. Oktober 13

Slide 61

Slide 61 text

- (UITableViewCell*)tableView:(UITableView*)t cellForRowAtIndexPath:(NSIndexPath*)ip Samstag, 5. Oktober 13

Slide 62

Slide 62 text

@interface PhotoCell (ConfigureForPhoto) - (void)configureForPhoto:(Photo *)photo; @end PhotoCell+ConfigureForPhoto.h Samstag, 5. Oktober 13

Slide 63

Slide 63 text

UITableViewController •Löscht Selektion •Daten neu laden •Scroll indicators zeigen •Editieren •Scrollen zum first responder •Refresh control •.... Samstag, 5. Oktober 13

Slide 64

Slide 64 text

Samstag, 5. Oktober 13

Slide 65

Slide 65 text

View Controller Containment Samstag, 5. Oktober 13

Slide 66

Slide 66 text

Samstag, 5. Oktober 13

Slide 67

Slide 67 text

[self addChildViewController:sliderController]; [self.view addSubview:sliderController.view]; [UIView animateWithDuration:0.25 animations:^{ sliderController.view.alpha = 1; } completion:^(BOOL finished) { [sliderController didMoveToParentViewController:self]; }]; ... oder im Kode Samstag, 5. Oktober 13

Slide 68

Slide 68 text

Kommunikation Samstag, 5. Oktober 13

Slide 69

Slide 69 text

Kommunikation •Delegate •Blocks •KVO Samstag, 5. Oktober 13

Slide 70

Slide 70 text

Kommunikation •Delegate •Blocks •KVO Zu viel? Samstag, 5. Oktober 13

Slide 71

Slide 71 text

Interface Builder Samstag, 5. Oktober 13

Slide 72

Slide 72 text

Samstag, 5. Oktober 13

Slide 73

Slide 73 text

Samstag, 5. Oktober 13

Slide 74

Slide 74 text

@interface MyCell : UITableViewCell @property (weak) IBOutlet UISlider *slider; @property (weak) IBOutlet UISwitch *switch; @end Samstag, 5. Oktober 13

Slide 75

Slide 75 text

Benutzerdefinierte Objekte im Nib Samstag, 5. Oktober 13

Slide 76

Slide 76 text

Samstag, 5. Oktober 13

Slide 77

Slide 77 text

Samstag, 5. Oktober 13

Slide 78

Slide 78 text

Samstag, 5. Oktober 13

Slide 79

Slide 79 text

Outlets funktionieren auch Samstag, 5. Oktober 13

Slide 80

Slide 80 text

@interface NSObject(UINibLoadingAdditions) - (void)awakeFromNib; @end Samstag, 5. Oktober 13

Slide 81

Slide 81 text

Demo Samstag, 5. Oktober 13

Slide 82

Slide 82 text

Testen Samstag, 5. Oktober 13

Slide 83

Slide 83 text

Getrennte Data Source ✓ Samstag, 5. Oktober 13

Slide 84

Slide 84 text

Kategorie für eine Zelle ✓ Samstag, 5. Oktober 13

Slide 85

Slide 85 text

View Controller x Samstag, 5. Oktober 13

Slide 86

Slide 86 text

- (void)testNibLoading; { id mockNavController = [self autoVerifiedMockForClass: [UINavigationController class]]; PhotosViewController *photosViewController = [[PhotosViewController alloc] init]; id photosViewControllerMock = [self autoVerifiedPartialMockForObject: photosViewController]; [[[photosViewControllerMock stub] andReturn:mockNavController] navigationController]; Samstag, 5. Oktober 13

Slide 87

Slide 87 text

Werkzeuge •Dateien nach Länge sortieren •Bibliothekenkenntniss •Refactoring: AppCode Samstag, 5. Oktober 13

Slide 88

Slide 88 text

Werkzeuge •Data Source extrahieren •View Controller Containment •Mehr im Modell, mehr in Views Samstag, 5. Oktober 13

Slide 89

Slide 89 text

Über mich •@chriseidhof •http://www.objc.io •http://www.uikonf.com •[email protected] Samstag, 5. Oktober 13

Slide 90

Slide 90 text

Fragen? Samstag, 5. Oktober 13

Slide 91

Slide 91 text

Vielen Dank Samstag, 5. Oktober 13

Slide 92

Slide 92 text

Samstag, 5. Oktober 13

Slide 93

Slide 93 text

Hier ist das Ende Letzte Folie Macoun ⌘ Samstag, 5. Oktober 13