ios
DESCRIPTION
Slides for a presentation on iOS that I gave at the fall 2012 Near Infinity conference. Links to the sample applications on GitHub are in the slides.TRANSCRIPT
Scott Leberknight
iOS
The Big Picture
Patterns
Languages
APIs
Tools
Patterns
MVC(S)
Notifications
Delegation
Protocols
Target-Action
Languages
Objective-C
C(lower-level APIs)
APIsCore
Lots more...
Core GraphicsFoundationUIKit
MapKit
GameKit
Core Location
Core Data Accounts
OpenGL
Social...
XCodeTools
Tools Interface Builder
First App*
MVC
Target-Action
Delegation
http://github.com/sleberknight/fortune-ios-app*
Model
@property (nonatomic, copy) NSArray *fortunes;
FOViewController.h
View
FOViewController.xib
Outlets
Actions
&
Outlets
in XCode...
FOViewController.h
Outlets in IB...
FOViewController.xib
Target-Action
Action - “touch up inside” Target - File’s Owner(our view controller)
Controller
FOViewController.h
#import <UIKit/UIKit.h>
@interface FOViewController : UIViewController
// Model@property (nonatomic, copy) NSArray *fortunes;
// Outlets@property (nonatomic, strong) IBOutlet UITextView *fortuneField;
// Actions- (IBAction)showFortune:(id)sender;
@end
(IBOutlet & IBAction keywords allow
connections in Interface Builder)
Controller
FOViewController.m
#import "FOViewController.h"
@implementation FOViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) { _fortunes = @[ @"A dubious friend may be an enemy in camouflage.", @"A feather in the hand is better than a bird in the air.", @"A friend asks only for your time not your money.", // ... ]; } return self;}
- (IBAction)showFortune:(id)sender { int fortuneIndex = arc4random() % [_fortunes count]; NSLog(@"fortuneIndex: %d", fortuneIndex); NSString *fortune = [_fortunes objectAtIndex:fortuneIndex]; [_fortuneField setText:fortune];}
@end
#import <UIKit/UIKit.h>
// Inherits from UIResponder// Conforms to UIApplicationDelegate protocol
@interface FOAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
Delegation
FOAppDelegate.h
#import "FOAppDelegate.h"#import "FOViewController.h"
@implementation FOAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Create our view controller; set it as the root view controller FOViewController *viewController = [[FOViewController alloc] initWithNibName:@"FOViewController" bundle:nil]; [[self window] setRootViewController:viewController];
self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; return YES;}
@end
Delegation
FOAppDelegate.m
Run It!
2. Tap “Get Fortune!”
1. Load view controllerin App Delegate
3. showFortune: called
4. Get fortune from model
5. Call setText: on UITextView
Objective-C
Object-oriented(layered on top of C)
Message sending
Single-inheritance
Protocols (like Java interfaces)
Objective-C (continued)
Properties
Selectors
Blocks (like closures)
ARC (automatic reference counting)
GCD (Grand Central Dispatch)
Properties
@property (nonatomic, strong) IBOutlet UITextView *fortuneField;
* Compiler generates:
- instance variable _fortuneField
- getter method fortuneField
- setter method setFortuneField
* IBOutlet indicates it can be an outlet to IB
* Modifiers determine threading and storage model
Sending Messages
[detailViewController setItem:newItem];
receiver
selector
argument
Sending Messages
[self presentViewController:navigationController animated:YES completion:nil];
receiver
selector arguments
Creating Objects
allocate memory
initialize object
WLItemsViewController *itemsViewController = [[WLItemsViewController alloc] init];
Blocks
int amountToAdd = 7;int (^adder)(int) = ^(int num) { return num + amountToAdd;};
NSLog(@"%d", adder(3));// prints "10" to XCode console
[detailViewController setDismissBlock:^{ [[self tableView] reloadData];}];
Blocks - inline
[self tableView] is capturedfrom scope defining block!
Objective-C really is an OK language,once you get used to its quirks,
and it keeps improving...
Core APIs
UIKit
Foundation
Core Graphics
UIKit
“The UIKit framework provides the classes needed to construct and manage an application’s user interface for iOS. It provides an application object, event handling, drawing model, windows, views, and controls specifically designed for a touch screen interface.”
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIKit_Framework/_index.html
UIKit & Grand Central Dispatch
"For the most part, UIKit classes should be used only from an application’s main thread. This is particularly true for classes derived from UIResponder or that involve manipulating your application’s user interface in any way."
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIKit_Framework/Introduction/Introduction.html#//apple_ref/doc/uid/TP40006955-CH1-SW1
-(void)handleIncoming:(NSData *)data{ dispatch_async(dispatch_get_main_queue(), ^{
// Retrieve data...
// Update the UI using UIKit methods...
});}
Update UI using GCD
Foundation
“The Foundation framework defines a base layer of Objective-C classes. In addition to providing a set of useful primitive object classes, it introduces several paradigms that define functionality not covered by the Objective-C language.”
http://developer.apple.com/library/mac/#documentation/cocoa/reference/foundation/ObjC_classic/_index.html
Core Graphics
“The Core Graphics framework is a C-based API that is based on the Quartz advanced drawing engine. It provides low-level, lightweight 2D rendering with unmatched output fidelity. You use this framework to handle path-based drawing, transformations, color management, offscreen rendering, patterns, gradients and shadings, image data management, image creation, masking, and PDF document creation, display, and parsing.”
http://developer.apple.com/library/ios/#documentation/coregraphics/reference/coregraphics_framework/_index.html
Many, Many More APIs
Core Location MapKit
Quartz Core Animation
AdSupport...Core Motion
Sample Application - Wishlist*
http://github.com/sleberknight/wishlist-ios-app
Displays list of items
Detail view to create/edit items
Move and delete items in list
Choose images for items
*
List of items Editing list
Add/edititem
Chooseimage
Patterns
MVC(S):
Model, View, Controller (, Store)
“Store” is like a DAO (data access object)
Extract store logic from controllers
Patterns
Inheritance - e.g. table view controller
Delegation - e.g. image picker delegate
Notification - e.g. low-memory warning
Model -
#import <Foundation/Foundation.h>
@interface WLItem : NSObject <NSCoding>
-(id)initWithItemName:(NSString *)name;
-(id)initWithItemName:(NSString *)name occasion:(NSString *)occasion store:(NSString *)store price:(int)price;
@property (nonatomic, strong) WLItem *containedItem;@property (nonatomic, weak) WLItem *container;
@property (nonatomic, copy) NSString *itemName;@property (nonatomic, copy) NSString *occasion;@property (nonatomic, copy) NSString *store;@property (nonatomic, assign) int price;@property (nonatomic, copy) NSString *imageKey;@property (readonly, nonatomic, copy) NSDate *dateCreated;@property (nonatomic, copy) NSDate *dateModified;
@end
WLItem
Views
UITableView (presents list of items)
* App delegate creates table view controller programmatically within a navigation controller
* Not defined in XIB
* Edit and + buttons defined in code
Views Detail View Controller
ControllersWLItemsViewController:
Subclass of:
Conforms to: UITableViewDelegateUITableViewDataSource
UITableViewController
Uses UINavigationController to present detail view controller for adding/editing items
Manages moving/deleting items
Responsible for creating table view cells
ControllersWLDetailViewController:
Subclass of:
Conforms to: UITextFieldDelegate
UINavigationControllerDelegate
UIViewController
UIImagePickerControllerDelegate
UIPopoverControllerDelegate
Responsible for loading/saving items & images
Manages image picking controllers
Manages text changed notifications
Stores
WLItemStore
WLImageStore
Stores WLItem objects
Stores UIImage objects
Application Flow
WLAppDelegateapplication:didFinishLaunchingWithOptions
- Create a WLItemsViewController
- Embed WLItemsViewController in UINavigationController
Tap + button, fires addNewItem: which presents detail view controller
- Create a UINavigationController
List editing UI is automatic when add button using editBarButton
WLItemsViewController viewWillAppear: loads table view
viewWillAppear:animated:
viewDidLoad: sets background color
WLDetailViewController init: creates Cancel & Done bar button items
- Sets up form for editing/adding item
- Display image if present
- Register for text change notifications
viewWillDisappear: saves item data
done: dismisses controller, completion handler reloads table data
Tapping camera button invokes takePicture:
UIImagePickerController presents camera or picture library
UIImagePickerController delegate (controller) handles selected image
imagePickerController:didFinishPickingMediaWithInfo retrieves selected image, stores it, and displays it
Use Core Graphics to add a border around image
Use Quartz to add a shadow around image
UITextFieldDelegate method textFieldShouldReturn: dismisses keyboard when return tapped
UIControlEventEditingChanged events trigger selector textChanged: which adds modified date when editing existing items
On iPad use a UIPopoverController for selecting images
UIPopoverController was used to select the delicious image...
One more thing...
Storyboards (an alternative way to define app flow)
Summary
Objective-C
Patterns, Languages, APIs, Tools
MVC(S), Delegation, Protocols
Lots of APIs to use (and learn)
XCode / Interface Builder (IB)
Connect outlets & actions in IB
References
http://www.bignerdranch.com/book/ios_programming_the_big_nerd_ranch_guide_rd_edition_
http://pragprog.com/book/adios/ios-sdk-development
Sample Code
http://github.com/sleberknight/fortune-ios-app
Fortunes:
http://github.com/sleberknight/wishlist-ios-app
Wishlist:
Fortunes:
My Info
scott.leberknight at nearinfinity.com
twitter.com/sleberknight
www.sleberknight.com/blog
www.nearinfinity.com/blogs/scott_leberknight/all/