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.
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.
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.
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.
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.
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).
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.
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.).
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.
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
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.
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).
Set default headers • Creates query strings or form data from NSDictionary, including multipart requests • Monitor and respond to network reachability changes
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.
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
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
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.
• 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.
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.
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.
(~ 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.
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
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.