Transcript
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Silence ]
>> Good afternoon.
My name is David Chan.
Today, we're going to talk
a bit about multitasking.
As you saw yesterday, we
have some great new APIs
for you today, and we're
going to just dive right in.
So first, we want to just do a
quick review of the multitasking
that we have in iOS 6.
We have a few changes here that
we want to just to note right
at the top and then
we're going to dive right
into the new APIs
that we have for you.
We're really excited to see
what you guys think about it
and what you'll do inside
of your applications.
And then next, we're
going to talk a little bit
about what it means to
run in the background.
For those of you who
haven't adapted any
of the more significant
multitasking APIs in the past,
these are a few tips and things
that you should be considering
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
as you're implementing it.
Details are incredibly important
to make a great application
and this is where
you're going to learn
about what you need
to do for those.
So, in iOS 6, we have a
number of great APIs for you
to for example playing
audio into the background
if you're listening to music,
for your application to be woken
up and notified when the user
changes location, if they enter
in a region that
they're interested in.
And of course, in iOS 5,
we introduced Newsstand
which allows newspaper
and magazine applications
to keep their content
up to date.
So, here are a few changes
that we've made to some
of the existing multitasking
APIs.
The UIApplication background
task API is really great.
It's certainly very useful
to continue operation
after users have left
your application.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And a number of applications
use this for encoding video
or transferring files,
uploading or downloading
and completing database
operations
or just generally finishing up
whatever the user was doing.
And so from a power standpoint,
it kind of looked like this.
When the application
enters the background,
obviously the phone stays awake
to keep that task running,
even when the user
locks her phone.
So, when you lock your phone
and you put it in your pocket,
you kind of expect
it to go to sleep.
But in iOS 6, that background
task would keep the phone awake
and then it would only go to
sleep after that task has ended.
In iOS 7, we've changed
this slightly
to improve battery life.
So, we have where the
application enters the
background, where it locks and
you'll see that the phone goes
to sleep shortly afterwards.
And that anytime that the
device is awake to, for example,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
check mail, your application
will get a chance to run
at that point too, so you get
these opportunistic slices
of time to run.
And you'll see that you still
get about the same amount
of time to run your task.
It's just split up
over that period.
So, if you're an application
that uses the background tasks
to transfer files, in iOS 7,
we're going to encourage you
to use the NSURLSession API
and we're going to discuss what
that looks like and how to
use that in a little bit.
And of course, if you're
going to support iOS 6 as well
as iOS 7, all we ask is
that you check to see
if that class exists and use
the new enqueuing behavior
but of course, continuing
to use your old stuff
for iOS 6 as well.
So, just to summarize,
applications will no
longer keep the device awake
when you're running these tasks.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
You'll still get several minutes
of runtime just as before,
it's just not guaranteed
to be contiguous.
So, next stop is
the App Switcher.
So, I hope you guys
noticed yesterday,
we have a great new
App Switcher.
It prominently features
snapshots, so users can go
through and find what they're
looking for just by recognition.
So, the really important
thing to note about this is
that your snapshots
that got taken
after your application goes
into the background is even
more important, and it's really,
really important now that
you go back to the same place
that the user was
at when they left.
And if you haven't seen it
before, I encourage you to go
to the State Restoration talk
that will be on Thursday.
And you'll be able to see how
to use State Restoration
to do that.
It's a really simple API.
It's very powerful.
You'll be able to use that
to make sure that when
that user taps that snapshot and
it flies in, it goes right back
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
into the same place
that they left it.
Also, users will be able to
swipe up to remove applications,
and so just as before in iOS 6,
that will stop the application
from running but now in
iOS 7, it will also stop
that application from
running in the background.
And we've made this consistent
across a number of APIs,
but you guys should be
aware that that is what's--
that will be what's happening
when the application is removed.
So, we applied these to
location services as well,
so with respect to the
App Switcher state,
so your application
for region monitoring
or significant location changes
won't launch in the background
if the users remove
that application.
In addition, users will be
able to configure whether
or not they want that
application to run
in the background with the new
Background App Refresh Settings
under General.
Newsstand.
So quick note about
Newsstand, we've only updated it
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to support these two things,
Settings as well as
the App Switcher.
You'll see a lot of really great
APIs here that might be tempting
to use if you're a
Newsstand developer.
Suffice it to say, we
encourage you to stick
with the Newsstand API for your
Newsstand behavior and that
for new features,
you'll certainly want
to consider using our new stuff.
OK, so with that, let's dive in.
First, multitasking API
is background app fetch.
And what this is, is
it's a periodic way
for your application to get
launched into the background
to update its content.
It's based on when the user
actually users your application
so that your fetch opportunities
can be as fresh as possible.
And we'll go into a little bit
about what that means and how
that works so that you guys
can get an understanding of how
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to build your features.
Next stop is notifications.
This is really a great API.
We've had lots of
request for this
and I think you guys
are going to love this.
This basically just gives
your application a chance
to launch whenever you send
it a push notification crafted
in a certain way,
it can actually wake
up your application
in the background
with a silent push notification.
So that if there's
something immediate that needs
to happen inside of the
application but doesn't need
to bother the user,
you can do that too.
It's really great.
And lastly is a Background
Transfer Service,
so this will allow you
to enqueue large uploads
and downloads for iOS to
continue in the background
after the user leaves your
application and can continue
across reboots and just
handles all of that for you.
It's really great.
So with that, let's
start talking
about background app refresh.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, let's say you've got
the next great social
networking application.
Now, this might sound
typical to all of you,
or familiar to all of you.
When your app becomes
front most,
you typically refresh
your feed right then,
which means that
for a few seconds,
your users are stuck looking
at what they saw last
time and not what's new.
And obviously, they've
gone to your application
to see what's going
on with your--
you know, with their
friends and family.
So, now in iOS 7, you can update
your content before the user
returns to your application.
So, just like you resume
mail and has new mail there,
then you can get that
same experience in iOS 7.
So, that new interesting
content is just waiting there
for the users to go and see.
So, let's dig into the API.
It's really simple, but it's a
common pattern that we're going
to use throughout the top.
So, I want you to pay
attention to how this works.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The first thing you do is
either in the Info.plist
or in the new Xcode feature
capability's PNG, you're going
to enable Background
Fetch by adding this key
to UI background modes.
The second thing you do is you
set this Minimum Background
Fetch interval and that
will allow your application
to enable these fetches
to start with.
And we'll go over what
these values are and what
that actually means in
practice in just a moment.
Finally, once your
application does get launched
in the background, it'll go
through this typical pattern
where it did finish launching,
gets called, and then obviously
if your application
was already running
and it was simply
suspended in the background,
your application will be
resumed and perform fetch
with completion handle
will be called.
So, this is our new
delegate callback
in UIApplicationDelegate.
All you do is you implement
that, you get passed
in a completion handler
and from that point on,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
you're allowed a certain
amount of time in order
to kick off any network
request you need to do
to retrieve new content
and update your UI.
And then after you've done
all of that and you've gotten
that brand new stuff,
you're going
to call the completion
handler that was called--
that was passed in and
that's really important.
That's where your snapshot
gets taken and will go right
into that app switcher UI, so
that if the user is passing
by your application-- the app
switcher, they can see, "Hey,
look, there's brand
new content there.
That's a cool new picture,
I want to see that."
In addition, it also saves
the state restoration archive
so that, of course, when you
tap that, the user goes right
into your application even
if it may have exited
in the background.
So, let's talk about the
minimum fetch interval.
So with that same social
networking app, right,
it's like any other application,
you have a user account
that you have to log in with.
And so when the user first
installs it, it starts signed
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
out which means that
there's no content available.
And so the default value of the
minimum fetch interval is never.
Once the user signs in, however,
the content will
then be available.
So you can set that
fetch interval to minimum
and that means that the system
will use a reasonable default
in order to find out when your
application should be launched
to update.
And of course, the cycle
completes, if the user happens
to log out, you want to
set that back to never.
So never and minimum are two
of the values that you can use,
but of course you can set
a custom value expressed
in seconds.
So let's take a look
at what that actually--
how that actually works.
So let's say that I-- app
icon there represents some app
activity like the user
using your application
or a previous fetch.
For a limited amount
of time afterwards,
fetching will be disabled.
So if you set this to let's
say an hour, for the next hour,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
the system will not
wake up your application
in order to go and fetch.
But that for any
time after that,
fetching will be
allowed at any time.
So if you zoom out a little
bit, what that looks like is
that there's no repeating
interval.
It just means that
there's a period of time
after your app launches where
the system won't wake it up.
Now, you might ask, "Why
would you want to do that?
Of course, I want to be
updated all the time."
So I'll give you an example.
Let's say you have an
application that reads data
from a number of
personal weather stations
and that's really
expensive to do,
so you only do it once an hour.
You know ahead of time that
your content only updates once
an hour.
So if you were being woken up
let's say every 15 minutes,
that would be a waste of
the user's battery life
and it would be a waste
of your server resources.
So you can set this
value to that.
But if you don't have
constraints like that,
we highly encourage you to
use the default minimum.
We think that will give you
a really great experience
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and give your users
the right thing.
So, with that I'd like to invite
up on stage Brittany Hughes
from the SpringBoard team
and she'll show us how
to update your application
with these APIs
and how easy it is
to do an Xcode.
[Applause]
>> Hi. My name is Brittany
and I'm going to show you how
to update your app to fetch
new content in the background.
OK, I think I have the next
great social networking app.
I've been working on an app that
is a social network for clowns
and clown enthusiasts.
I call it Clowntown.
So, let's start by giving
you a little tour of my app.
[ Pause ]
OK, here we go.
You can see it's
a very simple app.
It just has a lot of posts
from my clown friends.
I can pull the refresh
to get new posts
and when I just pulled
the refresh,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
we just got two new posts.
They're marked in blue and
if you look really closely
down here on the corner of
a post, there's a timestamp.
That means these posts
were downloaded at 2:20.
So unfortunately for my
users, the only way for them
to see new posts from
their clown friends is
to pull the refresh.
Wouldn't it be great if my
app was already up to date
when the user launched it?
Well now in iOS 7,
we can do that.
Let me show you how.
The first thing we
need to do is we need
to add the new UI
background mode.
Xcode 5 has made it much easier
to manage your UI
background modes.
All you have to do is
click on your project
over here on the left.
And then on the Capabilities
tab,
down here there's a
background mode section.
If I zoom in here, you
can see here is the list
of background modes, so I'm just
going to check Background Fetch
and now it's added to my apps
Info.plist The next thing I need
to do is I need to set my
apps minimum fetch interval.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
This is super important because
the default interval is never,
that means my app will
never be given a chance
to run in the background.
I'm going to set my apps
minimum fetch interval
to the minimum interval which
means that iOS will decide
when it's best for my app
to run in the background.
The next thing I
need to do is I need
to implement the new UI
application delegate callback.
Application performs fetch
with completion handler.
In this method, I need
to go fetch my new posts.
I need to update my apps
UI to show the new posts,
and then I need to call the
completion handler to signal
to iOS that I'm finished
with my refresh.
Let's go check out
my View Controller
to see what options I have.
OK, it looks like I have
conveniently refreshed
with completion handler.
Let's use that.
It looks like this
method takes in a block
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
than when the refresh
is finished,
will give me back a bool whether
or not we downloaded new
post in that refresh.
Let's add that over here
in my UI application
delegate callback.
Now inside this block,
what I need to do is I need
to call the UI application
delegates completion handler.
The UIApplicationDelegate's
completion handler can take a
couple of different arguments.
So, if we did receive
new posts, then I'm going
to call the completion handler
with UI Background
Fetch result new data.
If there weren't any new
posts, then I'm going
to call the completion handler
with UI Background
Fetch result no data.
OK, let's go check out
and see what refresh
with completion handler
actually does.
OK, it looks like it takes
that completion handler
and assigns it to a property.
This was probably
a good idea before
when there was only one
code path that was coming
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
through here, but now
that we just added
that second code path, it's
not a great idea anymore.
The reason why this isn't a good
idea is because it's possible
for us to come through
this method one time
with a completion handler,
stash it away in our property
and then before that refresh
is finished, we'll come in here
with a different
completion handler,
assign it to the property which
will overwrite the first one.
That means the first completion
handler will never get called.
One of the most important things
about the UI application
delegate callback is
that we call the
completion handler.
Like I said a minute ago,
that's the signal to the system
that we're done with everything,
we're ready to be snapshotted.
If I don't call the completion
handler, bad things will happen.
So, instead of signing it to
a property, let's just get rid
of that and let's pass the
completion handler all the way
through the refresh.
So I'm going to delete that
line, I'm going to get rid
of my property and then
I'll just change this method
to fetch new posts with
completion handler.
And then that means I need
to update the signature
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to fetch new posts with
completion handler.
And then inside this method,
it's look like we were
referencing the completion
handler property that
we just get rid of.
So instead, let's just reference
the completion handler argument.
OK, looks like everything's
going good so far.
Let me run my app and make
sure I didn't break anything.
OK, here we are,
looks good so far.
If I pull the refresh,
all right,
we've got three new posts,
they're marked in blue
and their timestamp is 2:24
p.m. Now, I need to test
that my app can actually fetch
new content in the background.
There are two very important
scenarios you need to test here.
The first scenario is
having your app launched
in the background to
fetch new content.
The second scenario is
having your app resumed
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
in the background to
fetch new content.
Let's test the resume
case first.
I recommend testing the resume
case by creating a new scheme.
So what I'm going to do is
I'm going to come up here
to my scheme list and I'm
going to hit Manage Schemes.
And I just have one the default,
so I'm just going
to duplicate that.
Let's call it Clowntown
Background Fetch with an R.
And if I zoom in here, in
the Run section of the scheme
under the Options tab,
there's a checkbox down here
that is Launch Due to a
Background Fetch Event.
So I'm just going to check that,
and zoom out and
then hit OK, OK.
Going to sneakily
clear this, OK.
And now I'm going to run my app.
What you'll notice here is
that the simulator launched
and my app is running but
it's not in the foreground.
That's because it was launched
into the background
to fetch new content.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
If I look down here in
the Syslog for my app,
it says that we fetched one new
post and then saved a snapshot.
Let's resume my app and
see what it looks like.
OK great, we have our one
new post, it's marked in blue
and the timestamp is 2:26 p.m.
That was just a couple
of seconds ago.
So the launch case worked.
Now we need to test
the resume case.
Xcode 5 has added
a new menu item
in the Debug menu called
Simulate Background Fetch
that will test the resume case.
So I'm just going to click that
and if I come back over here
at the simulator, it's
still running my apps not
in the foreground because it
was resumed in the background.
And if I check down
here on the Syslog,
it looks like we
fetched another new post
and saved another snapshot.
So let me resume my app and
see what it looks like now.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
OK great, we have one
new post from Mr. Happy,
it's the blue post and
its timestamp is 2:26:52
which is just a couple
of seconds ago.
So we just verified that my app
could be launched and resumed
in the background to
fetch new content.
And now it's possible for
my app to be up to date
when the user launches my app.
You've seen how easy it
is to update your app
to fetch new content
in the background.
It's not that hard.
Back to you Dave.
[ Applause ]
>> Thanks Brittany.
So what did we learn?
It's really, really easy
to update your application
with the new APIs.
We've made it intentionally
very simple.
We think that it should be
really easy for you guys
to get started even today.
But two main points that
Brittany made, make sure to pass
that completion handler
all the way through so
that every perform
fetch is bookended
with calling the
completion handler
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and calling the completion
handler with the proper status
of whether or not there's
new data, there's no data
or failed will give you--
will give us the
system more information
about how your application
is working.
So next, I wanted to pull
the curtain back a little bit
so that you guys can get a sense
of how Background Fetch works
under the-- behind
the curtains so that--
so that you can design your
features in the right way.
So the first thing that
you need to know is
that this system iOS
schedules these fetches.
It's important that
the system do this
so that these opportunities
can be coalesced
across applications.
That means that multiple
applications get an opportunity
fetch at the same time so
that we can optimize power,
that's really important.
You know, these phones
have great batteries
but you do too many of these
things at the same time and--
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
or you do too many of these
things over the course
of the day and that can
really wear it down.
The second thing to note
is that the system looks
at how users actually use their
device on the device in order
to see when they're
typically using it.
So that means it does a bit of
prediction in order to figure
out what the right
time to use that--
what the right time to
update that application.
The other thing that it
does is it's sensitive
to energy in daily users.
That means that it can look
at how much data is being used
and how much energy
is being used in order
to manage these fetches
correctly
so that we don't have users
with poor battery life
and excessive data plans.
And as we've mentioned before,
this is completely indifferent
to your actual app
running state.
If you happen to be
running, you'll get resumed.
If your application is no longer
running, you'll get launched.
So let me give you a
small example about--
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of what I mean by-- when I
say adapts to user activity.
So let's say the user
uses their device
in this particular pattern
on the first day and uses it
in a slightly different way
on the second day and so on.
The device can observe this
pattern so it can really figure
out that yes, the user uses
this INN app in the morning.
And they use it around
lunch time
and then they use
it in the evening.
And that's a really
simple thing to observe
because then it allows us to
actually make this prediction
about when those apps get used.
And the best time to update
an application's info is just
before the user launches it.
So that the data is as
fresh and up to date
as possible before
they get into it.
So it allows us to
make this prediction.
So three main points
that you should remember.
It learns these patterns
based on actual device usage.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
It coalesces, fetches across the
applications at the same time.
And this system allows us
to avoid frequent fetching
during periods of inactivity.
So of course, it would be
inefficient both for the device,
as well as your servers, if
we have the system fetching,
you know, every 15 minutes
or in the middle of the night
when the user is asleep.
So that's Background Fetch.
Now, we think this is going
to be incredibly useful
for many different
kinds of applications,
we thought about
social networking feeds,
news and entertainment
applications, blog aggregators,
weather apps, finance apps.
And we think that you can use
this in conjunction with one
of the other APIs that we're
going to be talking about soon,
call background transfers
in order
to download even bigger
things like photos or videos
to allow you to get
an experience
where the user can pop
up in your application
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and instantly start
viewing, you know,
large beautiful photos
or videos.
So next, let's talk about
Remote Notifications.
So if any of you have a kind of
messaging functionality inside
of your application, I'm sure
you're familiar with this flow.
If I send a message to somebody
over my new application here,
what happens is my server send
a push to the Apple servers
and that sends a
push to the device
and that causes a
notification banner to show
up on the lock screen.
When the user goes and slides
to view that notification,
only then is your
application launched or resumed
and then that's when you go
and retrieve the full message
so that it's ready to view.
Now, this can leave
users with a bit of lag
where they see either the old
message or an old transcript
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that they were looking
at before.
And then only after a few
seconds does it actually update
to show them their message.
So we flipped this around.
In iOS 7, you can actually get
woken up before the user sees
that banner notification.
So you can immediately
retrieve that message
and then make it ready
for viewing so that
when the user just swipes
to view on the lock screen,
they can see that
message right away
and we think this
is really powerful.
[ Applause ]
In addition, you can omit that
alert line and that'll allow you
to actually send a
silent notification.
And this gets delivered
in the background.
Again, if your app wasn't
running, we'd launch it.
If it is running, we resume it.
And you can go and retrieve
whatever content you need
to at this point.
Now, this is incredibly
powerful.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We think there's a lot of
applications that we'll be able
to take advantage of
this and do really,
really great auto
behavior with it.
There are a couple
things to note.
There's a new protocol that
we're introducing this year
that is optional right now.
That also was intended
to support silent pushes.
And you should go to the push
notifications lab on Wednesday
to learn more about it.
We think many providers
will get a kick
out of what the new
protocol can do.
But for you guys, all you need
to know is that you just need
to provide this content
available flag here
and you can set silent
notifications that gets
to your app up to date.
So let's take a look about the--
at the API in a little
bit more detail.
So this should be
a familiar pattern.
You just set this
Remote Notification key
in the UI background modes
or use the X code
feature capabilities menu
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to enable this.
You set content-available 1
in your APS payload and then
when your app is launched in
the background or resumed,
you will get a,
didReceiveRemoteNotification
with a completion handler.
So that will allow you to go
and retrieve that new message
or whatever you need to do.
And then call the completion
handler when you're done.
So again, in order to do a
silent push, all you need
to do is omit that alert or
sound entry in the APS payload.
Important thing to realize about
silent notifications though is
that the rate limited.
With normal notifications,
we fully expect users
to be able to manage that.
If you're annoying your user,
they will clearly do
something about it.
But with silent notifications,
obviously,
if the user doesn't have
any indication of them,
they can't manage
that on their own.
So iOS and our push servers will
manage a rate limit for you.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And the thing you need
to get out of this is
that we're not asking you
to hold back your silent
push notifications.
We want you to send
them as frequently
as your application dictates.
And the thing you
need to realize is
that we've done the work
for you to make sure
that the device can protect
itself and that it can make sure
that it doesn't run out of power
because it's using too
many push notifications.
So, I just want to let you know
how this works so that you can--
as you're going ahead
and testing this
that you're not surprised by the
way the pushes are rate limited.
So when the push rate is
completely acceptable and,
you know, let's say you're
sending only a couple an hour,
something like that, both normal
and silent push notifications
are delivered immediately.
You have that same quality
service that we have today,
it just sends straight
through and of course,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
they don't wake up the device.
Or rather they don't
wake the screen up.
When that push rate is too high,
silent pushes can
then get stored
for later delivery
on our servers.
And for those of
you who are familiar
with the way pushes work today,
we still have the same
storage guarantee, we store one
on the server, and if there's
another silent notification
that comes in when the push
rate is still too high,
that will get stored
in the server.
Then, if there's any
other communication
between the Apple push
service and the device,
we'll actually put that silent
notification on the back of that
and actually piggyback that
along, send along to the device.
So we're not halting
your pushes.
All we're doing is delaying
it by just a little bit
until when it's a good
time for the device
to receive it based on power.
So again, there's
nothing special
that you need to do here.
All you need to do is
realize that the device
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and the servers will take
care of the rate for you,
that you can just send it
when it's appropriate
for your application.
So here're some really great
examples that we came up with.
Obviously, like we
had in the example,
instant messaging is a
perfect example for this.
We think picture messaging
is especially important here
because oftentimes, when
you get that message,
the application needs to then
download that whole photo.
So now, you can download
it in the background
and that picture is completely
ready to go once users use that.
We think this is
really, really awesome.
This is really great for email.
So if you're already
sending push notifications
as email notifications,
right, you can then go
and fetch the entire mailbox.
We think silent notification
is being used
for completely different things.
If you have episodic content,
you can get those downloaded
using the Background
Transfer Service.
There are applications out
there that implement this kind
of read some stories later
kind of functionality.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And some applications
have actually gone so far
as to implement a
fetching behavior
on the back of region
monitoring.
So that when you go home or you
leave work, you can actually go
and download content then.
We think that this is
a much better model.
All you do in that case is
when the user add something
to that list, selling the silent
notification to the device
because A, the user
doesn't need to be notified
that they added something
to that list.
So that should be silent.
And then the application
can download that content
that they want to read offline.
So we think this is
actually really awesome
and it will work really well.
For Purchase Syncing, so if
you have a library of magazines
or comic books or something,
and the user buys something
on your website, this can be a
great way to send a notification
to the device so that it can
go download that new content
so it's available offline.
Or if you have a File
Syncing application
with documents, same thing.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Just send that notification
when it's ready, and then go.
So let's talk a little bit
about how silent
notifications can work
with background transfers to
provide a brand new feature,
auto downloading in
a TV application.
So let's say some TV network
has an application out there
that allows you to do
offline content viewing.
And they want to offer
a system where, hey,
every week when that
new episode of the show
that the user's favorited is
ready that it can download
onto the device so that
they can view it at anytime.
So the user asks
for new episodes
to be downloaded
when it's available.
When that episode is available,
the content provider can
just send a silent push
to the devices that have
signed up for the stuff.
And so the app going to
wake up and can check
for any newly available
episodes and queue them
into the Background
Transfer Service
so the application can go
back to sleep at this point
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and then once it's completed,
the application just wakes up,
updates the UI and then post a
local notification letting the
user know that it
has new content.
So the same thing would kind of
go for File Syncing application.
If you, let's say,
favorite a particular file
and then you want it
updated all the time,
whether that file changes,
let's say, if they're editing
on their desktop, that service
can send a silent push right
away and because it's rate
limited already, you don't need
to do anything to make sure
that's going at the right speed.
So once that app
wakes up, it can check
for any newly available files
and enqueue those file diffs
into the transfer
service and then the UI--
I'm sorry, the application will
then wake up and update its UI.
So receive push notifications
at the background,
we think this is big.
Silent pushers are rate
limited and that's intended
to help save you
effort and time.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So here were the two APIs that
we've talked about so far.
And when you're sitting down
and looking to enhance one
of your features with this,
we want you to kind of keep
in consideration why you
would pick one or the other.
You would typically use fetch
when the content is
really interesting
but not quite critical.
It's not really important
to let the user know
about it right away.
Whereas Remote Notifications
that would be a lot more
immediate, you know,
it's a message from their
friend or it needs as much time
as possible in order
to download.
If the content was available all
the time very, very frequently,
it can be really burdensome on
power as well as your servers
to notify all the applications
about it whenever that happens.
So we think that that's
a much better use case
for Background Fetch.
So for example, I
don't know about you
but my social networking
feeds always look
like they're updating
every single second.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And for Remote Notifications,
it's fine if it's very frequent
but maybe that's more sporadic
so if I'm working on a document
on my PC and it's supposed
to sync to my phone,
that would be sporadic but maybe
kind of frequent for that period
of time, where Remote
Notifications would be the
appropriate thing to use there.
OK, so let's dive into the
Background Transfer Service.
So in iOS 6, using the UI
application background test API,
applications can transfer files
while in the foreground or even
for a few minutes when
the application returns
to the background.
But that's limited sort
of arbitrarily by time.
You only get a few minutes
to download or upload
and that can cause weird user
experience where, you know,
maybe your video
didn't finish uploading.
So in addition, you
couldn't kind
of effectively download the
content or upload large assets.
In iOS 7, we've changed this.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We're providing a service that
allows you to enqueue downloads
and uploads that are managed
by the OS that continue even
after your application
exits or the device reboots.
It's not restricted by time.
We intend this for you
to enqueue large things.
You can enqueue it anytime,
either from the foreground.
Let's say if the user decided
to upload a video or download,
let's say an episodic content,
or from the background.
So if you get woken up
for a Background Fetch
or for Remote Notifications,
that's a great time
to enqueue a transfer into
Background Transfer Service.
And of course, your
application is woken
up to handle authentication
errors or completion.
So once it's done,
you can update your UI
and make sure the user
sees it very prominently,
that they have a new
piece of content.
So let's just take a
quick look at the API.
So we are introducing a new
class called NSURLSession today.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
It's part of the
CFNetwork framework
and I highly encourage you
to go to the What's New
in Foundation Networking
talk as well
as the foundation networking
lab and we'll have links
at the end of the talk.
So you create this NSURLSession,
you configure it using a
background session configuration
and then all you do is you
enqueue these NSURLSessionTasks
that are associated with
an existing NSURLRequest.
So any of the NSURLRequests
that you're doing right now,
all you do is you attach
them to the session task
and enqueue them
into the service.
And this can be download
tasks or upload tasks
and those just continue.
And then once you're-- once
that transfer is complete,
if you're in the background,
if you're not running
or you have been suspended, your
application will get launched
into background, you'll
get did finish launching
and then you'll get this new
callback called handle events
for background URL session
with a completion handler.
And what this allows
you to do is reconnect
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to your NSURLSession by
providing a unique identifier.
And that will allow you
to handle that new content
so you can, for example,
you know, update your UI
to prominently show
that there's--
your upload is completed or
that your download is done.
And then, of course, you want
to call the completion handler
to make sure that the
system can go back to sleep
and your snapshot gets taken.
So within the transfer
service, we have this notion
of a discretionary transfer.
And discretionary transfers
help preserve battery life
and data usage.
And the way they do that is
that they're power managed
and they also only go for Wi-Fi.
So if you enqueue a
transfer from the background,
these transfers will
always be discretionary.
And if you're enqueuing
something let's say
from the foreground, that
transfer can optionally request
for it to be discretionary.
So for example, if it's
something that is not--
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
let's say, it needs to
happen at some point
but the user didn't
say specifically,
"I want this downloaded,"
that would be something
that you would enqueue
as discretionary.
So here're some examples.
So this would be incredibly
useful for uploading photos
and videos like we said before.
Used in combination with some of
the existing multitasking modes,
so for example, if you have
significant location change,
and your user, for example,
flies to San Francisco,
they can download, let's say,
new Map Packs and new tiles
for the area in order to
automatically make sure
that their navigation
application continues
to work really well.
This will help keep your app
up to date by downloading
in the background number
of different things.
Maybe even, you know,
podcast or game content.
We think this will
be really great
and users will get
a kick out of this.
OK, so these are our three
new multitasking modes.
We think they're
really excellent.
We think that they add
a lot to the ecosystem
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and we really can't wait to
see what you guys do with it.
So details.
We have the viewed details that
we want to discuss with you
to make sure that as you're
architecting your applications
to take advantages of
these new opportunities
that you do the right
things in order to kind
of function well in the system.
The first thing to realize is
that you get a limited amount
of time to run to
the background.
This wouldn't be very power
efficient if you were able
to run for, let's
say 10 minutes.
You're given about less than
a minute to finish your update
and your fetch is in
parallel with other apps,
which means that you
want to make sure
that your CPU profile is
as minimal as possible
and you're doing these updates.
Obviously, since this is
designed for networking,
we expect many of
your applications
to use very little CPU time
because you're just transferring
data for the most part.
But you want to make sure to
use time profile and instruments
to make sure that you
are using as much as--
as little CPU time as possible
and that there's nothing obvious
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that you can get rid off.
So, it's really important
that you also complete as soon
as possible because if
you've been woken up,
the device is going to
stay awake for as much time
as it gave you until you
tell it to say, "I'm done,
I can let the system
go to sleep."
So it's important to
complete as soon as possible,
call the completion handler,
let the device sleep.
So the background task API.
When it's called from
the Background Fetch AP--
delegate or the Remote
Notification delegate
or the background
transfer completion,
your task will only be
given seconds to run
to the background
rather than minutes.
We realize that many of you
use the background task API
to close database connections
or close file handlers
or other system resources.
And we want to let you continue
doing that but this is not a way
for your application to run
for minutes and minutes on it.
The next detail.
So like I said before,
your snapshot
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and your state restoration
is saved
after calling the
completion handler.
You want to make sure it
configure your view hierarchy
to hide sensitive
information like,
let's say the user's passwords
of your say password
management application.
And like I said before,
you really want
to use save restoration
to transition seamlessly
from that cool snapshot
of the app switcher
back to the application.
Next up is a bit of privacy.
We've always encouraged
you to use data protection
when handling sensitive
user data.
This is incredibly
important for privacy.
We think that users come to
iOS and user applications
because it's a secure way
of using their device.
And so a lot of you
should be familiar
with this NSFileProtection API.
Just to explain just
a little bit.
Of course, there is a Data
Protection lab that you can go
to and we'll have a link
at the end of the session,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
but let's explain
this for a second.
So we've got
NSFileProtectionComplete.
What that means is that
whenever the device is unlocked
and actively being used,
these files are available.
You can use them as normal.
But when the device is locked,
those files are inaccessible.
And of course, the low
means that these files
and keychain items
are available always.
So even after the
first boot, you know,
when the device is
locked, et cetera.
And we highly encourage
you to not use the lowest
but use the highest or one
of the ones in between.
And we'll go over what
this mean in just a second.
But for completeness, here
are the rest of the APIs
that you should be
looking at but of course,
that'll be on the slides
that you'll get afterwards
and you can look at it there.
So, why should you
care about this
if you're doing the right thing?
If you're doing the right
thing, your keychain items
and credential, so let's say,
users-- usernames and passwords
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and log-in tokens
or cookies should be
in the keychain item
as a sec item.
And that should be the
maximum protection.
That's actually the default.
Your database, SQLite database
or coordinated database should
also be using the complete
protection so that
it's not available
when the device is locked.
Now, we've just told you
about all these great ways
that you can wake up and run
in the background and some
of those times, the device
is going to be locked.
It's going to be in their pocket
when they receive
a new text message
or if they get an
opportunity to launch.
So that means that you
need to kind of make
that a little bit more partial.
You want to be able to
have access to connect
to your service,
but what we're going
to do here is set these keychain
items to be partially protected
and specifically, we're
going to use the mode
where the data is available
after the very first unlock.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So what we encourage you to
do is to actually create--
is not to actually
reduce the protection
of that main credential
but to create a kind
of derivative credential
that has limited access.
So you might make it Read-Only
or you might make it expire
within, let's say, a week or so,
so that if that were to get
out, then there wouldn't be,
you know, harmful consequences.
So what do you do with the
data that you then download?
So you have that credential,
you connect your server,
you're able to download
some new information.
What you wanted use is the
background mode that allows you
to have this data accessible
while the file handle is open.
And you can go back
and refer to the--
read the previous
slides afterwards,
but all it does is allows you
to download new data, save it,
and as soon as you close
it, it can be secured.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And then once that main
database is accessible
when the device is unlocked,
you're going to merge
that new data into your database
when that's appropriate.
So there's a fairly
common pattern.
You can definitely go to
the data protection lab
and get more details about how
to do this, but we encourage you
to do this instead
of, let's say,
just downgrading the protection
on your end credentials.
OK, so next is battery life
and cellular data usage.
So, even though the system
protects the device and the user
against excessive cellular data
usage and power efficient--
and power usage, you can do
a lot to be a good citizen
and make sure that on
the user's devices,
they get as many opportunities
as possible in order
to have other applications
and your own application
get launched more often.
Very specifically, the
more efficient you are,
the more opportunities
there will be for your app
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and other apps to get launched.
So what can you do?
Well, just minimize
cellular data usage.
That's absolutely the
best thing you can do.
So we encourage you, before
calling the completion handler
to only really download what's
necessary to update your UI.
So download thumbnails
instead of full images.
But then enqueue
those full images
into a background transfer so
that the system can manage that.
For power efficiency, we
encourage you to enqueue
as many transfers as possible in
parallel that allows the radios
to go back to sleep as
quickly as possible.
So in addition, that also means
that if you have to be using,
let' say, Core Motion or one of
the other hardware-specific APIs
in order to, you know, provide
some kind of user interaction,
let's say you have a game
that involves moving your
phone around, we encourage you
to make sure that that's get
turned off while you're running
in the background so that
you're not impacting power.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And then of course,
like I said before,
call the completion handler
as soon as you're done.
That allows the system
to go back to sleep.
OK, so a quick reminder as well.
If the user removes your
application from app switcher,
your application
will no longer run
until it's then relaunched
by the user.
So if your-- you know, you get
feedback from users of saying,
"Hey, I removed it and then
I was expecting update."
This why. And the same
is true for settings.
If the user turns you off,
obviously, you won't get
up any background opportunities.
We'll be introducing API soon
to inspect new settings--
sorry, new API that will
allow you to inspect settings
so that you can say, "Hey,
am I going to actually run
in the background after
this," so you can make sure
that if you're promising some
functionality to the user,
that you can warn them, that
it's not going to be there.
And of course, like
Newsstand and Location,
they'll appear here as well.
So that the user can go
through and, you know,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
turn off particular applications
or turn off Background Fetch
overall if they want to.
So this is multitasking in iOS 6
and we've added Background Fetch
which allows you to
periodically get new content.
We added Remote Notifications so
that your application can launch
and be updated, in-response
from push notification.
And finally, we have a
Background Transfer Service
that allows you to enqueue
large uploads and downloads
to be finished later and then
woken up in the background.
For more information,
you're welcome
to contact our evangelist and
look at the programming guide
as well as access
to developer forms.
We have a lot of
related sessions to this.
We highly encourage you
to go the What's New
in Foundation Networking
session.
The keychain session
will let you learn more
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
about the data protection
pattern that I showed here.
I highly encourage you
to go to the What's New
in Core Location talk.
They have a lot of great
new things and you want
to check it out, as well as
the State Restoration talk.
You'll learn about how
do you state restoration
in your application,
how you can make sure
that your application
is up to date
when the user taps
on that app switcher.
With that, thank you.
[ Applause ]