Your SlideShare is downloading. ×
Bonjour, iCloud
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Bonjour, iCloud

2,705
views

Published on

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 …

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

Published in: Technology

1 Comment
4 Likes
Statistics
Notes
No Downloads
Views
Total Views
2,705
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
52
Comments
1
Likes
4
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. iOS Networking: Bonjour, iCloud! Chris Adamson • @invalidname CodeMash 2012Monday, January 16, 12
  • 2. What we’ll cover • Obvious networking APIs • iCloud, Bonjour, GameKit, CFNetwork • Not-so-obvious networking APIs • Foundation, media APIs, System ConfigurationMonday, January 16, 12
  • 3. The first thing your network app should do?Monday, January 16, 12
  • 4. Monday, January 16, 12
  • 5. Do I have network access at all?Monday, January 16, 12
  • 6. 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 accessMonday, January 16, 12
  • 7. Monday, January 16, 12
  • 8. 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
  • 9. 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
  • 10. Reachability callbacks • Networks come and go; your app should handle this • SCNetworkReachabilitySetCallback() MyNetworkReachabilityCallBack( SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info );Monday, January 16, 12
  • 11. Monday, January 16, 12
  • 12. http://mattgemmell.com/2011/07/25/network-link- conditioner-in-lion/Monday, January 16, 12
  • 13. Assuming the network is working…Monday, January 16, 12
  • 14. Say hello to iCloudMonday, January 16, 12
  • 15. The iCloud API • • • • •Monday, January 16, 12
  • 16. 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 storesMonday, January 16, 12
  • 17. iCloud set-up Enable iCloud for AppID in provisioning portal Enable entitlements in .xcodeproj (also creates .entitlements file)Monday, January 16, 12
  • 18. Browsing in iCloud • Compose an NSMetadataQuery (from Spotlight API) • Include NSMetadataQueryUbiquitousDocu mentsScope in search scopes • Start search (asynchronous!)Monday, January 16, 12
  • 19. -(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
  • 20. // 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
  • 21. - (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
  • 22. Monday, January 16, 12
  • 23. But what about document contents?Monday, January 16, 12
  • 24. iCloud documents • Subclass UIDocument (new in iOS 5) • Override contentsForType: and loadFromContents:ofType:error:Monday, January 16, 12
  • 25. UIDocument overrides - (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; }Monday, January 16, 12
  • 26. 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
  • 27. 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
  • 28. Saving changes [note updateChangeCount:UIDocumentChangeDone]; [note closeWithCompletionHandler:^(BOOL success) { NSLog (@"document close was %@", success ? @"successful" : @"not successful"); }];Monday, January 16, 12
  • 29. Detecting iCloud conflicts • Register for NSNotificationCenter for UIDocumentStateChangedNotification • Inspect the documentState property for the value UIDocumentStateInConflict • Use NSFileVersion method unresolvedConflictVersionsOfItemAtURL to inspect the versionsMonday, January 16, 12
  • 30. Demo: CloudNotesMonday, January 16, 12
  • 31. But what if my data isn’t in iCloud?Monday, January 16, 12
  • 32. Networking in Foundation • NSURL • Classes that load from URLs • Property lists • URL Loading SystemMonday, January 16, 12
  • 33. initWithContentsOfURL: • Supported by NSString, NSData • Also NSArray and NSDictionary if contents are a property list • These calls block!Monday, January 16, 12
  • 34. URL Loading System • NSURL + NSURLRequest + NSURLConnection + delegate callbacks • connection:didReceiveResponse:, connection:didReceiveData:, etc. • Fairly deep HTTP support (incl. authentication) • Not an arbitrary socket networking APIMonday, January 16, 12
  • 35. But I want to host a server on my iPhone!Monday, January 16, 12
  • 36. 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
  • 37. 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 CFWriteStreamRefMonday, January 16, 12
  • 38. Network DiscoveryMonday, January 16, 12
  • 39. Bonjour! • Protocol for address self-assignment and service discovery • Published ZEROCONF standard • Open-source implementations for Mac, Windows, Linux, Java • APIs: NSNetService and CFNetServiceRefMonday, January 16, 12
  • 40. Searching for Bonjour http servers -(void) startSearchingForWebServers { ! NSNetServiceBrowser bonjourBrowser = [[NSNetServiceBrowser alloc] init]; ! [bonjourBrowser setDelegate: self]; ! [bonjourBrowser searchForServicesOfType:@"_http._tcp" inDomain:@""]; } - (void)netServiceBrowser:(NSNetServiceBrowser *)netServiceBrowser didFindService:(NSNetService *)netService moreComing:(BOOL)moreServicesComing { ! [discoveredWebServices addObject: netService]; ! [tableView reloadData]; ! if (! moreServicesComing) ! ! [activityIndicator stopAnimating]; }Monday, January 16, 12
  • 41. 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
  • 42. GameKit • Simplified Bonjour over Bluetooth or WiFi • GKPeerPickerController UI for peer discovery • APIs allow client-server or peer-to-peerMonday, January 16, 12
  • 43. GKSession • All about the delegate callbacks: • didReceiveConnectionRequestFromPeer: • peer:didChangeState: • receiveData:fromPeer:inSession:Monday, January 16, 12
  • 44. Demo (if we are really, really lucky)Monday, January 16, 12
  • 45. GameKit voice chat • Set up through Game Center • Create with -[GKMatch voiceChatWithName:] • Does anyone use this?Monday, January 16, 12
  • 46. Speaking of media…Monday, January 16, 12
  • 47. 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, MPMoviePlayerControllerMonday, January 16, 12
  • 48. 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 upMonday, January 16, 12
  • 49. 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.tsMonday, January 16, 12
  • 50. 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.m3u8Monday, January 16, 12
  • 51. Demo: HLS bandwidthMonday, January 16, 12
  • 52. TakeawaysMonday, January 16, 12
  • 53. 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 wifiMonday, January 16, 12
  • 54. End of line.Monday, January 16, 12