bonjour, icloud

Post on 07-May-2015

2.750 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

Mobile devices are so useful because they can get on the net with their built-in wi-fi or cellular data radios. But how does this work? In iOS, we have a slew of networking APIs, each appropriate in different situations. From decades-old BSD sockets to the new-in-iOS-5 iCloud, there are a wide range of networking calls available to your app, and an equally wide range of semantics in how to use them. In this talk, we'll start with high-level abstractions like iCloud and other objects that can either load from or save to a URL, then progress down through the stack, grabbing arbitrary content from URLs, self-networking with Bonjour and Game Kit, and finally accessing the socket layer with CFNetwork and BSD sockets. iCloud sample code at: http://dl.dropbox.com/u/12216224/conferences/codemash12/bonjour-icloud/CloudNotes.zip

TRANSCRIPT

iOS Networking:Bonjour, iCloud!

Chris Adamson • @invalidnameCodeMash 2012

Monday, January 16, 12

What we’ll cover

• Obvious networking APIs

• iCloud, Bonjour, GameKit, CFNetwork

• Not-so-obvious networking APIs

• Foundation, media APIs, System Configuration

Monday, January 16, 12

The first thing your network app should

do?

Monday, January 16, 12

Monday, January 16, 12

Do I have network access at all?

Monday, January 16, 12

Reachability

• Defined in SystemConfiguration.framework

• C-based API, Obj-C wrapper available as sample code from Apple

• Your network-based app will be rejected if it turtles without network access

Monday, January 16, 12

Monday, January 16, 12

Reachability

• Create a SCNetworkReachabilityRef from host name (as a C string) or address (as a sockaddr)

• Get network info with SCNetworkReachabilityGetFlags()

Monday, January 16, 12

Reachability Flags

enum { kSCNetworkReachabilityFlagsTransientConnection = 1<<0, kSCNetworkReachabilityFlagsReachable = 1<<1, kSCNetworkReachabilityFlagsConnectionRequired = 1<<2, kSCNetworkReachabilityFlagsConnectionOnTraffic = 1<<3, kSCNetworkReachabilityFlagsInterventionRequired = 1<<4, kSCNetworkReachabilityFlagsConnectionOnDemand = 1<<5, kSCNetworkReachabilityFlagsIsLocalAddress = 1<<16, kSCNetworkReachabilityFlagsIsDirect = 1<<17, kSCNetworkReachabilityFlagsIsWWAN = 1<<18, kSCNetworkReachabilityFlagsConnectionAutomatic =

kSCNetworkReachabilityFlagsConnectionOnTraffic};typedef uint32_t SCNetworkReachabilityFlags;

Monday, January 16, 12

Reachability callbacks

• Networks come and go; your app should handle this

• SCNetworkReachabilitySetCallback()

MyNetworkReachabilityCallBack( SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info);

Monday, January 16, 12

Monday, January 16, 12

Assuming the network is working…

Monday, January 16, 12

Say hello to iCloud

Monday, January 16, 12

The iCloud API

Monday, January 16, 12

iCloud: UIDocument

• iCloud does not have its own API, per se

• Special case of saving documents

• Same code to save to local or cloud documents directory by URL

• There are also iCloud APIs for simple key-value storage, and Core Data persistent stores

Monday, January 16, 12

iCloud set-upEnable iCloud for AppID in provisioning portal

Enable entitlements in .xcodeproj (also creates .entitlements file)

Monday, January 16, 12

Browsing in iCloud

• Compose an NSMetadataQuery (from Spotlight API)

• Include NSMetadataQueryUbiquitousDocumentsScope in search scopes

• Start search (asynchronous!)

Monday, January 16, 12

-(void) refreshNotes { NSLog (@"refreshNotes"); [self.noteDictsArray removeAllObjects]; self.currentQuery = [[NSMetadataQuery alloc] init]; // register for notifications [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidUpdate:) name:NSMetadataQueryDidUpdateNotification object:self.currentQuery]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(initalGatherComplete:) name:NSMetadataQueryDidFinishGatheringNotification object:self.currentQuery];

Monday, January 16, 12

// Configure the search predicate NSPredicate *searchPredicate; searchPredicate=[NSPredicate predicateWithFormat:@"%K LIKE %@", NSMetadataItemFSNameKey, @"*.cloudnote"]; [self.currentQuery setPredicate:searchPredicate]; // Set the search scope to only search iCloud NSArray *searchScopes; searchScopes=[NSArray arrayWithObjects: NSMetadataQueryUbiquitousDocumentsScope,nil]; [self.currentQuery setSearchScopes:searchScopes];

// Start the query! [self.currentQuery startQuery];

Monday, January 16, 12

- (void)initalGatherComplete:sender; { // Stop the query, the single pass is completed. [self.currentQuery stopQuery]; for (int i=0; i < [self.currentQuery resultCount]; i++) { NSMetadataItem *noteMetadata = [self.currentQuery resultAtIndex:i]; NSString *noteName = [noteMetadata

valueForAttribute:NSMetadataItemDisplayNameKey]; NSURL *noteURL = [noteMetadata valueForAttribute:NSMetadataItemURLKey]; NSDate *noteModifiedDate = [noteMetadata

valueForAttribute:NSMetadataItemFSContentChangeDateKey]; NSLog(@"%@: %@", noteName, noteURL); NSDictionary *noteDict = [NSDictionary dictionaryWithObjectsAndKeys: noteName, NSMetadataItemDisplayNameKey, noteURL, NSMetadataItemURLKey, noteModifiedDate,

NSMetadataItemFSContentChangeDateKey, nil]; [self.noteDictsArray addObject:noteDict]; }

Monday, January 16, 12

Monday, January 16, 12

But what about document contents?

Monday, January 16, 12

iCloud documents

• Subclass UIDocument (new in iOS 5)

• Override contentsForType: and loadFromContents:ofType:error:

Monday, January 16, 12

- (id)contentsForType:(NSString *)typeName error:(NSError **)outError { NSLog (@"archiving: %@", self.noteDict); return [NSKeyedArchiver archivedDataWithRootObject:self.noteDict];}

- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError *__autoreleasing *)outError { BOOL success = NO; if([contents isKindOfClass:[NSData class]] && [contents length] > 0) { NSData *data = (NSData *)contents; self.noteDict = [NSMutableDictionary dictionaryWithDictionary: [NSKeyedUnarchiver unarchiveObjectWithData:data]]; success = YES; } NSLog (@"noteDict: %@", self.noteDict); return success;}

UIDocument overrides

Monday, January 16, 12

Start a new document in iCloud

NSFileManager *fm = [NSFileManager defaultManager]; NSURL *newDocumentURL = [fm URLForUbiquityContainerIdentifier:nil]; newDocumentURL = [newDocumentURL URLByAppendingPathComponent:@"Documents" isDirectory:YES]; // fileName calculation omitted newDocumentURL = [newDocumentURL URLByAppendingPathComponent:fileName]; CDMNoteDocument *doc = [[CDMNoteDocument alloc] initWithFileURL:newDocumentURL]; // Save the new document to disk. [doc saveToURL:newDocumentURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) { NSLog (@"new document %@ saved", success ? @"was" : @"was not"); }];

Monday, January 16, 12

Open an existing iCloud document

NSURL *noteURL = (NSURL*) [noteDict valueForKey:NSMetadataItemURLKey]; CDMNoteDocument *doc = [[CDMNoteDocument alloc] initWithFileURL:noteURL]; [doc openWithCompletionHandler:^(BOOL success){ NSLog (@"opening doc at %@ %@", doc.fileURL, success ? @"succeeded" : @"failed");

}

Monday, January 16, 12

Saving changes

[note updateChangeCount:UIDocumentChangeDone]; [note closeWithCompletionHandler:^(BOOL success) { NSLog (@"document close was %@", success ? @"successful" : @"not successful"); }];

Monday, January 16, 12

Detecting iCloud conflicts

• Register for NSNotificationCenter for UIDocumentStateChangedNotification

• Inspect the documentState property for the value UIDocumentStateInConflict

• Use NSFileVersion method unresolvedConflictVersionsOfItemAtURL to inspect the versions

Monday, January 16, 12

Demo: CloudNotes

Monday, January 16, 12

But what if my data isn’t in iCloud?

Monday, January 16, 12

Networking in Foundation

• NSURL

• Classes that load from URLs

• Property lists

• URL Loading System

Monday, January 16, 12

initWithContentsOfURL:

• Supported by NSString, NSData

• Also NSArray and NSDictionary if contents are a property list

• These calls block!

Monday, January 16, 12

URL Loading System

• NSURL + NSURLRequest + NSURLConnection + delegate callbacks

• connection:didReceiveResponse:, connection:didReceiveData:, etc.

• Fairly deep HTTP support (incl. authentication)

• Not an arbitrary socket networking API

Monday, January 16, 12

But I want to host a server on my iPhone!

Monday, January 16, 12

CFNetwork

• C-based API, abstractions over network protocols and BSD sockets

• Deep support for HTTP, HTTPS, FTP, DNS

• Built to work asynchronously in RunLoop-based applications (incl. Cocoa Touch)

Monday, January 16, 12

If you must run a server

• Create CFSocketRef with CFSocketCreate() [or similar] setting callbackTypes to kCFSocketAcceptCallback

• Callback receives a CFSocketNativeHandle

• From this, CFStreamCreatePairWithSocket() to get CFReadStreamRef and CFWriteStreamRef

Monday, January 16, 12

Network Discovery

Monday, January 16, 12

Bonjour!

• Protocol for address self-assignment and service discovery

• Published ZEROCONF standard

• Open-source implementations for Mac, Windows, Linux, Java

• APIs: NSNetService and CFNetServiceRef

Monday, January 16, 12

Searching for Bonjour http servers

-(void) startSearchingForWebServers {! NSNetServiceBrowser bonjourBrowser = [[NSNetServiceBrowser alloc] init];! [bonjourBrowser setDelegate: self];! [bonjourBrowser searchForServicesOfType:@"_http._tcp" inDomain:@""];}

- (void)netServiceBrowser:(NSNetServiceBrowser *)netServiceBrowserdidFindService:(NSNetService *)netService moreComing:(BOOL)moreServicesComing {

! [discoveredWebServices addObject: netService];! [tableView reloadData];! if (! moreServicesComing)! ! [activityIndicator stopAnimating];}

Monday, January 16, 12

Got a service,now what?

• Bonjour provides the discovery, not the service itself

• The NSNetService object includes addresses, host name, and port

• Client connects to the host via NSURLConnection, CFNetwork, etc.

Monday, January 16, 12

GameKit

• Simplified Bonjour over Bluetooth or WiFi

• GKPeerPickerController UI for peer discovery

• APIs allow client-server or peer-to-peer

Monday, January 16, 12

GKSession

• All about the delegate callbacks:

• didReceiveConnectionRequestFromPeer:

• peer:didChangeState:

• receiveData:fromPeer:inSession:

Monday, January 16, 12

Demo (if we are really, really lucky)

Monday, January 16, 12

GameKit voice chat

• Set up through Game Center

• Create with -[GKMatch voiceChatWithName:]

• Does anyone use this?

Monday, January 16, 12

Speaking of media…

Monday, January 16, 12

HTTP Live Streaming

• Firewall-friendly audio/video streaming for iOS and Mac OS X 10.6+ (replaces RTP/RTSP)

• Required for any app that streams more than 10MB over mobile network

• Client support: AVPlayer, MPMoviePlayerController

Monday, January 16, 12

HLS: How It Works

• Segmenting server splits source media into separate files (usually .m4a for audio-only, .ts for A/V), usually 10 seconds each, and creates an .m3u8 playlist file

• Playlist may point to bandwidth-appropriate playlists

• Clients continually reload playlist, fetch the segments, queue them up

Monday, January 16, 12

Sample playlist#EXTM3U#EXT-X-TARGETDURATION:8#EXT-X-MEDIA-SEQUENCE:0#EXTINF:8,0640/0640_090110_120505_0.ts#EXTINF:8,0640/0640_090110_120505_1.ts#EXTINF:8,0640/0640_090110_120505_2.ts#EXTINF:8,0640/0640_090110_120505_3.ts#EXTINF:8,0640/0640_090110_120505_4.ts

Monday, January 16, 12

Bandwidth-delimited playlist

#EXTM3U #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1280000 http://example.com/low.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2560000 http://example.com/mid.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=7680000 http://example.com/hi.m3u8

Monday, January 16, 12

Demo: HLS bandwidth

Monday, January 16, 12

Takeaways

Monday, January 16, 12

iOS Priorities

• Asynchronicity — don’t block the UI

• Many network APIs are difficult or impossible to block on

• Domain-appropriate abstractions

• iCloud, GameKit, HLS

• You don’t need to know the difference between cellular and wifi

Monday, January 16, 12

End of line.

Monday, January 16, 12

top related