WWDC2017 Session 709

Transcript

[ Applause ]
>> Jeff Tu: Good afternoon,
everyone.
I'd like to welcome to you part
two to Advances in Networking, a
continuation of the session from
the past hour.
My name is Jeff Tu, and I'll be
taking you through the first
topic.
In this session we'll discuss
new URLSession developer API and
enhancements, networking best
practices, and other important
technology areas in networking.
Our first topic is new
URLSession API.
But before that, I'd like to
review the underlying API we'll
be talking about, which is
URLSession.
URLSession is an easy-to-use API
for networking introduced in iOS
7 and OS X Mavericks.
URLSession supports networking
protocols like HTTP/2; HTTP/1.1;
FTP; and custom streams with an
overall emphasis on URL loading.
If you provide it an HTTPS URL,
it also automatically provides
the encryption and decryption of
data between you and the web
server.
Last year we deprecated
NSURLConnection API.
So we encourage any new app
development to occur with
URLSession.
For more information on
URLSession, I encourage you to
review past WWDC sessions and
other online documentation.
Recall that there are different
kinds of URLSession objects that
you can create.
The basic object you can create
is a default configuration
URLSession object.
Default sessions have a behavior
where a task either fetches a
URL immediately; or if the
device can't connect to the web
server, fails immediately.
URL loads can fail because the
device isn't connected to the
Internet or if the server you're
trying to reach happens to be
down.
Those are just a couple of
examples.
Background URLSession objects,
on the other hand, don't have
this immediate fetch or fail
behavior but are scheduled out
of process and continually
monitored for network
connectivity to the server.
There are more examples of a
URLSession task failing because
of bad connectivity.
You might have no Internet
connection, you might be in a
theatre with your device in
Airplane Mode or it should be in
Airplane Mode.
Perhaps you have a session
object where you've disallowed
cell usage but the user only has
cell connectivity.
Or the server might only be
accessible behind a VPN and the
admin recently changed VPN
access.
How do you as an app developer
deal with a network load that
fails?
In the past, we've advised you
to use the SCNetworkReachability
API to monitor when you might
have connectivity again to the
server.
Other approaches are polling
every set period of time or
depending on the user to tap or
drag to refresh the UI.
The problem is that these
approaches add complexity to
your apps and aren't always
effective.
SCNetworkReachability only tells
you that you might be able to
reach the server, not that you
will.
You, our developers, have been
asking for an easier solution.
Wouldn't it be easier to say,
then, "Please fetch me this
resource when the network is
available"?
We're happy to tell you about a
new feature that lets you do
this.
We call this the URLSession
Adaptable Connectivity API.
This --
[ Applause ]
This API is available now on all
platforms.
By opting into this API, you
tell URLSession that in the
event that the task would fail
because of a lack of
connectivity that it should wait
for a connection to the server
instead of failing.
How do you opt in?
There's a new boolean property
called waitsForConnectivity.
Set this to true, and then you
get the new behavior.
I'd like to repeat what this
property does.
You go from the default behavior
of load it now or fail now if I
can't connect to load it now,
but if I can't and would have
failed because of a lack of
connectivity, try again when I
get a real chance to talk to the
server.
The API also waits when it
encounters DNS failures as well
since one network's DNS service
might fail to resolve but
another one may not.
Please note that this boolean is
a no op for background sessions,
as background URLSession objects
get this behavior automatically.
We'll tell you later in this
hour more about the differences.
You may be wondering, "Can my
code get a notification if it's
in this waiting state?"
You might want to have the app
present other behavior while
it's waiting to connect.
For example, having an offline
browsing mode or a mode that
operates when the user is only
on cell.
If you would like to know when
your app is in this waiting
state, you can optionally
implement the URLSession
taskIsWaitingForConnectivity
delegate method.
Note that this delegate method
is only called if you've opted
into the waitsForConnectivity
property with a true value.
If you've done this, the
delegate method itself will be
called only one time or not at
all if the task never had to
wait.
We recommend that your apps
always opt into the
waitsForConnectivity property.
This is because even when you
opt in, the task will still try
to run immediately.
The task will only wait if it
can't connect to the server.
There are rare exceptions to
opting into the property,
though.
For example, if you had a
URLSession task whose purpose
was to buy stock at market
price, you'd want that to run
now or fail now and not wait
until you had an Internet
connection.
I'd also like to mention that
when you opt into
waitsForConnectivity, the
timeout interval for request
timer starts only after you've
connected to the server.
Timeout interval for resource,
however, is always respected.
Let's summarize how we would use
the API and then go through a
code example.
The main thing is to opt into
the waitsForConnectivity
property.
You would create and resume the
URLSessionTask as before.
If the device can't connect to
the server, we'd call a delegate
callback if you implemented it
and only once.
All other URLSession methods are
still called same as before.
Remember, though, that this API
only has an effect for
non-background sessions.
Let's go through a sample code.
First create a session
configuration object and make
one for default session type.
Opt into the
waitsForConnectivity property.
Create the session object and
set the URL you want to load.
Use the session object to create
a task object.
And finally, resume the task to
get it started.
Even with adaptable
connectivity, your request may
still fail for other reasons.
For example, you could connect
to the server, but a new data
center employee might unplug a
server, cause the network
connection to drop, and all your
apps on your phone might
disappear.
Or your device connects to the
server and sends an HTTP
request, but there's so much
traffic that the request times
out.
For situations like these, we'd
like you to consult online
resources that go into more
detail on what you can do.
Retrying network loads in a
tight loop, though, is almost
always a bad idea.
You asked for a better way to
load network resources.
Better than polling for network
connectivity to the server and
better than reachability API
that won't guarantee a
connection to the server.
Let URLSession do the work for
you.
Opt into the
waitsForConnectivity Adaptable
Connectivity API.
If you opt in, the request will
still run immediately with no
performance penalty and only
wait if you can't connect to the
server.
Once it can connect, your
URLSession task behaves just
like it did before.
Continuing our theme of what's
new, I'd like to pass the mic to
my colleague, Jeff Jenkins.
[ Applause ]
>> Jeff Jenkins: Thanks, Jeff.
Well, good afternoon.
Hope you guys are having a great
WWDC.
And I'm exciting to be here and
thrilled to talk to you a little
bit more about some enhancements
we've made to the URLSessionTask
API.
Now, first I want to spend a
little bit of time talking about
background URLSession.
We haven't talked a whole lot
about it, so let me give you a
little bit of background on
that.
The background session
URLSession API allows your
application to perform
networking even if your process,
your application isn't running.
We monitor the system
conditions, CPU, battery, all
sorts of things to really find
of right time to do your
networking tasks.
Now, of course, if you implement
various delegate methods, we're
going to wake up your app and
call those delegate callbacks so
that you can handle that
information.
And, of course, we're going to
make sure your app is running
when your task completes so that
you can then process that data.
Now, one of the great use cases
for background URLSession is
taking advantage of another
feature on the system, which is
background app refresh.
Now, what this really does is
allows your application to have
the most current, the freshest
data, right?
There's nothing more frustrating
than pulling your device out,
launching an app, and the first
thing you're greeted with is
some sort of spinner, right?
You're waiting for this
application to start pulling
down data.
You want that data right away.
You want to be able to get that
data to your user so your user
is excited and happy to use your
app.
Background app refresh is a way
to do this.
It's a way to tell the system
that, "Hey, in the future I want
to be able to be launched so
that I can refresh my data so I
have the most important
information," maybe stock
information, or weather
forecast, other important things
that your app does.
Now, this applies to
applications, as well as watchOS
complications.
And if you want to learn a
little bit more in depth about
background app refresh, you can
go back to 2013 WWDC, as well as
last year's 2016 WWDC and look
at these sessions for more
details.
So let's look at background app
refresh in action; what is it
really doing?
And to do that, we kind of need
to look at the state of your
application.
We're interested in three states
here: A running state, suspended
state, or a background state.
Now, with your app running,
you're going to opt into
background app refresh.
You're going to say, "In the
future, run my app, make sure my
app runs so that I can get the
latest information."
And then your process could be
suspended.
And in the future your process
is now running, your app is now
going to be able to ask for new
data.
And like good developers, this
app is using URLSession API.
In fact, it uses a background
URLSession.
It creates a URLSession task and
schedules this task to run and
grab the data that your
application needs.
Now, your process could go away
at this point, but then at some
point URLSession is going to run
your task and it's going to run
it to completion hopefully if
everything goes well.
And you're going to get the
data.
So we're going to background
launch your application and
allow you to process that
completed task and process that
data that we've fetched for you.
And then at some point the user
is going to launch your app,
it's going to come foreground,
and boom, they've got the
freshest data there.
So this is great.
But we looked at this flow and
said, "Hmm, maybe there's
something we can do to help our
developers improve their
applications on our platforms."
And we think we can do something
for you.
The first problem that we want
to solve is we noticed there's
an extra background launch that
had to happen just for you to
create the URLSession task.
And as we all know, anytime your
process is launched, what does
that do?
It impacts battery life,
requires CPU burden.
So that's not necessarily great
for the device if we're doing
extraneous work, and we really
don't need to be doing that.
The other problem we'd like to
solve are stale network
requests, right?
You're asking URLSession to do
work.
And at some point in the future,
that work is going to complete.
Well, what happens between when
you ask for the work to be done
and when it actually got done?
Maybe there was some change in
context and that original
request doesn't make sense
anymore.
So we need to give you an
opportunity to really, if
there's a context change, let us
know about that and get rid of
these stale network requests.
Because there's nothing worse
than getting data and going, "I
can't do anything with it," and
throw it away.
And the last problem we think we
could help you with is helping
us know how to best schedule
your URLSession tasks.
When is the most optimal, best
time in the system to be able to
run your task so that we can get
your data in the most efficient
way for you to display that so
that your users are excited and
delighted by that data?
Let's look at what we did.
We're introducing the
URLSessionTask scheduling API.
Now, this is available across
all of our platforms.
It's available in the beta
builds that you have received
here at WWDC.
And we encourage you to take a
deep look at this.
Now, what we've done first is we
provided a new property.
This is a property on
URLSessionTask object.
It is called earliestBeginDate.
And what you're going to do here
is provide a date to us in the
future when you want your task
to be eligible for running.
I use that word eligible because
it's important.
It doesn't mean that this is the
point in time when your task
will run, it will do networking;
it's just telling the system, "I
would like my task to be
eligible so that it can run."
And we're still bound by system
policies as to when we can make
the networking happen for this
task.
It's only applicable to
background URLSessions and tasks
built off of background
URLSession.
Let's take a look at how this
property in conjunction with
other existing properties really
allows you to do some fine-grain
scheduling.
So you'll create a
URLSessionTask and, of course,
you'll call resume on it so that
we know that this task can now
be put into the queue so that
work can happen.
You'll -- and at this point the
task will be in a waiting state.
We're waiting for the
earliestBeginDate to happen.
And as soon as that is hit, that
task becomes eligible for
running.
Now, you can use the existing
timeoutIntervalForResource to
really control how long your app
is willing to wait for at that
resource to get loaded, right?
You might set some amount of
time to say, "After this point
in time, this resource isn't
interesting to me anymore."
And that interval of time covers
from resume to when that timeout
happens based on the value you
place in
timeoutIntervalForResource.
Now, I want to go back to the
original background app refresh
workflow that we looked at
earlier.
Right? We noticed there was a
couple of background launches
that occurred.
But with this new API we're able
to get rid of one of those.
So the way that your app will
work is while your running,
you're going to create a
URLSessionTask; you'll opt into
our new scheduling API by
setting an earliestBeginDate;
then your process can go to
sleep.
We're going to complete the work
for you.
And when that work is available,
we're going to background launch
you that one time and allow you
to process the resulting data.
And then when the user brings
your app to the foreground,
boom, it's got the freshest,
most current data.
And we've been able to solve
that one problem of that
additional background app
launch.
And so it's better performing on
the system, and we think that's
great.
So that's problem number one
solved.
Let's look at problem number
two, the stale network fetches.
We want to give you an
opportunity to alter future
requests.
So you might have given us a
request, but the context might
change.
We've introduced a new delegate
callback on a
URLSessionTaskDelegate titled
willBeginDelayedRequest.
With this delegate, you'll be
able to be called at the moment
when your task is about to start
networking.
So it is you've told this that
the task is eligible and the
system now has decided yes, this
is the right time to do the
networking.
We're going to call this
delegate method, if you
implement it, and allow you to
make some decisions about this
task.
Now, this will only be called
one, if you implement it; also,
if you opt into the scheduling
API by setting an
earliestBeginDate.
And, again, this is only
available on background
URLSessions.
And as I mentioned, this is an
optional delegate.
And I want to take a second here
to have you really think about
this because it's important,
this delegate method.
As with all delegate methods,
they're all opt into.
But this one will cause some
interesting side effect that
I'll show you in a minute.
You really need to think about,
"Can my application determine
context, the viability of a
request in the future?"
Now, there's a completion
handler that's passed to this
delegate method.
And you need to give a
disposition to URLSession.
You need to tell us does the
original request, does it still
make sense?
Go ahead and proceed.
Or maybe the context has changed
enough and you need to make some
modifications, maybe a different
URL or maybe a header value's
different and you want to go
ahead and modify that request at
this point in time right before
the networking happens.
Or you might make the decision
this request is just useless at
this point, cancel.
We don't want to do stale
requests.
So now if we go back to this
workflow and we go back to my
comment about really thinking
about this delegate method, you
will see that we're kind of back
to that original workflow where
there's two background launches
in order to satisfy this URL
task.
Right? But we have to stop and
think about that.
What is more expensive,
performing a stale network load
or a mere application background
launch?
It is way more expensive to the
system to do stale loads, get
all this data, and then decide I
don't need it and pitch it.
Okay? So we want you to really
think about this new delegate
method and whether your
application has the ability to
really understand the viability
of your requests in the future.
Hopefully that make sense to
you.
Now, the third problem we want
to solve is how do we schedule
your request in a most optimal,
most intelligent way in our
system?
There's some information that in
URLSession we just don't know
about.
So we're providing a little bit
of change to our API to allow
you to explain to us some
information about your requests
and also about your responses.
We're giving you two properties,
the first one is countOfBytes
ClientExpectsToSend, and the
second one is countOfBytes
ClientExpectsToReceive.
We think you know more about
your requests.
Maybe you have a stream body
that you want to attach to a
request, we don't know about
that.
You probably know the size of
that.
We don't know about your servers
and the size of data your
servers' shipping back.
We believe you have some insight
to that.
And that will give us hints as
how we can in a most optimal,
intelligent way schedule your
tasks.
If you don't know, well, then
you can always specify
NSURLSessionTransferSizeUnknown.
So that solves the third
problem.
Let's take a look at how this
new API works in code.
It's very easy to use.
First thing we're going to do is
create a URLSession background
configuration.
We're then going to create a
session based on that
configuration.
Once we have that, we're going
to now generate a URLRequest,
specify the URL we want to go
to, maybe set a header value,
something that makes sense for
your task.
Again, this is just an example.
And now we're going to create a
task that encapsulates that
request on that session.
And we're going to opt into the
new scheduling API by setting
the earliestBeginDate property
and give us a date.
In this example we say two hours
from now I want this task to be
eligible to be run.
And I'm also going to give some
hints to URLSession and say,
"This is a small request,
there's no body, I've just set
one header, maybe 80 bytes."
And then my server probably is
going to send about a 2K
response to this.
And with all URLSession tasks,
make sure you call resume.
Now, how does the new delegate
work?
Well, we decided I know context.
I can make some intelligent
decisions about my networking
tasks in the future.
So I've implemented
willBeginDelayedRequest.
So in our example here what I've
decided to do is to modify the
request.
I'm going to take the original
request, create a new
updatedRequest.
I'm going to maybe change a
value in the header that makes
more sense now that this task is
actually going to do some
networking.
Time has passed, I have new
information.
I put that information on that
task.
And then I'm going to call the
completionHandler and use a
disposition of useNewRequest and
passed it that new request.
If you take a look at our header
file, you can see other
dispositions available to you in
this completionHandler call.
So let me recap the scheduling
API that we're introducing here.
Background URLSession is an
awesome API for doing networking
that allows your application to
not even be running and have
this networking happen for you.
Our new scheduling API will
allow you to delay your requests
so that they can, you know,
obtain and pull down the
freshest information for your
application.
And it's really we give you an
opportunity to alter those
things based on the context and
the time at when the networking
is actually going to happen.
The other part of this API
change is to allow you to give
hints to us so that we can be
super intelligent and make these
tasks run at the most optimal
time on these devices.
Now, I'd like to turn the time
over to Stuart Cheshire, an
Apple distinguished engineer.
And thank you for your time.
[ Applause ]
>> Stuart Cheshire: Thank you,
Jeff.
Now we're going to talk about
enhancements in URLSession.
We have four things to cover,
let's move through them.
Often you want to show a
progress bar to indicate to the
users how progress is being
made.
And right now this is a little
bit cumbersome.
There are four variables that
you need to monitor with
Key-value Observing.
And sometimes the
countOfBytesExpectedToReceive or
Send is not always available.
The good news now in iOS 11 is
URLSessionTask has adopted the
ProgressReporting protocol.
You can get a progress object
from the URLSessionTask, and
that gives you a variable
fractionCompleted, which is a
number in the range zero to one.
You can also provide strings to
give more detail about what the
operation is.
You can attach that progress
object to a UIProgressView or an
NSProgressIndicator to get an
automatic progress bar.
You can also combine multiple
progress objects into a parent
progress object when you're
performing multiple tasks, such
as downloading a file,
decompressing a file, and then
handling the data.
So that makes your progress
reporting much simpler.
The binding between a
URLSessionTask and the progress
object is bidirectional.
So if you suspend a
URLSessionTask, that is the same
as pausing the progress object.
If you pause the progress
object, that is the same as
suspending the URLSessionTask.
We now have support for the
Brotli compression algorithm.
In tests this compresses about
15% better than gzip, which
results in faster network
access.
Like other new compression
schemes, this is only used over
encrypted connections to avoid
confusing middle boxes that
might not recognize this
compression.
Because Safari uses URLSession,
that's also means Safari gets
the benefit of this new Brotli
compression algorithm.
And many major websites have
already announced support for
Brotli in their web service.
Our next topic is the Public
Suffix List.
The Public Suffix List is
sometimes called the effective
top-level domain list.
And this is important for
determining where administrative
boundaries occur in the
namespace of the Internet.
One thing we don't want to allow
is for a website to set a cookie
on the com domain, which is then
accessible to any other dot com
company.
So you might be tempted to make
a rule that you can't set
cookies on top level domains,
only on second level and lower.
But domains are named
differently in different parts
of the world.
In America, Apple.com and
FileMaker.com are different
companies.
But in Australia many, many
companies are under com.au, and
that doesn't make them all the
same company.
So the Public Suffix List is a
file of rules and patterns that
tells software how to judge
where administrative boundaries
occur.
This is used for partitioning
cookies, and it's used by the
URLSession APIs.
And if you use the
HTTPCookieStorage APIs directly,
it's supported there, too.
We used to update this in
software updates, but now with
the more rapid progress in
creating top level domains,
we've changed to doing this over
the air.
We could push a new list every
two weeks if we wanted to.
URLSessionStreamTask is the API
you would use if you just want a
byte stream.
If you're not doing HTTP Style
Gets but say you want to write a
mail client,
URLSessionStreamTask gives you a
simple byte stream.
It supports upgrading to TLS
with the STARTTLS option.
If you have existing code that
is written using the old
NSInputStream and NSOutputStream
APIs, you can extract those
objects from a
URLSessionStreamTask to use your
old code.
But for any new code you're
writing, we strongly recommend
that you use the new native
URLSessionStreamTask APIs.
We announced this a couple of
years ago at WWDC 2015.
What we have new for you now is
automatic navigation of
authenticating proxies.
If the proxy requires
credentials, then we will
automatically extract those from
the key chain or promptly the
user on your behalf.
So we've covered the
enhancements for URLSession,
let's move on.
[ Applause ]
Thank you.
Tips and hints that we've
learned from our years helping
developers.
Number one rule: Don't use BSD
Sockets.
And by the same token, we
encourage you not to embed
libraries that are based on BSD
Sockets.
Because we do lots of work, as
you've been hearing today, to
provide benefits to your
applications.
We provide Wi-Fi Assist so that
your application succeeds
instead of failing when Wi-Fi
isn't working.
We provide techniques to
minimize CPU use and minimize
battery use to give users longer
battery life.
We have the ability to do tasks
in the background when your
application isn't even running.
And the third-party libraries
just can't do anything when
they're not in memory running.
And final bit of advice: Always
try to use connect-by-name APIs
as opposed to APIs where you
resolve a name to an IP address
and then connect to the address.
We talked earlier about the
requirement for IPv6 support.
And the reason that almost all
of your apps worked perfectly is
because when you use
connect-by-name APIs, you don't
get involved with the IP
addresses.
And if you're not involved with
the IP address, you don't need
to care whether it's v4 or v6,
it just works.
Another question we often get is
about the timeout values.
So I want to recap that.
The timeoutIntervalForResource
is the time limit for fetching
the entire resource.
By default, this is seven days.
If the entire resource has not
been fetched by that time, it
will fail.
timeoutIntervalForRequest is a
timer that only starts once the
transfer starts.
Once it starts, if your transfer
stalls and ceases making
progress for that time-out
value, that when that timer will
fire.
We have seen developers that
take their old NSURLConnection
code and convert it to the new
URLSession code by mechanically
making a URLSession for every
old NSURLConnection they used to
have.
This is very inefficient and
wasteful.
For almost all of your apps what
you want to have is just one
URLSession, which can then have
as many tasks as you want.
The only time you would want
more than one URLSession is when
you have groups of different
operations that have radically
different requirements.
And in that case you might
create two different
configuration objects and create
two different URLSessions using
those two configuration objects.
One example is private browsing
in Safari where each private
browsing window is its own
separate URLSession so that it
doesn't share cookies and other
states with the other sessions.
Most apps can just have one
statically-allocated URLSession,
and that's fine.
But if you do allocate
URLSessions dynamically,
remember to clean up afterwards.
Either finish tasks and
invalidate or invalidate and
cancel.
But if you don't clean up,
you'll leak memory.
We get developers asking us
about convenience methods and
delegate callbacks.
Delegate callbacks give you
detailed step-by-step progress
information on the state of your
task.
The convenience methods, like
the name suggests, are a quick
and easy way of using the API.
With convenience methods you
don't get all the intermediate
delegate callbacks, you just get
the final result reported to the
completionHandler.
Don't mix and match both on the
same URLSession, pick one style
and be consistent.
If you're using the
completionHandler, you will not
get the delegate callbacks with
two exceptions.
If networking is not currently
available and the task is
waiting for connectivity, you'll
be notified of that in case you
want to show some indication in
your UI.
The other delegate method you
may get notified is the
didReceive
AuthenticationChallenge.
So here's a summary of the
options available to you.
Doing URLSessionTasks in your
process with waits for
connectivity as we recommend,
the task will start immediately
if it can; or if it can't, it
will start at the first possible
opportunity.
You also have the option of
doing tasks in the background.
And you can do background
discretionary tasks, which will
wait until the best time in
terms of battery power and Wi-Fi
networking.
Now I have a couple of ongoing
developments to talk about.
I'm sure many people in this
room have heard about TLS 1.3.
TLS, Transport Layer Security is
the protocol that encrypts your
data on the network to prevent
eavesdroppers from seeing it and
perhaps as importantly to make
sure that you have connected to
the server you intended to
connect to.
TLS 1.2 is very old at this
stage.
It has a number of problems that
have been discovered.
And TLS 1.3 is almost finished.
That standard is not quite
finalized.
Apple is participating in that
IETF working group, and we
expect that to be finished by
the end of this year.
In the meantime, we do have a
draft implementation if you want
to experiment with it right now.
And if you check out the
security session from this Apple
Developer Conference, you can
learn how to experiment with
that.
Another thing you may have heard
of is QUIC.
QUIC is a new transport protocol
designed to experiment with new
ideas that are hard to do with
TCP.
QUIC started out as an
experiment by some Google
engineers, and it was a very
successful experiment.
They learned a lot.
Some ideas were good, some
turned out not to work as well
as they hoped.
Those engineers have taken those
lessons they learned to the
IETF.
We have formed a new working
group to develop the IETF
standard QUIC protocol.
Apple is also participating in
that working group.
That is not nearly as far long
as TLS is, but that is also
making good progress.
Before we finish, one other
thing we should talk about,
Bonjour.
Fifteen year ago at this very
convention center in San Jose,
Steve Jobs announced Bonjour to
the world.
And I got the opportunity to
tell you all how it worked.
A lot has happened since then.
Since we launched it in 2004, we
brought out Bonjour for Windows,
for Linux.
We had Java APIs.
The next year Mac OS X 10.4
introduced wide-area Bonjour to
complement the local
multicast-based Bonjour that was
in the original Mac OS 10.2
launch.
The same year the Linux
community came out with a
completely independent
GPL-licensed implementation of
Bonjour called Avahi.
A couple of years after that,
Apple shipped Back to My Mac,
which is built on the wide-area
Bonjour capabilities introduced
in 10.4.
And in 2009 we brought out the
Bonjour Sleep Proxy, which let
you get Back to Your Mac at
Home, even when it was asleep to
save power.
In the years since then, Android
adopted with Bonjour with their
own native APIs in 2012.
That was in API Level 16 for
those of you paying attention.
And a couple of years ago,
Windows 10 added their own
native Bonjour support.
Now, I know a lot of people in
this room are well aware of the
history.
We know about the major OS
vendors adopting Bonjour.
But something else happened that
surprised even me: Bonjour
started showing up in a lot of
other places.
And I want to illustrate this
with just a little personal
anecdote.
I recently bought a new house.
And as part of the process of
buying a new house, you often
end up buying a bunch of new
stuff.
And I started adding things to
my home and connecting things to
the network.
And I started finding a bunch of
stuff showing up in Bonjour.
Now, I bought a new printer; it
had Bonjour.
I bought some Access Network
security cameras, they had
Bonjour.
That didn't surprise me because
we know printers and network
cameras were among the first
devices to adopt Bonjour.
But then I got a surround sound
amplifier and it had Wi-Fi, and
it had an embedded web server
with Bonjour.
Now, you can set up the
amplifier with the TV and the
remote control, but naming the
inputs with up, down, left,
right on the remote control one
character at a time is really
tedious.
Being able to do this on my
laptop or on my 27-inch iMac
with a keyboard and a mouse is
such a nicer way to set up a new
piece of equipment.
I bought another amplifier from
different company, it also had
Bonjour.
I got solar panels on the roof
of the house to save on the
electricity bill, the inverter
has Wi-Fi with an embedded web
server advertised with Bonjour.
So now with one click, I can see
a graph of how much power I've
produced in the day.
My most recent purchase was an
irrigation controller to control
the sprinklers that water my
lawn.
It has Wi-Fi with an embedded
web server advertised with
Bonjour.
Compared to trying to program
your garden sprinkles with a
two-digital LCD display and the
plus minus buttons, this is such
a glorious experience to see it
all on my big iMac screen at the
same time.
[ Applause ]
So thank you to all you device
makers who are making these
wonderful products.
For the app developers in the
room, how does this affect you?
The IETF DNS Service Discovery
Working Group continues to make
progress.
We have new enhancements to do
serve discovery on enterprise
networks where multicast is not
efficient and on new mesh
network technologies that like
Thread that don't support
multicast well.
The good news for app developers
is this is all completely
transparent to your apps.
The APIs haven't changed because
we anticipated these things even
15 years ago.
The only thing to remember is
when you do a browse call and
you get back a name, type, and
domain, pay attention to all
three.
You may be used to see the
domain always being local, but
now it may not be local.
So when you call resolve, make
sure to pass the name, type, and
domain you got from the browse
call.
And for the device makers out
there, don't forget to support
link-local addressing.
Link-local addressing is the
most reliable way to get to a
device on the local network
because if you can't configure
it, you can't misconfigure it.
[ Laughter ]
So to wrap up, in part one we
talked about ongoing progress in
ECN.
It's now supported in clients
and servers, the stage is set.
Any ISP can now see an immediate
benefit for their customers by
turning on ECN at the key
bottleneck links.
Continue testing your apps on
NAT64.
Mostly known use there, we're
very happy everything is going
smoothly.
We have a move to user space
networking, which also doesn't
change the APIs.
But you may notice when you're
debugging and looking at stack
traces, you may see symbols in
the stack trace you're not used
to.
You may see differences in CPU
usage.
We wanted to you to be aware of
that so it didn't surprise you.
We have new capabilities in the
network extension framework.
And the big news, we have
multipath TCP as used by Siri
now available for your apps to
use as well.
Thank you.
[ Applause ]
In part two, we covered some
enhancements in URLSession,
especially the
waitsForConnectivity, which is
really networking APIs done the
way they always should have
done.
When you ask us to do something,
we should just do it, not bother
you with silly error messages
that it can't be done right now.
You ask us, we will do it when
we can.
I gave some tips about best
practices and news about ongoing
developments.
You can get more information
about this session on the web.
We have some other sessions we
recommend you hear that you'll
probably find interesting.
Thank you.
[ Applause ]