Transcript
[ Music ]
>> Hi, everybody.
I'm Giovanni Tarducci, from the
System UI SpringBoard team.
And today, I'm happy to tell you
everything about managing your
windows on iPadOS.
We are introducing three new
API's, to do just that.
To respectively activate,
refresh, or destroy any of your
scene sessions.
But let's jump right into a demo
of these API's at work, in an
app we've been prototyping.
Okay. We call it Clown Town.
And it's a great new way to get
a clown for your party.
It opens to a full-screen map,
showing all the clowns in my
network.
I can tap on any of their
markers, to see more about them.
The implementation is straight
forward, as well.
The detail view controller just
knows how to show a clown with a
given ID.
While the map view controller,
delegates everything,
presentation, animation and
gestures to UIKit.
Through the presentviewcontroller
animated API.
Well, with the enhancement to
multitasking, we can push this
delegation model to the next
level.
And gain powerful new features
for free.
Taxes may apply at checkout.
So, we did start by adding an
"open in new window" button in
the data view.
So, that all our users are going
to be able to discover this
great new feature.
When tapped, we call new request
scene session activation API, to
open this clown in an auxiliary
dedicated window.
Let's do that.
Already, I can keep browsing my
map and checking out and
comparing other clowns.
But not only that, we can now
have the whole system working
for us.
We can resize the windows, move
them around.
Keep opening new windows.
And the one I had on my side, is
now in its own space in the
switcher.
Now, I can make this one a slide
over, move it around, stash it.
And maybe opening another couple
details, Crusty and a last one,
Mr. Happy here.
Okay, so, with the swipe app, I
can check out my whole stack of
slide overs.
And I can even quickly swipe
through them all, just like
that.
I can even go back from being a
slide over, to being next to the
map again.
Now, let's pause for a second.
We did achieve all of these,
again, by delegating,
presentation, animation and
more, to the system.
So far, through the single
request scene session activation
API.
Now, I only now noticed that Mr.
Happy here has got a one-star
rating.
Probably not a good clown.
So, let's get rid of him and his
window, through new request
scene session destruction API,
which I'm calling for the upper
right down button here.
Let's do that.
And he's gone for good.
Now, I remembered the one I had
in my switcher, had a five-star
rating.
So, let me open her again.
Notice how she wasn't
duplicated.
This is Clown Town policy.
And it's easily enforced, just
by asking the request session
activation API to activate and
existing session instead of a
new one.
I can even track her
availability.
She was checked and found
available, as I can tell from
the green navigation bar.
Also, an instant book button did
appear on the left side.
If her availability were to
change, I will get a
notification.
I will update this UI to have
the navigation bar now in red.
And I will call the new request
scene session refresh API, to
update, beside other things, the
snapshot of this UI, for it to
be represented in the switchers.
But I did not decide yet.
So, let us instead start
tracking them all, just like
this.
Say now that I do background the
app, to do something else.
Maybe recommend this app to my
friends.
And show the current collection
I have right now.
But I'm getting notifications
already.
A bunch of them are no longer
available.
I cannot recall their names.
So, let me instead use app
expose, to glance at all my
windows at once.
And there we go.
Their snapshots were updated,
which is great.
Because I can manage my window
right here and there.
A couple of swipe ups and I'm
done.
Looks like these clowns are
running out fast.
So, let me go ahead and book the
great BuBu LuBu, so we can go
back to our party.
Oops, see you later Clown Town.
Okay, so...
[ Applause ]
Thank you.
[ Applause ]
So, let's check out the API's,
activating a session.
First of all, you activate a
session only in response to
direct and local user
interaction.
The user has to touch the screen
for it to happen.
And you do so by calling the new
request scene session activation
API on UI application.
To either activate an existing
session or a new one.
Now, in Clown Town, when we
first launched, UIApplication
had just one open session.
The one with our map
configuration.
All in just window, displaying
our whole view hierarchy.
When the open a new window
button was pressed, through
delegation, the detail view
controller gets to the map view
controller, which is presenting
it.
And the map view controller
calls this method that we added
on our application delegate.
Here, since we have the no
duplicate policy, we check for
any existing session for this
given clown.
Now, on first launch, we won't
find any.
So, we're going to end up
passing nil here, at runtime.
Pass nil here, to this
parameter, requests a brand-new
scene session to be created.
We then create a userActivity
for this clown.
And the userActivity is going to
be given back to us by UIKit,
later on along the delegate
chain, as we'll see.
The options objects, let's me
specify a requesting scene,
which is meant to be the one
where this request was user
initiated.
The system uses this information
to avoid replacing the
requestingScene with the
activated one.
And for other navigation
purposes.
We can now call the API.
The new window is shown.
And alongside, a new session
hierarchy has been created.
As I mentioned, there are two
key delicate methods you
definitely want to implement, in
order for your app to have a say
in what actually gets created.
And how it gets configured.
So, let's step back and go back
to when we called the API.
As soon as we do so, UIKit
creates a brand-new scene
session.
And let's you specify a
configuration for it, by calling
configuration for connecting
scene session on your app
delegate.
You definitely want to implement
this one.
And here, you can inspect the
user activity.
Which is given back to you now
through the UI scene connecting
options, to pick a session.
In my case, it's the detail
configuration.
Now, if your configuration
specifies a storyboard, as I do
recommend.
At this point, UIKit is able to
go ahead and create the whole
view hierarchy.
And you just need to configure
that.
You do so by implementing
scenewillConnectToSession on
your scene delegate.
In there again, you'll be able
to find your user activity and
the connecting options.
And you configure your window
and view controller hierarchy
for it.
Now, that was a new session.
What about an existing session?
If the session is still is
existing, we go straight to the
scene delegate.
And if the session had been
disconnected in the meantime, we
call sceneWillConnectToSession.
But if the scene is still
connected, we'll just go to the
continueUserActivity one.
You definitely want to implement
those.
To recap, you activate a
session, only in response to
direct user request.
To either activate a new or
existing session.
And you want to implement your
app and scene delegates methods,
to be able to configure both
session and the window for the
activity at hand.
Now, onto refreshing a session.
You refresh for user-relevant
updates from your app.
A couple of examples.
It could be that you have
multiple windows showing and
working on the same assets.
And the user may have modified
them from a window or even
another device.
And now you want to keep them in
sync.
You want to have their
presentation being updated in
these features and more.
Or you just fetched new data and
it is available for the user to
be seen.
Or you want to update some scene
and session metadata, as we'll
see.
You do so by calling at any
time, the
requestSceneSessionRefresh API
on UIApplication.
By just passing in the session you
wish to be refreshed.
Now, what is it actually that
this API affords you to update?
You can update the state
restoration user activity for
the session.
You can update the scene
activation conditions.
And your UI, which is eventually
going to be captured in a
snapshot, again.
As we saw in Clown Town, thanks
to those updated snapshots, the
app felt alive in the switcher.
And we were able to confidently
act on the incoming data.
Without having to navigate to
each and every session, just to
find out, once connected and
updated, that we didn't even
want them anymore.
On an architectural note, you
want to listen for rare model
changes for which you want to
call the API.
Both in the interested view
controller, as well as in a
long-lived object.
Because if the scene is still
connected, either in the
foreground or the background, it
can listen to the notification
itself.
And call the API, which is going
to do the right thing
internally.
If the scene has been
disconnected though, the view
controller won't be there
anymore.
And so, the long-lived object
can step in, figure that out and
call to refresh API in its
place.
The scene is going then to be
background connected.
And the view controller will
have a chance to update itself.
And the snapshot will be
captured.
As a summary, you want to
refresh for user relevant
updates from your app.
Make your layout time fast, so
that we can quickly capture the
snapshot.
And do not rely on it being
executed immediately.
The system reserves the ability
to fulfill this request at a
later point in time, if
necessary.
Now, destroying a session, also
known as going away with style.
You destroy a session for direct
user request.
Or if you have a window, which
is an auxiliary window dedicated
to show a piece of data, an
item, that the user already
deleted from somewhere else.
Another window or even another
device.
You do so by calling, at any
time, the
requestSceneSessionDestruction
API, on UIApplication.
Which takes in the session you
wish to be destroyed.
As well as an options object.
This option lets you specify a
DismissalAnimation.
Which the system is going to
take into account, if the scene
happens to be foreground at that
moment.
Now, let me be clear, the
session is going to go away and
won't come back.
But the animation lets you
acknowledge the user's intent in
getting rid of it.
So, which one to pick, then?
The main draft is a great
paradigm.
When the main draft is
cancelled, without saving, the
user is explicitly asking for
its content to be destroyed.
Which is the common case, when
getting rid of a window, as we
saw in Clown Town.
You pick the standard animation,
in these cases, to acknowledge
this intent.
When to draft the assent, the
user is not asking for his
content to be destroyed.
The session though, will be
destroyed as a side effect of
the user accepting the final
purpose of the session.
Which, in the mail case, is
sending the e-mail.
In the Clown Town case, was
booking the clown, if you are in
tracking mode.
You pick commit to acknowledge
that the final purpose of the
session has been approved by the
user.
Now, when the draft is cancelled
and saved, the user again, is
not asking for his content to be
destroyed.
The session though, will be
destroyed as a side effect of
the user declining from taking
action right now.
You pick decline, in these
cases, to acknowledge that the
final purpose of the session has
not been fulfilled yet.
To recap, you destroy a session
in response to user request.
Either locally or remotely.
And you pick the animation style
to best acknowledge the user's
intent in getting rid of it.
To recap, we've seen how through
these new API's, you can empower
your user's actions.
And you can delegate complexity
to the system, while gaining
powerful new features, easily
discoverable by all your users.
Thank you.
[ Applause ]