High Performance
iOS Networking
@smithclay · New Relic
UIKonf · 23 May 2016 · Berlin
Slide 2
Slide 2 text
This talk: tech notes
• iOS 9 only (changes in iOS 10?)
• NSURLSession is assumed (AFNetworking
2.0+)
• Not about the absence of a network
connection.
• No code—focus on the network layer and
server-side. Don't block the main thread.
TCP Fast Open Guide
• Only for idempotent data (HTTP GET)
• Needs Linux Kernel v4.1
• https://developer.apple.com/videos/play/
wwdc2015/719/
• http://devstreaming.apple.com/videos/wwdc/
2015/719ui2k57m/
719/719_your_app_and_next_generation_net
works.pdf?dl=1 (Implementation details)
Slide 13
Slide 13 text
Does it work with
NSURLSession?
No :(
Slide 14
Slide 14 text
Transport Layer
Security (TLS)
Slide 15
Slide 15 text
App Transport Security
nscurl --ats-
diagnostics
TLS 1.2,
Strong
certificates
Slide 16
Slide 16 text
Full TCP + TLS handshake
Device Server
Data Transfer
{
Round trip
1. SYN
2. SYN/ACK
3. ACK
{
{
TLS, +2 RTTs
Cool demo (browser-based): https://tls.openmirage.org/
Slide 17
Slide 17 text
Use a CDN if possible
TLS tuning for iOS (server-side)
Reduce RTTs (False start, session resumption)
Coming soon (?): TLS 1.3
Visit istlsfastyet.com
https://developer.apple.com/library/ios/qa/qa1727/_index.html
Use a CDN (shortcut)
H2 implementation tips
Consider server-side TCP tuning (initcwnd)
Use keep-alive for HTTP 1.1 clients
Measure before + after
https://tools.ietf.org/html/draft-stenberg-httpbis-tcp-00
Slide 24
Slide 24 text
Caching with
NSURLSession
Slide 25
Slide 25 text
Use the Cache-Control
header
• NSURLRequestUseProtocolCachePolicy
(default policy for NSURLSession)
observes the protocol spec.
• Cache-Control: max-age=,
public
http://nshipster.com/nsurlcache/
https://tools.ietf.org/html/rfc7234
Slide 26
Slide 26 text
The ETag Header
Device Server
200 OK
Last-Modified: Mon, 22
ETag: ad87...
GET /fave-cats.json
https://en.wikipedia.org/wiki/HTTP_ETag
GET /fave-cats.json
If-None-Matched: ad87..
304 Not Modified
Remote Virtual Interface
• rvictl creates an interface
for packet capture tools (i.e.
wireshark)
• Device must be plugged in
using USB
https://developer.apple.com/library/mac/qa/qa1176/_index.html
http://useyourloaf.com/blog/remote-packet-capture-for-ios-devices/
Slide 31
Slide 31 text
Wireshark setup
Download: http://wireshark.com/
Slide 32
Slide 32 text
...see all the packets
Slide 33
Slide 33 text
Instruments: Network
Must test on a real device.
Slide 34
Slide 34 text
Meh.
Must test on a real device.
Slide 35
Slide 35 text
HTTP Proxies
• mitmproxy: mitmproxy.org
(0.16 supports HTTP/2!)
• charlesproxy.com/Fiddler
(Nice UI, paid, no HTTP/2
support yet)
http://jasdev.me/intercepting-ios-traffic
Slide 36
Slide 36 text
mitmproxy: install notes
1.El Capitan python issues: use brew
install python
2. For simulator, must set proxy on OS X to
127.0.0.1:8080 to start capturing HTTP(S)
traffic.
3.Must install certificate after running proxy:
go to http://mitm.it on simulator.
Other tools: bad networks
• https://github.com/facebook/
augmented-traffic-control
• http://nshipster.com/
network-link-conditioner/
Slide 39
Slide 39 text
Checklist
Repeat this 5 times: the network is unreliable*.
Reduce the number of TCP connections.
Don't implement your own caching
scheme: use the protocol features.
Test and measure network traffic regularly.
*https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing
Slide 40
Slide 40 text
Last thought
The person who uses your app doesn't care about
network stuff. They just want it to be fast.
Slide 41
Slide 41 text
Thanks.
@smithclay · New Relic
UIKonf · 23 May 2016 · Berlin
Slides will posted on Twitter.