Paul Danbold danbold@apple.com — Evangelist
This was another really fast presentation with loads of detail. I look forward to grabbing the presentation from the iPhone dev site.
- don’t want to use CFSocket or BSD Socket
- don’t let you bring up wireless, or involve security
- service discovery:
- NSNetServices, CFNetServices, dns-sd, BSD Sockets
- dns-sd is Bonjour or Zeroconf
URL Loading system
- NSURLRequest, NSURLConnection & about 10 other classes (also mutable ones)
- there’s sample code for validating URLs
- recommend to use asynchronous API style:
- use delegate mechanism — calls
connection:didReceiveResponse:
- use delegate mechanism — calls
- also
connection:didReceiveAuthenticationChallenge:
- finally
connectionDidFinishLoading:
- default behaviours should work fine
Local area networking — service discovery
- kick off NSNetServiceBrowser in asynchronous mode, w/delegation
- browser
searchForServicesOfType:inDomain:
- e.g. type
_http._tcp
in domainlocal.
— don’t go beyond any routers - can look for your own types too such as
_foo._tcp
- e.g. type
- then get
myServiceBrowser:didFindService:moreComing:
- call
NSNetworkService getInputStream:outputStream
to resolve- this takes time (many seconds)
- wait for the user to choose before resolving
- and let the user decide when to cancel
resolveWithTimeout:0.0
- must release input & output stream objects returned by NSNetService
- bug in Apple’s code — doesn’t obey normal Cocoa behaviour
OutputStream & InputStream
- NSStreamEventHasSpaceAvailable is probably the interesting one
- though you want to handle the errors too…
advertising & publishing
- advertise service with
NSNetService initWithDomain:type:name:port
- domain can be empty — means local
- name can be blank too — will use device’s iTunes name
- then call
publish
on service
stop when you’re done
- browsing is fairly lightweight on the network, but you should stop anyway
- the same goes for publishing, when you’ve got all your connected clients
register types & ports
- to register a service type:
- http://www.dns-sd.org/ServiceTypes.html
- send them an email, no money changes hands
- and http://www.iana.org/assignments/port-numbers for one further
game kit — peer to peer
- 3.1 adds WiFi support as well as Bluetooth
GKSession initWithSessionID:displayName:sessionMode
- session ID is your Bonjour service type — how you advertise yourself
- again, can leave displayName as nil for iTunes name
- sessionMode can be peer to peer (1 to 1) or client/server (multiple clients)
- can’t physically go over 10-20 clients with Bluetooth
- 3.1 and later is a lot better, but still no more than 3-4 clients
- Bluetooth also has low bandwidth
- set up delegate and set
available
to YES - check other peers with
peersWithConnectionState:
- can be available, already connected, in the process of getting connected
connectToPeer:withTimeout:
- generally set timeout to zero to let user cancel if they want
- actual connection made with
session:didReceiveConnectionRequestFromPeer:
andacceptConnectionFromPeer:error:
- must monitor the network using
session:peer:didChangeState:
- other players can drop out, so you’d have to tear down your session
- send data with
sendDataToAllPeers:withDataMode:error:
andsendDataToPeers:...
- can choose unreliable (UDP) or reliable (TCP) data modes
- as always TCP imposes a performance cost so use sparingly
- receive data with
setDataReceiveHandler:withContext:
andreceiveData:fromPeer:inSession:context:
- always check for errors — buffers fill up on low bandwidth networks
- check it by using a slow network
- when you’re finished, tear down with
disconnectFromAllPeers:
- there’s a GKPeerPickerController for setting up Bluetooth peers
- doesn’t work for client/server or WiFi
- the only way to find out if Bluetooth is turned on is to use the GKPeerPickerController (it uses private APIs…)
- all data sent & received is NSData-wrapped — design your packaging for network efficiency first and coding efficiency second
Voice chat
- GKVoiceChatClient and ~Service
- sets up socket interface
- handles microphone, echo suppression, etc
network challenges
scoped routing and reachability
- iphone 3.0 and later provides scoped routing
- keeps both cellular and wifi up at the same time — so cellular connections keep going when you enter a wifi hotspot
- but this puts a toll on the battery, so you should behave and check for networking changes
- use SystemConfiguration APIs to monitor network state
- Am I on the network and what kind of network is it?
- cannot tell you that packets will arrive…
- if network changes, finish what you’re doing, close connection and start a new one
- use
SCNetworkReachabilityRef
and check for flags- but again use callback APIs since the calls take about 30 seconds
- no point using this to pre-flight as things may change
- just use to monitor
- can set UIRequiresPersistentWiFi key
- keeps WiFi live while your app is live
- shows up UI elements automatically (like offering to turn off Airplane mode)
- but if the device sleeps, you still lose your WiFi connection
battery use
- listening is cheap, transmitting is expensive
- 3GS sending leaves the antenna in high powered state for 5 seconds
- so don’t send every 5 seconds — it will leave it in high power continuously
- compress data, send large chunks
- tear down connections when reachability changes
other tips
- try to use the cache as much as possible
- try to resume downloads rather than restart
- use pipelining if poss.
- ask for lots of things at once and be careful about return order
- some web proxies and apache configs just break pipelining
- also use multiple connections
- but different network conditions and different servers require different tuning
- test in areas where you know the network is flaky!
- use a packet analyzer — see QA1176
- try to isolate the user from network problems
- often there’s a transient glitch — try again before alerting the user
- see also Technote TN2152
- look for developer forum postings by eskimo1 :-)
there’s some new sample code available:
- SimpleNetworkStreams
- SimpleURLConnection
- SimpleFTPSample
- Reachability — there’s a new version! The old version had bad code :-)
- BonjourWeb
- WiTap — peer to peer, but doesn’t use GameKit
- GKTank
- GKRocket — work in progress, with voice chat too
1 comment:
Hi Adam!
Thanks for the briefs. But how can one create a custom UI instead of the normal popup "available bluetooth devices" screen?
Best regards
Alan Serhan
Post a Comment