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

Essential Cocoa Networking

Essential Cocoa Networking

The first half is an introduction to networking on Cocoa, focusing on the features and use of NSURLConnection. The second half discusses strategies for designing apps that use the network to keep them fast and responsive.

Steve Madsen

August 10, 2012
Tweet

More Decks by Steve Madsen

Other Decks in Programming

Transcript

  1. Why Networking? 0 225 450 675 900 1981-85 1986-90 1991-95

    1996-2000 2001-06 Worldwide PC sales (millions) 0 125 250 375 500 2007 2008 2009 2010 2011 2012* Smartphone sales (millions) Source: http://www.c-i-a.com/pr0806.htm * through Q3 2012 Source: https://en.wikipedia.org/wiki/Smartphone I believe networking is the catalyst that makes computing platforms attractive to the general population. We saw it in the accelerated adoption of PCs in the ‘90s (as the Internet became popular) and again in the late ‘00s with smartphones.
  2. What We’ll Cover • Downloading resources • Interacting with a

    web services API • Strategies for good performance
  3. APIs • NSURLConnection • AFNetworking • MKNetworkKit • Not recommended:

    ASIHTTPRequest, Three20 Third-party libraries can ease the more tedious aspects of network programming. ASI and Three20 aren’t flawed, but they are also abandoned. I don’t recommend them for new projects.
  4. NSURLConnection • The workhorse • Feature packed: cookies, caching, authentication,

    proxies, pipelining • Most third-party libraries use it Built on CFNetwork, so it gets all the benefits that Apple makes to their networking APIs. It hides a lot of the complexity of dealing with sockets, especially now that we’re transitioning to an IPv6 world.
  5. NSURLConnection • Events via delegate • Asynchronous requires a run

    loop • Or setDelegateQueue:, but it’s broken on iOS 5 (http:// www.ddeville.me/2011/12/broken-NSURLConnection-on-ios/) The run loop requirement makes using NSURLConnection anywhere but the main thread tedious.
  6. Delegate Protocols • Delegate protocol was informal prior to OS

    X 10.7, iOS 5 • Now two formal protocols: NSURLConnectionDelegate, NSURLConnectionDataDelegate The connection delegate methods are for lifecycle events of the connection/request, while the data delegate methods are an odd mix of data delivery and lifecycle events (finish, redirects, caching).
  7. - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { // For HTTP, cast

    to NSHTTPURLResponse * and check status code } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { // Append data to NSMutableData or write to a file } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { // Do something with the data } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { // Network failures are a "when", not an "if" } This is a reasonable minimal delegate implementation.
  8. NSURLRequest • Simple GET NSURLRequest *request = [NSURLRequest requestWithURL:...] •

    For more control, use the mutable variant • POSTs, types of service, custom request headers, etc. Network service types let iOS prioritize packets (VoIP, video, background traffic, etc.).
  9. POSTs • Content types aren’t just for responses • Simple

    keys & values (think web forms) can use application/x- www-form-urlencoded • File uploads require multipart/form-data; see RFC 2388 • POST data goes in setHTTPBody: With multipart/form-data, every key+value is a separate MIME part. These look a lot like raw email and are tedious to build. Libraries usually will do it for you.
  10. Content-Type: multipart/form-data; boundary=AaB03x --AaB03x Content-Disposition: form-data; name="submit-name" Larry --AaB03x Content-Disposition:

    form-data; name="files" Content-Type: multipart/mixed; boundary=BbC04y --BbC04y Content-Disposition: file; filename="file1.txt" Content-Type: text/plain ... contents of file1.txt ... --BbC04y Content-Disposition: file; filename="file2.gif" Content-Type: image/gif Content-Transfer-Encoding: binary ...contents of file2.gif... --BbC04y-- --AaB03x--
  11. Demos Image carousel: demos fetching, cookies (image changes with same

    request due to session), caching (after wrap around, no load delay) Server error response is not an NSURLConnection error Providing credentials for authentication Synchronous request on main thread: eventually watchdog will kill you
  12. Web Services • NSJSONSerialization (iOS 5+) • NSXMLParser • Apple

    doesn’t provide a DOM parser on iOS If your API returns XML and you’re on iOS, use a third-party XML parser. Depending on your document size and needs, you’ll either want to work with an NSDictionary or run XPath queries.
  13. AFNetworking • Blocks-based, modern Cocoa style • Very popular and

    in use in a lot of production apps • Simplifies much of the tedium in NSURLConnection • Requires iOS 5+ and ARC
  14. Simple AFN JSON Fetch NSURL *url = [NSURL URLWithString:@"https://alpha- api.app.net/stream/0/posts/stream/global"];

    NSURLRequest *request = [NSURLRequest requestWithURL:url]; AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { NSLog(@"App.net Global Stream: %@", JSON); } failure:nil]; [operation start]; A bit hard to read, but blocks replace the delegates and in ~5 lines of code it fetches a remote resource, parses the JSON and returns a property list type (NSArray or NSDictionary).
  15. AFHTTPClient • Set a base URL in one place •

    Set default headers • Creates query strings or form data from NSDictionary, including multipart requests • Monitor and respond to network reachability changes
  16. MKNetworkKit • Stated goal is feature richness of ASIHTTPRequest, but

    modern style and leanness of AFNetworking • Small (2 .m files) • Queue size adapts to active interface* I’ve heard lots of good things about it, but haven’t used it myself yet. The one thing that bothers me is the adaptive queue size. As I’ll discuss later, knowing the active interface doesn’t tell you anything about the network topology after hop #1, and the wrong decision can create more problems.
  17. Here Be Dragons The 8 Fallacies of Distributed Computing 1.

    The network is reliable. 2. Latency is zero. 3. Bandwidth is infinite. 4. The network is secure. 5. Topology doesn't change. 6. There is one administrator. 7. Transport cost is zero. 8. The network is homogeneous. Explanation: http://www.rgoarchitects.com/Files/fallacies.pdf
  18. Designing for the Network • Latency • Timeouts • Topology

    • Bandwidth and CPU time • Power • Mind the main thread
  19. Latency • In network terms, the time for a packet

    to travel from source to destination • More generally, the lag from when the user starts an operation until it finishes Demo Typical results on Wi-Fi: 55ms average single request, 15ms keep-alive, 20ms pipelined (more benefit on slower networks), .7ms batched
  20. Design for Latency Instagram: tapping the green checkmark starts uploading

    the photo while the user is entering a caption and location. My Christmas Lights Finder app uploads all of the data about a new location in the background, retrying if necessary.
  21. Timeouts • Let your user be the timeout/retry mechanism •

    Only they know when they’re tired of waiting and if they want to try again
  22. Topology • Don’t assume network conditions based on link type

    • Wi-Fi on a plane ≠ Wi-Fi in your house • Shape behavior based on observed conditions and expect them to change This is what HTTP Live Streaming does: it adjusts the bitrate based on if it’s falling behind or easily keeping up. Most apps don’t need to do anything about this, but it greatly affects the perceived performance and quality of those that do.
  23. Simulating Topologies The Network Link Conditioner is part of the

    Hardware I/O Tools for Xcode download, available at developer.apple.com/downloads. With it, we can test in an environment closer to reality without leaving our desks.
  24. Bandwidth & CPU Size Parser LoC Parse Time Size (deflate)

    XML JSON Binary plist 15 KB 22 36.0 ms 3.2 KB 8 KB 1 23.5 ms 3.0 KB 7 KB 1 2.5 ms 4.8 KB 100 element array. XML representation generated by Rails 3. XML parsed by NSXMLParser, JSON by NSJSONSerialization, plists by Foundation. Times from iPod touch (4th gen). Very simple data structure with two random strings and an integer. No DOM parser on iOS unless you use third-party code. I consider JSON to be best in class: compact format, very compressible, excellent server-side support and a fast, easy to use, built-in parser on iOS 5.
  25. Power • Data over 3G puts the radio into high-power

    (~ 1 W) mode for 4 seconds after last transmission • Next 15 seconds, drops to approximately ½ of high-power (~ 0.5 W) • From idle to high-power takes about 1 second Source: B. Zhao, Q. Zheng and G. Cao, “Energy-Aware Web Browsing in 3G Based Smartphones” Be bursty: once you pay the cost of powering up the radio, do as much work as you can, then stay idle for as long as possible.
  26. Mind the Main Thread • Building your network request takes

    time • Heavy image processing • Creating a large amount of POST data • At best, you annoy the user because the UI stalls • At worst, you hang long enough that iOS kills you
  27. Debugging • NSMutableURLConnection+CurlDescription • tcpdump + rvictl • CFNetwork and

    libsystem_network logging; see WWDC ’12 session 706 video The former prints a Curl command line to the console. You can copy and paste that into a terminal to see what the server returns. For even more visibility, rvictl creates a virtual network interface on your Mac that tcpdump can use to capture all network traffic to and from a device connected via USB.
  28. Steve Madsen [email protected] @sjmadsen (Twitter and ADN) Light Year Software,

    LLC http://lightyearsoftware.com/ Demo code http://github.com/sjmadsen/EssentialNetworking