The next wave of the Internet's evolution is happening now. You'll learn best practices for supporting IPv6, restricting cellular usage, and using Quality of Service to create a fast lane for your iOS apps. Discover how to support a multilingual Internet by using UTF-8, and how new internationalized domain names and email addresses affect you.
It's great to see so many people here.
How many of you are here for the first time at WWDC?
Wow! That's incredible.
I hope WWDC is going well for you.
Now we're going to talk about some networking topics.
I've got five things to cover today.
We're going to give you an update
on Explicit Congestion Notification
that we talked about last year.
We're going to give you an update in the progress on IPv6.
We're going to talk a little bit about international text,
which is becoming increasingly important.
We're going to explore how you control access
to network interfaces to avoid running
up big data bills for your customers.
And we're going to finish off with some discussion
of network quality of service.
You may have heard about the Apple Cisco
We're going to talk a little bit about how
that might apply to your applications.
So let's start with ECN.
To recap from last year,
we showed how Smart Queue Management
and marking packets instead of dropping them can lower latency,
reduce delays due to retransmission,
and improve the user experience for all applications,
and especially for things like streaming video.
In iOS 9, we did not enable ECN for TCP connections,
but in an unrelated change,
the VPN software would pay attention to ECN markings.
We found one ISP in Germany that marked all packets
"congestion experienced," which was bad for VPN.
The good news is they fixed their network
within a couple of weeks.
We had no reports of any problems anywhere else
in the world, and what that tells us now is we rolled
out iOS all around the world, found one problem, fixed it;
the Internet is now safe for ECN.
And because of that, in iOS 9.3 and OS X El Capitan,
five percent of TCP connections at random are using ECN,
and we're using this to gather performance data and check
that the Internet continues to be safe for ECN.
In the Developer Seed that you have already,
100 percent of Wi-Fi connections and 100 percent of connections
on these three carriers are now using ECN.
So last year, I reported that 56 percent
of the Alexa top million websites supported ECN,
which is a pretty impressive support number
for a technology no one was using.
I talked to my good friends at ETH Zurich, and Brian,
Brian Trammell and Mira Coolwind,
and their colleagues reran the experiment for us.
This year the percentage is up to 70 percent.
And if you only look at IPv6 sites, it's up to 83 percent.
So this is a call to action to ISPs and carriers
and their vendors who sell equipment to them.
The clients are now doing ECN.
The services are supporting ECN.
It's time for the network in the middle
to start marking packets instead of dropping them.
It gives you a better user experience,
it reduces delays due to retransmission,
and it makes more efficient use of your network
because you are avoiding wasted bandwidth
Our next topic is IPv6.
World IPv6 launch was four years ago last week,
and it continues to grow.
I looked at a variety of statistics, and I'm going
to show you just a small sampling here.
I looked at accesses to Apple's home page but coming over IPv6.
In Belgium, it's now up to 39 percent.
On T-Mobile USA, we're up to 54 percent.
On Verizon, we're up to 74 percent.
So it's pretty clear now on these carriers
that IPv6 traffic is the majority.
And the reason is clear.
IPv6 is simpler, it's more reliable,
it's less expensive to operate.
So it's very clear why the carriers want to move to IPv6.
But at what cost to developers and customers?
Is IPv6 less mature?
Is it slower?
Is there less capacity allocated to IPv6?
These are important questions, and content providers
and developers pay close attention to this.
They use statistics gathering in the web browsers
to measure things like page load times for every single one
of their users viewing the web page and report that back,
so they can tell how well their product is working
in different countries around the world, different ISPs,
different carrier networks.
LinkedIn reports that now 10 percent of their traffic is
over IPv6, and they find the page load time on average is 10
to 40 percent faster than over IPv4.
They theorize that that is due to less overhead,
setting up connections through overloaded large scale NATs.
Facebook found similar results.
45 percent of their traffic is now over IPv6,
and they reported recently
that on average ATP GET requests are 15 percent faster over IPv6.
If you only look at the iPhone data in that collection,
it turns out to be 30 percent over IPv6.
So IPv6 is better for network operators.
It's better for users and content providers.
And that's why Apple is 100 percent backing the move
And you will have all seen this announcement last month.
We announced last year we were going to be requiring all apps
to be compatible with IPv6 networks,
and we said we would be testing all apps on our own IPv6 network
with the NAT64 Gateway.
Starting this month we started enforcing that requirement,
and we looked very closely for any evidence
that this was causing an increase in the rate
of application rejection, because if that were the case,
we would have to look into it and work out what to do.
But the good news is, look as hard as we can,
we don't find any change in application rejection,
so what that really tell us is that 99 percent of you have apps
that are working just fine with IPv6 support,
which is what we expected, but it's still really good
to have that confirmed.
Now, if you've had an app rejected
and you think it might be to do with IPv6, then come on down
to the labs today or tomorrow.
You can test your app here at WWDC on the NAT64 network,
and we can help you troubleshoot what might be going wrong.
Our advice continues to be, as it always has been,
use the high level APIs that are address-family agnostic.
If you have to use the low level BSD APIs,
then there is extra work that you are going to have to do,
which is why we really advise using the high level APIs
that do that for you.
Another key piece of advice is use hostnames,
not literal IPv4 addresses.
Because IPv4 addresses are inherently tied to IPv4.
And let me give you a little picture showing why.
This is a typical situation from a few years ago.
You have a client on IPv4.
You have a server on IPv4.
The packets make their little detour via the NAT Gateway,
and that's how you connect to the server.
Nowadays, many more carriers are rolling out IPv6 networks
with a NAT64 Gateway, and the packets still make their little
detour through the NAT Gateway and connect
to that old legacy IPv4 service on the Internet.
Now, if your data center guys bring up dual-stack services
but you're still using v4 literals in your apps,
then the packets are going to make that same detour
through the NAT to get to the v4 interface at the service.
But if you look up by hostname
and they put the IPv6 quota records into the DNS,
that's how you get the straight through data path without going
through the NAT Gateway.
I talked about literal addresses.
We now support using IPv4 literal addresses
in selected APIs.
And if you use one of those addresses,
we will actually do the DNS64 synthesis for you locally
on the device, create a temporary IPv6 address
corresponding with your v4 service on the Internet,
and then connect through the NAT64 Gateway.
Now, remember, using literal v4 addresses will prevent your app
from ever connecting to an ATV6 server.
But that said, if that's what you need to do for your app,
here is an example of how you do it.
If you're writing code using Swift
and the high layer Cocoa APIs, this happens
for you automatically.
But if you're writing UDP code today
and you're using BSD sockets, the API you need
to use is getaddrinfo.
You pass in the address you want to connect
to as a literal string.
You pass in the port you want.
Here https is a synonym for port 443.
You loop through all the addresses you get.
Remember, don't just take the first one.
You'll get back an array of multiple addresses to try, and,
of course, free the memory when you're finished.
Another question we get from developers is
about the Internet of things.
There are developers writing apps that interact
with the device that they don't make,
and some of those devices are not very modern.
Now, we'd like those devices to support IPv6.
And if they don't support IPv6, we recommend that they
at least support IPv4 link-local addressing.
So even on a v6 only network,
devices can use v4 amongst themselves to communicate
with link-local addressing.
Now, if the device can't do either
of those things, that's okay.
Inform app review, when you submit your app,
that is not grounds for rejection of your app.
It probably is grounds for putting one
of these stickers on the device.
[Laughter] And remember, all off link communication still have
to be compatible with IPv6 and NAT64.
So to summarize, we recommend you support both IPv4 and IPv6
at both ends, in the clients and the servers.
We recommend you use hostnames.
That way you can get a v4 address on a v4 network
and a v6 address on a v6 network.
If you do need to use literal addresses,
those are now supported in select APIs,
as long as you do it properly.
But remember, imbedding v4 literals will block
communication to v6 servers in the future.
So that brings us to our next session, international text.
You may have started to see things like this,
and if you're a native English speaker,
this can look pretty daunting and scary.
And what I want to talk
about today is how simple this really is.
International support in your application doesn't need
to be a big task.
In fact, it really is no harder than supporting ASCII.
So even though the title of this session is International Text
and Networking, really we can scratch the networking.
For now I just want to talk
about how you support international text in general.
I'm going to start with some background.
Not because many of you will need to encounter this day
to day, but I want to de-mystify some of this
and make it less scary, because it really isn't any more
complicated than ASCII.
So the first concept we have is Unicode.
Unicode is a big list of numbers, and corresponding
to each number a human visible character,
and it's like a big phone directory.
In fact, it is available in book form.
It's a big, thick book with page after page
of number and character.
And that's an abstract concept.
You have integers and you have the characters they represent.
Now, to use those integers in our computers, we need some way
of representing those numbers, in memory,
on disk, over the network.
One way of representing them is UTF-32,
which is just a 32-bit number.
And like any 32-bit number,
you have to be concerned whether it's big endian
or little endian.
And it takes up four times as much space as ASCII.
UTF-16 is more compact.
It uses 16-bit numbers.
It still has the same problem of little endian versus big endian,
and because it's only 16-bits,
it can only represent 65,000 values.
So you have to use the surrogate pairs
to represent the values outside that range.
So that's a bit cumbersome.
UTF-8 is an 8-bit byte-oriented encoding.
Because of that, there are no byte order issues,
and this is really what makes it the ideal encoding to use.
So let's dive in a bit deeper into UTF-8.
It was invented late night in New Jersey 1992, and it's one
of those rare pieces of computer science genius.
And when I first heard about that,
I immediately saw, this is the answer.
This solves the problem for international text.
So I want to tell you guys a little bit about how it works
so you can understand how simple it is.
The Codepoints in Unicode from 0
to 7F are exactly the same as the ASCII values.
And UTF represents them using the exact same bytes in memory.
So what that means is if you've got a disk full
of plain ASCII files, I can wave my magic wand over it and say,
I declare you to be UTF-8.
Not a single byte on disk changes.
The meaning of the files doesn't change.
You have automatic backwards compatibility with all
that legacy of ASCII, so that is a wonderful thing.
UTF-16, UTF-32, other encodings don't have that property.
For the values that are outside the ASCII range,
they are represented as multi-byte sequences.
But all those multi-byte sequences only use byte values
So there was no overlap between the ASCII characters
and the multi-byte encodings
of the higher value Unicode Codepoints.
That property is not true of other encodings
that re-use the high code bytes to mean something else.
UTF-8 has three flavors of bytes.
It has the plain ASCII bytes.
If a byte starts with the most significant bit being 0,
that tells you it's plain ASCII.
If the top two, three, or four bits are 1s,
that tells you it's a two, three, or four byte sequence.
And if the top bits are 1 0,
that tells you it's a continuation
of a multi-byte sequence.
So I'll show that in context.
The ASCII characters stand alone.
The bytes with two leading 1s signify two byte sequence.
Three leading 1s is a three byte sequence.
Four leading 1s is a four byte sequence.
And this gives it a wonderful property that you can jump
into the middle of a UTF-8 file anywhere, and by just looking
at any old byte, you can tell what you've got.
Does this stand alone as ASCII?
Is this the start of a multi-byte sequence?
Did I land in the middle of a multi-byte sequence and I have
to skip forward or back to find the character boundary?
So it's very, very robust to insertion and deletion errors.
It's an encoding that is efficient enough to be compact
but has just enough redundancy to be very reliable.
Another useful property it has is in an UTF encoding
of a string, there are no 0 bytes.
And C treats 0 as the string terminator,
so that's a very useful property.
UTF-16 strings have zeros all over the place.
And another nice property is
if you do a naive simple byte-wise string sort
on UTF strings, they sort in the same order
as if you sorted the Unicode Codepoints directly.
So a whole bunch of really wonderful properties,
and this is why just six years after Ken Thompson invented it,
the IETF issued a document saying that from then on,
all new Internet standard protocols had
to work with UTF-8.
And that philosophy has been embraced on the web.
Four years ago, Google did a survey and found that 80 percent
of web pages were UTF-8, and that includes a small percentage
that were old fashioned, plain ASCII,
which is of course a compatible subset of UTF-8.
Last month that number is now up to 87 percent.
And because of that, the W3C, just like the IETF,
also recommends that we only use UTF-8 for everything.
And this is wonderful.
There is, however, one catch.
For some reason, lost in history,
the DNS community decided not to do that,
and they invented a different encoding
that they call Punycode.
And Punycode re-uses existing ASCII byte values
to mean different things.
So those are the byte values that correspond
to letters, digits, and hyphens.
A result of this is that if we have a block of bytes,
I can interpret those bytes as ASCII values and get something
like that, or I can interpret them as being Punycode encoding
and get what they're meant to be.
And that dual interpretation
of the same bytes can be very problematic,
because it becomes unclear what you want to display to the user
or what the user meant.
If we contrast that with UTF-8,
the first thing you notice is the encoding is more compact.
It takes fewer bytes,
and there's also only one valid interpretation.
So there was no ambiguity there.
The good news for you guys is you don't need to care
about this, because we handle it for you.
In iOS 9 and OS X El Capitan, if you tried
to ping a UTF-8 hostname on the command line, it would fail.
You type in UTF-8, those characters pass through the tool
to the APIs on to the network, but that name was not put
into the DNS as UTF-8 and it fails.
Starting now in iOS 10 and macOS Sierra, the same ping command
on the command line with the same UTF-8 input,
we will now translate that automatically to Punycode,
do the query, and it will be successful.
Now, here the ping command is taking that Punycode
and displaying it as if it were ASCII so you get this gibberish
on the screen instead of the actual name that you meant,
and that's part of the problem
of having dual interpretations of the same string.
But the good news is all the Bonjour
and DSA APIs will now accept international text input
in UTF-8 format, because --
Because the Punycode format is quite restrictive,
it doesn't support even simple things like spaces in names,
and we use DNS for Bonjour search discovery, we don't want
to be that restrictive.
So the way the algorithm works, which is what's documented
in RFC 6763, we will first try UTF-8 as is,
and if the DNS administrator put UTF-8 into their zone file,
which is very easy to do, and people were doing that back
in the '90s, we do the query, we are successful,
we get the result, everything is fine.
What's new now is that if we fail, instead of giving up,
we will do one more try with Punycode and see if that works.
So we support both in the same API.
Email addresses are also becoming
And this is also not hard to do, but users face problems
for a silly, trivial reason.
Many apps, when you sign up for an account or you go
onto the website to sign up for an account, they try to validate
if the email address is valid and they check whether it ends
in .com or things of that form.
And users with perfectly valid email addresses are not allowed
to sign up for accounts because their email address is rejected.
So we need to remove those ill-advised validators.
Really the only thing you can check
for in an email address is it has to have an @ sign.
And if it's got that, it could be a valid email address.
If you want to know if it's valid, send a validation email
and have the user respond to confirm that it's live.
If you're writing an email client or an email server,
there are a bunch of RFCs you are going to need to look at.
But for the rest of you, you don't need to worry about that.
Let the user enter their email address as UTF-8,
stick it in your customer database,
and have the mail server send that out correctly encoding
with the email standards.
So to wrap up this section, we recommend UTF-8 for everything.
Makes everything so much simpler.
Don't worry about Punycode.
We handle it for you.
And be liberal about accepting user input
in this new international multi-lingual world.
That brings us to interface selection.
Now, Wi-Fi Assist is something that we introduced last year.
Really, this is not new.
This is the way things have worked
since the very first iPhone.
If I have Wi-Fi, I want my phone to use it.
If I don't have Wi-Fi, that's why I pay for cellular data,
so I have network access outside the home as well.
And the first iPhone did this.
What we changed last year is we did it better.
We were smarter about making that determination,
because there's always this gray area right
on the edge of a Wi-Fi network.
And mobility factors into this as well.
We have a situation that we call the parking lot problem,
and it happens at the end of the day when you leave work.
You leave the office, you get your phone out, you have Wi-Fi,
you're walking out to the car and you want to check maps
or weather forecasts or look for movies or something
and your phone thought it had Wi-Fi.
It had Wi-Fi a moment ago, but you just walked out of range
and it hasn't realized yet.
With Wi-Fi Assist, we will detect that.
We'll try to use Wi-Fi.
If it doesn't work, we'll use cellular instead.
But like any new feature, there's sometimes a tendency
for the new thing to be the whipping boy that gets blamed
for people's problems.
Everybody hates it when some app uses a ton of data
and they get a big bill they weren't expecting,
and it's human nature to blame the new feature.
But if you actually look at your Wi-Fi Assist data,
you will probably find they are very small.
Wi-Fi Assist is normally not the problem here.
Now, apps have the switch.
If you don't want that app using lots
of data, you can turn it off.
But that's very crude.
That's kind of an all or nothing switch.
And a lot of apps want to do something a bit more subtle.
Say you have a video streaming app.
You may want the user to be able to browse the catalog,
see little thumbnail pictures,
read the descriptions over mobile data.
Doesn't cost very much.
But you may want the setting in your app
that says don't stream videos over mobile
because users may not want to spend
that much money on mobile data.
And if you have that, you're going to want to be able
to differentiate between getting the thumbnail, which is allowed
over cellular, and streaming the video, which is not.
A lot of developers have done things like this.
They use the reachability API to say, am I on cell?
Yes or no?
If I'm not on cell, go ahead and do that download.
Well, things don't stay the same in networking.
Things change from second to second.
And between you checking whether you're on cell
and actually doing the connection,
the user may be walking across the parking lot.
So this is not the right way to do it.
The right way to do it is to express your intent
to the networking layers, and we will honor what you tell us.
The first step here is don't bother with preflight checks.
If you want to do a network transaction, just try it.
If that's a transaction that you don't want to use cellular data,
then you can express that to the networking layers.
Using the CoreMedia APIs,
you set the allow cellular access key using NSURLSession.
If you set allows cellular access to false,
then we won't use cellular data connection.
Nice and simple.
If that connection fails, you can ask the user,
do you want to stream this video over mobile data,
or you can just wait, subscribe for better route notifications,
and when the phone comes back on Wi-Fi, you'll be told about it
and then you can retry your connection once Wi-Fi is
So to summarize, don't assume that because you're
on Wi-Fi now, you will still be on Wi-Fi one second from now,
or even half a second from now.
Express what you want to the networking layers
and we will respect that.
Our last topic is networking quality of service.
Last summer, we announced a partnership between Cisco
and Apple, and I'm going to tell you a little bit about one
of the new APIs that you can use to express your needs
to the networking layers.
There are different kinds of networking traffic.
99 percent of what we do is good,
standard Internet best effort traffic.
We want the best throughput we can get,
and ideally we'd like low delay.
But we definitely want as much throughput as we can get.
This supplies browsing the web, sending an email.
Another thing that we do is online backup,
uploading photos to iCloud.
And that also wants to have good throughput, but not as good
as the priority stuff.
We'd like to be able to upload all of our photos to iCloud
in the background without disrupting our Netflix TV binge.
The photo upload should take place when we're sleeping.
It is what we call scavenger-class traffic.
It uses the otherwise idle capacity of the network
that would otherwise have been wasted, but it is second class
to sending emails, browsing the web,
anything that the human is actively involved with.
The third class of traffic is telephony,
interactive voice and video.
And I say interactive, because that's the key thing.
When we're having a conversation, I speak,
you hear me, you respond, you speak back, I hear you.
If that round-trip is more than a couple hundred milliseconds,
human communication breaks down.
When people talk about voice and video, it's important to realize
that watching a YouTube video may be video,
but it's not interactive.
It doesn't need that sub 200 millisecond round-trip time.
Listening to a podcast may be voice;
that doesn't mean a podcast is voice traffic.
It's not interactive.
So that's why I labeled this part of the chart telephony,
because this is interactive voice and video.
For that traffic you want the lowest round-trip time possible,
and it's very small throughput.
It's a few kilobits per second.
You don't need 50 megabits of voice.
So marking your traffic
as telephony tells the network keep the latency low,
but you also don't have a big queue.
If you try to do any kind of bulk transfer as voice class,
you're going to lose most of your packets,
because a very small amount
of the network capacity is allocated for that traffic.
So one of our FAQ questions people ask us,
will Fastlane make my app faster?
And the answer is no, it doesn't make it faster.
It will lower the latency for voice traffic.
You may be wondering, how does this relate
to the Smart Queue Management
and Explicit Congestion Notification
that we were talking about earlier?
And the answer is those technologies improve the delay
for all traffic across the board,
but telephony will probably still be an extreme case
that wants the very, very lowest latency
and doesn't mind sacrificing throughput to get that.
Starting in iOS 5 we had the network service type API,
and that lets you express some of these needs to the network.
But many of the developers writing apps like Skype
and Facetime that are doing this kind
of voice telephony are using UDP.
And to use UDP today on iOS, you need to be using BSD sockets.
So we now have a socket option
that exposes the same functionality
so your UDP clients can benefit from this.
We know some developers had been previously setting the IP type
of service bits in an attempt to get the same effect.
The problem is those type
of service bits are not well defined.
They are not specified anywhere.
Some Wi-Fi chip vendors will look at the type of service bits
and use that as a hint to set the Wi-Fi traffic class
to voice, video, background.
But the problem is with no standard definition of the bits,
that interpretation is not consistent.
So you may test it in your office and think it works fine,
but for a customer, it does something different.
And that's why we have the new socket option
that gives you reliable,
consistent behavior across all devices.
If you're writing Swift code,
you can set the network service type property
to voice, video, or background.
Or if you don't set it at all,
then that is traditional best effort.
If you are using the socket option,
we have the same options.
We have about another seven more than this, which is more
than most of you will need.
These are the four interesting ones.
When you set these options, a couple of things happen.
On the device itself, there are multiple outband queues,
and the type of service you set
for your traffic controls which queue it uses.
On Wi-Fi interfaces, it will also set the wireless
multi-media access category.
This is supported on all devices, iOS and OS X,
and the outband queue selection also applies
for Ethernet as well as Wi-Fi.
Now, if your device is on one
of these new Cisco Fastlane networks, we will recognize that
and we will also set the IP layer differentiating services
Code Point so that you get that handling that you want,
not just on the first hop leaving the device
but in subsequent hops through the enterprise network.
I want to stress this is not something that you all need
to feel obliged to go away and change your code.
If you're writing an online backup app,
definitely set background traffic class.
If you're writing the next Skype, then set the voice class.
But for the rest of you,
standard best effort is almost certainly what you want.
Some other things you ought to remember:
The outband queue selection and Wi-Fi layer,
quality of service marking is supported on all devices,
but remember it only applies to outband packets.
The packets coming in have to be marked by the thing
at the other end sending them.
And the IP layer marking is also only for outbound packets.
It's today only supported on Cisco networks
with compatible hardware.
It's only on iOS.
It's not supported on Macs or Apple TV or anything else.
And for now it's only supported on Wi-Fi.
I know most people don't use Ethernet with your iPads,
but if you do plug in an Ethernet adaptor,
the quality of service is not supported on Ethernet.
And finally if the administrator chooses
to install a management profile on the device,
then that management profile can restrict which apps are allowed
to use this type of service option, and only apps
that are listed in the profile will be able
to set type of service.
It will be a no op for all other apps.
So to summarize this section,
most of your traffic should continue to be best effort.
If you are doing large, bulk transfers
that are not time critical, background traffic is a way
for you to be less disruptive
and be a better citizen on the network.
Remember, it's not a priority level.
There isn't a ranked ordering here
of high priority to low priority.
It's a web expressing whether you want low throughput
and low latency or high throughput and moderate latency.
So that ends our session.
Thank you for coming.
We've talked about Smart Queue Management, and this is a call
to action to all the ISPs and carriers and network vendors.
The clients are supporting ECN.
The servers are supporting ECN.
If you start marking the packets in your network instead
of dropping them, you will make your users much happier.
The message for developers
in the room is IPv6 is now the majority of traffic
for many carriers on many networks.
Support IPv6 in your applications.
Support IPv6 and IPv4 in your servers.
For your text, UTF-8 is the new ASCII.
It's no harder than ASCII.
It's really very simple to use it.
All of our devices now have good support
for all the Unicode characters in the fonts,
so you should have no worries
about supporting UTF-8 without hesitation.
And finally, we have new ways for you to express intent
to the networking layers.
You can control when you don't want to use cellular data,
and you now also have finer control
of the throughput latency characteristics of your data.
So with that, there's a link
where you can find more information.
We have other sessions that you can watch on video
that you may find interesting.
We have sessions about networking
and security, which is important.
We have a couple of other sessions
We have some sessions
about higher layer networking applications, like HomeKit.
So with that, thank you for coming to WWDC.
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.