WWDC2016 Session 711

Transcript

X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Music ]
[ Applause ]
>> Thank you.
Thank you.
Good morning.
Thanks for coming
and being here today.
This is NSURLSession: New
Features and Best Practices.
My name is Jeff Jenkins.
I'm a Software Engineer
in the Internet Technologies
Department.
I think we have some great
information that we'd
like to share with you today
within the NSURLSession.
So why don't we just get started
and jump right into an agenda
and show you some of the
things we're going to look at.
The NSURLSession API provides
really a rich set of classes
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The NSURLSession API provides
really a rich set of classes
and methods that
simplify the complexities
of modern day networking.
Today I'm going to discuss
with you how the
NSURLSession API has evolved.
And I'm going to share
with you some new features
and enhancements that
we've made to this API.
And we're going to have a
demonstration that'll show you
some of these features and
actions in a real application.
I'll spend some time
discussing security.
It's important for your
users that their data
and privacy be safeguarded.
If it's important to your users,
we know it's important to you
and to your applications.
So I'm going to share
with you some
of the enhancements we've made
to technologies in NSURLSession
with regards to use security.
Now, during the entirety of this
session I'm going to be sharing
with you some best
practices and tips
so that you can make your
apps even more incredible.
Now, let's start by looking at
the highest level APIs available
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now, let's start by looking at
the highest level APIs available
to applications across
all of Apple's platforms.
For many years, Foundation
provided the
NSURLConnection API.
Now, NSURLConnection was a
great network abstraction.
It enabled a lot of great
fundamental networking
functionality for you
developers in your apps.
But you know, we
asked ourselves:
What could we do better?
And what is it that you
developers are asking us to do?
And we sat down and
we talked about this.
And we found that a lot
of the answers had to do
with configuring networking --
that configuring network
in an app can be difficult,
especially if you need
to do different types
of networking all from
the same application.
So, we took action.
We officially deprecated the
NSURLConnection API in 2015.
And this really means we're not
adding new features to that API.
And it's really receiving
very minimal maintenance.
But prior to the official
deprecation at WWDC 2013,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
But prior to the official
deprecation at WWDC 2013,
we introduced NSURLSession
as the replacement API
for Foundation layer networking.
Now, we encouraged you then, we
continue to encourage you now
to move your networking
code to the NSURLSession API
in your applications today
and apps that you're going
to be developing in the future.
Now, since NSURLSession
is the best high-level API
for network programming
on Apple's platforms,
let's review some of the
basics of NSURLSession.
Now, if you want a real
in-depth detail, you know,
inside into NSURLSession, I
recommend that you go back
to WWDC of 2015, and
especially 2014, and take a look
at the videos and slides
with the sessions
regarding NSURLSession.
So, I've been praising
NSURLSession API
and recommending that
your apps use this API.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and recommending that
your apps use this API.
So what really makes
NSURLSession worthy
of all this praise?
Well, some of the benefits,
we continue our great support
for the HTTP/1.1 protocol.
We also have support
for the SPDY protocol.
Now, we don't recommend that
you build new Web services based
on SPDY, but really
that you look ahead
to HTTP/2 and that protocol.
We obviously have support
for HTTP/2 in NSURLSession.
Our support is based
on RFC 7540.
And we're adding new features
of this protocol all the time.
The app transport
security, or ATS.
This is a great feature
built into NSURLSession.
It's a security feature
that improves the privacy
and data integrity
of connections
between apps and Web processes.
One of the most important
aspects of ATS is
that your apps must
use the HTTPS protocol.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that your apps must
use the HTTPS protocol.
Now, at the same time it
allows you, the developer,
to implement best practices
when making connections
to remote servers
over the HTTPS.
The HTTP Strict Transport
Security, or HSTS,
another great feature
built into NSURLSession.
This feature protects your
users' data and privacy.
Now, it can be configured
via an HTTP header delivered
from your Web service.
Or it can be configured using
a preloaded list embedded
in the system along
with your application.
Once configured, all the data
that is transmitted, sent,
received over a secure
connection.
The great thing about HSTS is
it does not require any code
changes in your applications.
All the great built-in
support subsystems built
in for the handling of
caches, cookies, proxies,
authentication challenges,
all these things are
built into NSURLSession.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
all these things are
built into NSURLSession.
And last but not
least, configuration.
As I said, we talked a lot
about how can we make networking
or configuring networking
easier in your applications?
We feel that we need to have
better control over networking.
So, we looked at
configuration hard.
So what we did to achieve
fine-grade and control
over your networking
in NSURLSession,
we created this new class called
NSURLSessionConfiguration.
Now, this class contains
many properties
that you can configure.
You can create configurations
based
on different networking needs
within your application.
Now, here's a sample of
just some of the properties
that you can set with
NSURLSessionConfiguration.
The Transport Layer
Security or TLS version.
You can control the minimum
and maximum versions of TLS
that your app wants to support.
We default the minimum TLS to
1.0 and the maximum TLS to 1.2.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We default the minimum TLS to
1.0 and the maximum TLS to 1.2.
You can control the use of
cellular by your application.
Do you want to let your app
use the cellular network or no?
Maybe you want Wi-Fi
only networking.
This is the place to do that.
You can specify your
network service type.
Some examples of this
might be just default,
which is the standard
internet data traffic.
Your app might have VoiP control
or video data or voice data.
All sorts of different
types of data.
And really, this is just a
hint to lower networking layers
of what type of data to expect
so that it can create a quality
of service that's
best for your app
on the device that
it's running on.
Cookie policy.
Now, maybe you want your
cookies to be a session duration
or a persistent cookies.
This is the place to
set the policy for that.
Similar for cache.
Maybe you want an
ephemeral cache,
persistent cache that's
used between app launches.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
persistent cache that's
used between app launches.
This is a place to
set that policy.
You can also specify
storage objects.
Well, maybe you want to share
caches between different types
of networking or cookies between
different types of networking,
all within your same app.
This is a place that you
can set the storage object
for that configuration.
And time-out specifiers.
You can set resource
and request time-outs
so that your app can handle
error conditions in the network.
Now, I expect many of
you have some exposure
to NSURLSession API.
If not, really, go
ahead and look back
at the WWDC 2014
on NSURLSession.
You're going to get a lot
more in-depth instruction
on how that API works.
But I think for us in the
remainder of the talk here,
it's good for us to take a
look at how NSURLSession works
from a code perspective.
So very simply, the first
thing we do is we're going
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So very simply, the first
thing we do is we're going
to create a configuration
object.
First thing we do.
Here we call
NSURLSessionConfigurations
.defaultSessionConfiguration.
We take all the defaults
and we've got a very
simple config ready to go.
Now, we take that config
and we give it to a session.
We create a session by
calling NSURLSessions emitter
that takes a config object.
And boom! We've got a very
simple session ready to go.
Now that we've got this session,
we're ready to do some work.
Now, the first thing we're
going to do is create an NSURL
and specify what's the
endpoint that we want
to retrieve or request
data from?
Once we have that,
we can create a task.
Here we call the
dataTask function.
And we pass the NSURL object
that we created to
that dataTask.
We also provide a closure.
Now, this closure is
called asynchronously
when our task is
finished loading
and the requested
resource is returned to us.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and the requested
resource is returned to us.
Now always, don't forget, make
sure you call task.resume.
All of our tasks are
created in a suspended state.
So you must call task.resume
to get that task executed.
All right.
So in review, very
simple review,
NSURLSession is really
a three-step process.
First you're going to create
your configuration object.
Once you have that config you're
going to create your session.
And now you're ready with that
session to make it do some work
and you're going to create
tasks on that session.
Now, I want to suggest to
you a best practice here.
Want to make sure that
you avoid the one-task
to one-session model.
You should really not set
up your networking this way.
Really, what you want
to do and how you want
to design this is have
one session service many,
many tasks.
So of course, you can
have multiple sessions.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So of course, you can
have multiple sessions.
But avoid the one-session
to one-task model.
And the reason for that,
it really boils down
to performance.
You're going to get
better memory management
and OS resource utilization
by having few sessions
servicing many, many tasks.
Now, as I mentioned, the
NSURLSession API is evolving.
I'd like to talk about
the HTTP/2 protocol
and what we've been doing
in this protocol
within NSURLSession.
Now, the support of
the HTTP/2 protocol
within the NSURLSession was
introduced last year at WWDC.
And it's increasing
in popularity.
You know, large Internet service
providers are supporting HTTP/2.
Now, what makes HTTP/2
such a compelling protocol?
Well, let's look at
some of its features.
One of the great features
of HTTP/2 is multiplexing
and concurrency support.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and concurrency support.
Now, this feature allows
multiple requests and responses
to be in flight concurrently.
Responses can be received
out of order and all
on the same single
TCP connection.
Another great feature of the
protocol is header compression.
This reduces the size
of the HTTP/2 headers.
It cuts down on network
round trips.
This is better for
bandwidth, and really better
for performance for
your application.
Another great feature
is stream priorities.
As a client of HTTP/2 you
can indicate the priority
at which resources are
returned from the server.
And this really allows
you to look out
and tune the networking
for your application.
So in essence, HTTP/2 is
all about performance.
Now, this will result in an
improved end user experience
as they interact with your apps.
Now, there's one more
feature that we have
to take a look at of HTTP/2.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to take a look at of HTTP/2.
Today we're introducing
support in NSURLSession
for HTTP/2's Server
Push feature.
[ Applause ]
So what is Server Push?
Well, when a client
makes a request,
a server will respond
to that request.
But concurrently, it can
push additional responses
to the client.
So if you think about a Web
page, it's made up of lots
and lots of resources.
Instead of the client having to
fetch each individual resource
over the network, a server can,
in parallel to the original
response, push information
about additional resources
the client is likely to need.
So, Server Push prevents
multiple network round trips
that HTTP/1.1 and non-Server
Push HTTP/2 requires today.
Now, I want to bring to
your attention something
that the server obviously
has to support this protocol,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that the server obviously
has to support this protocol,
has to support HTTP/2 and
it has to be configured
to enable the Server
Push feature.
Now, Server Push is
available now to applications
that use NSURLSession.
There's no need to opt in.
No funny properties
that you have to set.
It's just there.
And it just works.
So this is all more
reason we feel
that NSURLSession
API is the best API
for your applications today.
Now, let's take a minute here
and look a little bit deeper
about how Server Push
will benefit your app.
Here I've got a graph that
represents an app's use
of NSURLSession using
the HTTP/1.1 protocol
to do some network loading.
Now, as we move down this graph,
we're going to accumulate
more time.
And this will be
our total latency
for our network loading
for our application.
So, first our app is
going to resume a task.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, first our app is
going to resume a task.
And that task is going
to request index.html.
We'll assume that
everything's working great
because networks just do that.
And we're going to get our
response from the server
with the requested data.
Now, in addition to the
data for index.html,
we note that time has passed.
And that our total latency has
accumulated, has increased.
Now, our app is going
to resume another task
and request style.css
from the server.
And again, assuming
everything's working properly,
we're going to get
that response.
And now we have style.css
and our total latency has now
increased by the time required
to fetch that resource
over the network.
Here the application will
make the final task resume
and request background.jpg.
We get the response
from the server.
And here we've got
background.jpg.
Our application is now finished
with its network loading.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Our application is now finished
with its network loading.
And we look at the graph,
we see this is our total latency
cost for an HTTP/1.1 load.
Now, let's take a look at our
application when it's able
to use HTTP/2 and Server Push.
And I'm just going to shift
the HTTP/1.1 result graph
over to the side
just for reference.
So again, our app will resume
a task request index.html.
Again, our total latency,
we receive our response.
And our total latency is pretty
much exactly the same as it was
for the non-Server Push case.
That's expected.
What will happen, however,
is that concurrently
to our response for
the original request,
the server will push other
resources to NSURLSession.
Now, this comes along with the
original request or a response
from the original request.
When our application
resumes the second task
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
When our application
resumes the second task
and requests style.css we get
an almost immediate response.
And this is because Server
Push gave us the data before we
really knew we needed it.
Now we have style.css and we
notice that the accumulated time
for style.css is substantially
shorter when compared
to the HTTP/1.1 needed to
load the exact same resource.
Now the app makes
some final task resume
and requests background.jpg.
Again, we get a real
quick response.
The app has background.jpg.
And we add the total time
to our accumulated total.
At this point the app is done
with its network loading.
And we see that the HTTP/2
with Server Push latency is much
smaller than that of the HTTP/1
or the non-Server Push load.
The reason for this
improved performance is
that with Server Push we were
able to save the latency cost
of network round trips needed
when requesting resources.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of network round trips needed
when requesting resources.
Now, I'd like to
invite Andreas Garkuscha
to show us what Server
Push looks
like in a real application.
Andreas.
[ Applause ]
>> Thank you, Jeff.
Good morning everyone.
Today I'm going to
demonstrate the advantages
of using HTTP/2 Server Push when
loading resources for your apps.
You are looking at the very
common part of an app that many
of you may already
have implemented
or at least have seen while
using some of the existing apps.
What you see now could
be a social network app
for photographers showing
the most popular pictures
where you can list the
most popular picture
for a certain photographer.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
View the individual pictures.
Go to the next.
Go back. Go back
to the top list.
Choose another one to view.
And so on.
This app could be
a food recipe app
or a music streaming app
showing the album artwork.
So an app which is loading
resources from your server.
In this case, it is loading
and showing some images.
Now notice here for demo
purposes there is a switch.
It allows us to choose
between the initial URL
with Server Push configured
and one with no Server Push.
In both cases, first we request
the initial document containing
the image URLs to load.
Then we request the images.
If the Server Push is off,
nothing is getting pushed.
So we need to send the requests
for every image over
the network.
In case of the Server Push,
and now I'm going to switch
to this mode, as Jeff explained
previously, the requesting
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to this mode, as Jeff explained
previously, the requesting
of the initial document
will trigger the push
of the resources from the
server to your application.
There will be no need
to send the request
for every image over
the network.
The data for your data
tasks will be delivered
out of the Server Push storage
directly to your application.
Now, let's compare the
performance of the Server Push
and non-Server Push loads.
I'm going to switch between the
initial URL with Server Push
and non-Server Push a couple
of times so that you can see
when the Server Push is on,
this entire collection
view is loaded faster.
But how much faster?
Well, let me show you that.
Now the demo application is
going to provide the results.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
It's the bottom of
the current view.
For the fastest non-Server
Push load in red.
And for the fastest
Server Push load in green.
Let me do it a couple of times.
Now the same with
the artist view.
A couple of times.
Server Push off.
Server Push on.
You can see here that
the Server Push load is
at least two times faster.
Pushing the images is about
two to three times faster
than loading them on the high
latency network we are actually
using here.
The kind of network your
applications can experience
when on cellular or slow Wi-Fi.
I prepared a video showing
the Server Push load
and non-Server Push
loads side by side.
Well, let me show you that.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, you can see when the Server
Push user is already viewing the
pictures, the other guy is just
trying to load the artist view.
Let's see it one more time.
Once again, the Server Push
user on the right is getting
through much faster than
the non-Server Push user
on the left.
Two to three times faster.
Just think about it.
Think about the user experience
you can provide your customers
if you configure the Server
Push on your HTTP/2 server.
And you don't even have to
change any code in your app.
And this is great.
Just awesome.
This was the Server Push demo.
Thank you very much.
Have a great conference.
And now, back to Jeff.
[ Applause ]
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Applause ]
>> All right, thanks, Andreas.
So let's summarize
what we've seen
and discussed regarding
HTTP/2 and Server Push.
Server Push is supported
only in NSURLSession API.
So if you're writing new apps
or you're on NSURLConnection,
we highly recommend that you
move to NSURLSession APIs today.
There's no coding
that you have to do
to take advantage
of Server Push.
It's not an opt-in.
It just works.
And with Server Push
your apps will perform
in the most optimal manner,
giving your users an
even better experience
with your applications.
Now, another evolution to the
NSURLSession API is the addition
of Network Statistics.
Now, who out here
loves statistics?
We have any statistic people?
We got some folks
that love statistics?
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We got some folks
that love statistics?
All right, I've got
a stat for you.
Are you ready?
Here it is.
All right.
Right. Sorry about that.
Sorry. We're going to get to
some actual useful statistics.
And this is, we believe,
network statistics are part
of that 2% useful values.
So, why is it useful?
Have you ever had slow
network performance
in your applications?
Imagine some of you have.
And how did you go about
figuring out what was wrong?
You know, how did
you debug that?
We believe network statistics is
going to be great for you guys
to be able to use
in the development
and debugging environment.
You could use this to
collect information,
possibly out in the field.
Maybe you could leverage
Test Flight
and collect some information
about your app running
in the field.
Network statistics is
about analyzing performance
of network loading
within your app.
It's about finding and fixing
networking-related bugs.
And it's about giving
you better understanding
of what your networking is doing
inside of your application.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of what your networking is doing
inside of your application.
Currently, network
statistics is supported in iOS,
macOS and on tvOS platforms.
Now, before we get started with
the actual statistics values,
let me explain to you how you're
going to get all these values.
And to do this, we need to
look at a little bit of code.
Here we have a brand
new delegate called
didFinishCollecting metrics.
This is a delegate method
of the NSURLSession
Task Delegate class.
Now, when you implement
this delegate,
it's going to be passed a task
for which the metrics
were collected
and a new class object.
This is NSURLSessionTaskMetrics.
The NSURLSessionTaskMetrics
class has a property
named taskInterval.
This is the interval of
time from a task creation
to the point in time when all
the statistics are collected
and are ready to be delivered
to your
didFinishCollectingMetrics
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to your
didFinishCollectingMetrics
delegate.
Another property I'm showing
you here is the redirectCount.
Now, that's fairly
straightforward.
And as the name indicates,
this is the number of times
that an HTTP redirection
occurred during the
task's execution.
The last property
of NSURLSessionTaskMetrics
called transactionMetrics.
Now, this property
is really the core.
This is the meat of
our network statistics.
This is where you get an array
of NSURLTaskTransactionMetric
objects.
Now, let's take a closer look
at this particular new class
because this is really
where some
of the great metrics
are located.
Now, in order to understand
all of these metrics,
we're going to chop them
up into four categories.
Now, the first two properties of
NSURLTaskTransactionMetrics make
up the first category.
And I'm going to call
that Request and Response.
There's two properties here
called Request" and "Response.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
There's two properties here
called Request" and "Response.
And they really allow you
to analyze what was
it that I asked for?
And what was the response
to that original question?
The second category of
statistics has to do
with protocol and connection.
The property networkProtocolName
is just --
it tells you what type
of protocol was used
during the time
at which statistics
were collected.
And here's a possible list
of names you might see here:
HTTP/1.1, HTTP/2, or SPDY.
Now, this list can and
will change over time.
Another property you'll
have is isProxyConnection.
This tells you whether
the transaction was part,
or had a proxy connection
involved during the time
collections were gathered,
or statistics were
gathered or collected.
And the isReusedConnection.
This property is set to Yes
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
This property is set to Yes
if a persistent connection
was used during the fetch
of the resource.
Now, the third category of
metrics has only one property.
And it deals with
the information
about the resource
loading or load info.
The single property
is resourceFetchType.
Now, it tells you how a
resource was obtained.
Now, some of the values you
would see here are network load.
This indicates that the resource
was loaded over a network or,
as commonly referred
to, an origin load.
You might see local cache,
which indicates the resource
was fetched from a local cache.
It was stored local
to your application.
No network transaction
was really required.
And Server Push.
This tells that the resource
was found as a result
of a Server Push cache hit
when you made that request.
The fourth category of
transaction has to do
with connection establishment
and transmission.
Now, the first group of
metrics measure time related
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now, the first group of
metrics measure time related
to the setup of a
network connection.
The second group of metrics
measure HTTP-related activities
of a network load.
These properties are timestamps
and are taken at a time
when the event actually
occurred.
So let's take a closer
look at these metrics
and when they are collected
during the execution
of a network load.
To do this, we're going to look
at a very simple network load.
Now note that this is just
one model of one type of load.
There's all sorts of activities
that happen during
network loading.
You've got cache lookups.
You've got cookie lookups.
You're dealing with
redirections,
sometimes authentication
challenges.
But we're going to keep
it real simple just
for our purposes here.
The NSURLTaskTransactionMetrics
class contains properties
that contain all these time
stamps at various points.
So, we begin with fetchStart.
fetchStart is a time when the
application begins requesting
a resource.
A fetch could be satisfied
from a local cache,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
A fetch could be satisfied
from a local cache,
or possibly resource
that was origin loaded.
So now we're looking
at domainLookup.
So the domainLookupStart
property.
This is the time just
before a name lookup
for a resource begins.
Now, this is the DNS query.
And this converts a host
name to an IP address.
So, domainLookupEnd is
when that lookup completes.
And an IP address is
sent back to the caller.
Here we're going to take a
look at what metrics we collect
for connection establishment.
The connectStart property is the
time just before an app begins
to start or establish
a TCP connection
with the remote server.
Now, this value could be nil
if the response is
found in a local cache.
I'll discuss the connectEnd
property in just a moment.
If you're doing HTTPS you're
going to need a TLS handshake.
So we've got a statistic
for that.
The secureConnectionStart
metric,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The secureConnectionStart
metric,
the point in time just before
the application starts the
security handshake to secure
the current connection.
And secureConnectionEnd, well,
that's when the secure
handshake is completed.
It's finished.
Now, as I mentioned, connectEnd.
Now, that's the time immediately
after an app has connected
to the remote server,
including all the
security-related handshakes.
This is the point in
which a connection is
considered established.
Now that we have an
established connection,
we can actually do some HTTP.
So, we have a few stats
that we can collect
for you regarding the
request and response.
So first we have requestStart.
And this is the time when
the app begins requesting the
resource regardless of whether
the resource was fetched
from a local cache
or a remote server.
If an origin load was
needed, this is the time
at which the first byte of the
HTTP header began transmission.
requestEnd is the time
when the last byte
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
requestEnd is the time
when the last byte
of the request was
written to the network.
responseStart.
This represents a time
when the first byte
of the response is
received from the server.
Now, if this is a cache load,
this is when the cache response
was received from the cache.
And responseEnd was
the time immediately
after the application
receives the last byte
of the resource requested.
Now that we've been looking
at stats collected
during an origin load.
That is, we had to send bytes
over a physical network.
It's possible that the
networking could have been
satisfied from a local cache.
And I've mentioned that.
So if a local cache contains
the response for our request,
then there's no need for DNS.
So there's no need to make
a TCP connection, et cetera.
Those statistics will be set
to nil in this cache case.
So just be aware of that
as you're looking
at these statistics.
Now, you might be asking,
"Okay, this is really cool.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now, you might be asking,
"Okay, this is really cool.
How do I get these
stats into my code?"
So, to do that, let's
look at some code.
Now, as I showed you earlier,
we start with the delegate.
And here I have an
implementation
of the NSURLSessionTaskDelegate.
This implements the new
didFinishCollectingMetrics
delegate callback.
And the one I'm showing you
here doesn't do really anything
of any interest at the moment.
I totally expect
you guys are going
to do some really
cool stuff here.
Maybe you're going
to do some logging.
A good point to do some
debugging and take a look
at what's happening
with your networking.
Again, maybe leverage Test
Flight and do some logging
so you can collect some
information from the field
about how the networking is
performing in your applications.
That's all up to you.
So, let's keep looking
at this example here.
Maybe a little bit
of housekeeping code.
First thing we have to do
with our delegate implementation
is instantiate an instance
of it.
Now, we're going to create a
default configuration object.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now, we're going to create a
default configuration object.
We take all the defaults just
by calling
defaultSessionConfiguration.
Next, we're going to
create an instance --
or we're going to create an
NSOperatonQueue instance.
And we have to do that because
we have to have some place,
some queue, so that our delegate
can actually do some work.
And as I mentioned earlier,
I recreate an NSURLSession
with that configuration object.
But here I'm calling
NSURLSession's init function
that takes additional
parameters.
And namely, those are the
instantiated instant delegate
object and the NSOperationQueue
object that we created.
So now we can actually
do some work.
We create a task
with our session.
And what do we want
our task to do?
Well, let's just simply load
this server's root Web page.
And here I'm using,
again, the dataTask method.
And this requires a
closure as a parameter.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And this requires a
closure as a parameter.
Now, note with this closure
that our
didFinishCollectingMetrics
delegate callback will be
called first and called before
that closure is invoked.
So, oh, and also, don't forget
your good old task.Resume.
Got to make sure
you resume that task
so that the work can
actually execute.
Now, this is an overly
simply review of how
to implement
networkStatisticDelegate
callback and the code
needed to make it work.
I'm sure that you guys are going
to do much more interesting
things and be much more creative
with your use of Network
Statistics that I've been here.
Now, I hope you like what you've
seen with Network Statistics.
What do you think of those?
[ Applause ]
All right.
Now you can access information
about what's really happening
under the hood with your
network transactions.
This will help you in your
debugging and development
to be able to get, you
know, fix your apps
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to be able to get, you
know, fix your apps
and make your apps work
the best that they can be.
And tune, really tune the Web
services and the types of apps
that you're making so
that they will work
in the most optimal way.
And again, this new feature is
available in NSURLSession APIs.
It's a great time to
be using NSURLSession.
Now, in the final
section I'm going
to discuss a topic that's
critical to everybody.
And now, as developers,
we all care about guarding
the privacy of user data.
The NSURLSession API
has some great built-in
security features.
And I want to share with you
just a few enhancements we've
made to these features.
Transport Layer Security,
or TLS, is a protocol
that protects data transmitted
by endpoints over a network.
So sometimes you've
heard the term SSL.
This was the predecessor to TLS.
So, TLS and SSL are sometimes
used interchangeably.
TLS makes use of ciphers
to achieve this protection.
Ciphers scramble
data on one side --
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Ciphers scramble
data on one side --
scramble data sent
over the network.
And the other receiving
side uses the same cipher
to unscramble that data so that
it can use and understand it.
If somebody were to grab
that data in the middle,
it's just big glob of blah.
They can't use it.
So it protects the data.
Now, one of the things
that has changed,
and I want to make you aware of,
is that Apple's platforms no
longer support the RC4 cipher.
So for more details, I recommend
that you take a look at,
review the security sessions
that occurred on Tuesday.
Possibly attend one
of their labs
and ask some questions there
for a little bit
more detail on that.
So, what this means to
your applications, however,
is that connections
that you used
to make successfully could
possibly fail suddenly.
And this could be due to servers
that are supporting
only the RC4 cipher.
Now, we have a way that you can
kind of test this theory out.
There is a command line
tool on macOS called nscurl.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
There is a command line
tool on macOS called nscurl.
And this could be used to test
for RC4-only ciphers on servers
that your apps communicate with.
Now, here I'm going
to use nscurl simply
to grab the root
document of this server.
So if I execute this
command -- whoa!
I see that, hey, the
HTTP Load failed.
Hmm. That's funny.
I used to be able to
connect that server.
Let's find out if our theory
about RC4 is true or not.
Here I've added a flag to
nscurl called enable-rc4.
And that means that I am
going to force the use of RC4
on the client's side
of the connection.
So I run this.
Wow! This worked
all of a sudden.
So this proves to me that this
server is only supporting RC4.
I'm going to have to go have
a talk with that server admin
and figure out what could we
do to get some secure ciphers
onto that server so we
can protect our user data
within our application.
So I hope you get
the point here.
The RC4 cipher is no longer
supported on our platforms.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The RC4 cipher is no longer
supported on our platforms.
And this could affect
your applications.
So just be aware of that.
App Transport Security, or ATS.
This is a great security
feature.
It allows you to set the policy,
security policies for your app.
You specify keys that
grant entitlements.
And these become your
policies for your applications.
Now, we've added two new keys
that I want to share with you.
The first one is
NSAllowsArbitraryLoadsIn
WebContent.
So, if you have a WK Web
view and have scoped only
to that class, if you have
that class in your application
and you have this key present,
that object will be allowed
to make any sort of network
loads that you have specified.
It'll ignore whatever other
policy you have in your app.
But again, that's contained
only to that one object.
Any loads outside of
that object will conform
to your security policy.
The other value we have
is NSRequiresCertificate
Transparency.
Now, this requires that certs
that your app receives must
support these certificate
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that your app receives must
support these certificate
transparency feature.
Certificate Transparency is
a feature of signedCerts.
This allows you to use
a provided certificate
with greater assurance that
the certificate is legitimate.
And that you can
trust the endpoint
that gave you that certificate.
For more details on that
particular subject, again,
recommend that you take a look
at these security sessions
or attend one of their
labs to get more details
on Certificate Transparency.
Everything that I've discussed
relates to the NSURLSession API.
We've seen this API evolve
with new features
that have been added.
And we're really excited to see
what you guys are going to do
with your applications as
you take advantage of some
of these great new features.
I introduced support for the
HTTP/2 Server Push feature.
This means that your
apps are going to be able
to perform even better.
I introduced Network Statistics.
Now you can introspect your
application network behavior
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Now you can introspect your
application network behavior
like never before.
This will result in an
improved end user experience
for your applications.
I shared with you some
security-related features in ATS
and the deprecation
of the RC4 cipher.
Your apps can now implement
best security practices
and keep your user data
safe and protected.
Now, we hope that you
will use NSURLSession
in your applications for
not just these reasons,
but for all the great features
that are inside of
NSURLSession API.
If you want more information,
this is the URL for
this session.
So you can go back
and review some
of the things we
discussed today.
Some related sessions we think
that you will be interested
in on this subject I've
got listed up here for you.
Well, that's it.
Thank you.
Hope you have a great
rest of the WWDC.
Thank you.
[ Applause ]