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

Advanced Cocoa Networking

Advanced Cocoa Networking

This talk discusses and demonstrates how to write a network app with Cocoa when you want to do more than access a remote server using HTTP.

Steve Madsen

August 10, 2012
Tweet

More Decks by Steve Madsen

Other Decks in Programming

Transcript

  1. Use Cases • When simple request/response isn’t enough • More

    serious, “roll your own” networking Use cases: non-web clients (mail, chat, etc.), games, telephony, anything that is real-time oriented and wants to avoid polling a server.
  2. If you need just a bit more than a web

    service... • Push notifications • Publish/subscribe systems like Faye or pusher.com; XMPP • Maintain a long-lived connection to a server and be notified by it • Be prepared to reconnect and switch from cellular back to Wi-Fi Apple’s push notifications are meant for small messages to poke a client to make a request to the server. No delivery guarantees. PubSub systems cut out Apple as a middleman (more reliably delivery) at the expense of additional server resources and maintenance costs.
  3. Need a Socket? TCP • Connection oriented (state on each

    end) • Reliable (guaranteed error-free, in- order delivery) • Stream-based UDP • Connectionless • Unreliable • Datagrams A TCP stream is like a file: you can read it in chunks of your choosing. By contrast, UDP isn’t a stream. A UDP datagram must be read in its entirety or you lose the rest of the bytes. While UDP has a checksum field, it isn’t always verified. If it is checked and it doesn’t match, the datagram is simply dropped. The sender never retransmits.
  4. • Use CFNetwork • Easier to support IPv6 • Activates

    cellular radio, VPN auto dial on iOS • Manages socket layer for performance For Client Code
  5. CFNetwork • NSInputStream, NSOutputStream • Toll-free bridged to CFReadStream, CFWriteStream

    • Streams are blocking • Schedule them on a run loop or set up GCD event sources Blocking is your biggest hurdle. Often you want to send and receive complete messages, but to do this you’ll need to wrap the stream objects and do the buffering yourself.
  6. For Server Code • POSIX or CFSocket • No support

    for listening in CFNetwork • For CFSocket, create run loop sources • For POSIX sockets, create dispatch sources • IPv6: evaluate dual-bound listener Oddly, Apple says if you’re writing code exclusively for OS X and iOS, to use the POSIX API to create the listener. This sounds fishy; I think the technical writer meant to say CFSocket. In 2010, Apple recommended creating a dual-bound listener, but absent from recent WWDC videos. There is debate about if this is a good idea (e.g., OpenBSD will never do this).
  7. Demo Simple TCP echo service: server is implemented with POSIX

    sockets and GCD event sources, while the client uses CFStream and the run loop. Both are contained in one app and demonstrate how you must buffer writes to avoid blocking.
  8. Securing a Stream • Securing your user’s content is important

    • Easy to do for clients [inStream setProperty:NSStreamSocketSecurityLevelNegotiatedSSL forKey:NSStreamSocketSecurityLevelKey]; NSDictionary *properties = @{ kCFStreamSSLValidatesCertificateChain: @NO }; CFReadStreamSetProperty((CFStream *)inStream, kCFStreamPropertySSLSettings, (CFTypeRef)properties)); Secure servers are necessarily more complex for two reasons. First, you have to dip down a layer to listen, so the stream properties aren’t available. Second, the server half requires a certificate and private key.
  9. Service Discovery • Servers advertise a service • Clients can

    find those services • No IPs, no ports: “zero configuration” • However: local subnet only Demo the same echo app, only using Bonjour to find the server instead of entering host and port. Communication code is exactly the same, but server publishes via NSNetService after binding the listener socket and the client looks for Bonjour services instead of asking for a host and port in the UI.
  10. GameKit P2P • Greatly simplified method to connect peers •

    Implemented using Bonjour Though it uses Bonjour, I was not able to get an iOS GameKit client to connect to a Mac Bonjour service. Demo the simple chat app. Since GameKit is also available on Mountain Lion, it would be straightforward to write a chat app that can talk between OS X and iOS.