Transcript
[ Applause ]
>> Hello, everyone.
I hope you're having a great
WWDC.
Welcome to Building Great
Document-based Apps.
Today we are going to talk about
all the new features of the
Files app and how to integrate
them in your app.
First, let's talk about the
Files app.
One of the biggest features of
this app is that it gathers all
the cloud vendors in one place.
This is done thanks to the new
file provider extension.
All the cloud vendors that use
this file provider extension
will appear next to the iCloud
drive on my iPad in the sidebar.
If you want to know more about
this extension, we invite you to
check out the File Provider
Enhancements session tomorrow at
11:00 a.m. There are two file
providers by default in the
system.
The first one is the iCloud
Drive provider.
It will show all the files
inside the iCloud drive folder
of the user as well as all the
files in the Cloud container of
all the applications in the
system.
The second provider is the on my
iPad provider.
It will let the user leverage
the storage of their devices.
It will show the content inside
the Documents folder of the app
container.
If you want your app to be part
of this local storage provider,
your app needs to be a
document-based app or support
File Sharing and Opening
Documents In Place.
As I said before, we are going
to be showing the documents
inside the, the files inside the
Documents folder.
So please keep the content of
this folder clean.
You should only have the files
that matter to the user.
Also, you have to keep in mind
that these files won't be synced
across multiple devices but
still will be part of the iCloud
backup.
Now I would like to talk about
the new Recents view.
This view will show all the
documents that have been
recently opened, imported, and
modified.
Also, it will show all the
documents organized by tags and
all the documents that are
shared with other people.
Tags are a great means to
organize files.
And in iOS 11, there's new
tagging UI that will let the
user create new tag and manage
their tags.
Tags will be synced across
multiple providers and they will
be also synced across all your
devices.
The last thing -- The last
feature I would like to talk
about in the Files App is the
Recents Popover.
The user will be able to present
this popover when performing a
long press on the Files App.
This [inaudible] will show all
the recent documents and the
user will be able to open them
with just one tap.
It will also let the user import
the document into any
application using the new Drag
and Drop gesture.
I'm sure now you want to have
all these great features in your
app.
Throughout the last release
cycles, we've received very many
requests from you.
You want to have a unified UI
for file browsing.
You want your app to be able to
access any file from other apps
in the system.
You don't want to write more
code in order to adopt all the
cloud vendors that are already
part of the system.
And you want to have deeper
integration of your custom
content types throughout system.
Well today we are going to view
some new API.
I will tell later how we've done
so far with those requests.
First, I would like to talk
about the new document browser
API.
This year there's a new class,
the UI Document Browser View
Controller.
I know it's a mouthful, so from
now on I will call it the
Browser VC.
Together with this, there's a
new Xcode template that will let
you create a new document-based
application from scratch.
And also the UI Document Picker
will get some of the features of
the Browser VC.
So now let's first talk about
the Browser View Controller.
This view controller will
provide your app the same
feature set as Files app.
In fact, Files is just a very
thin layer on top of this
Browser View Controller.
With this view controller, you
won't have to write more code in
order to integrate any cloud
storage provider that supports
File Provider.
Also it will support appearance
customization to make it look
like your app.
And by using this view
controller, your app will get
the Recents Popover that we saw
before.
Spotlight plays a key role in
this Browser VC.
By using this view controller,
all the metadata of your
document will automatically be
indexed in Spotlight.
If you need to have further
integration, you will have to
register your own CS Searchable
Items.
Now there will be two CS
Searchable Item in the system as
in order to duplicate them, the
Browser VC will use a content
URL of this CS Searchable Items.
So you have to set it properly.
If you want to know more about
Core Spotlight, there's a
session at 4:10 p.m. today.
At Apple, we deeply care about
our user's privacy.
Because of that, we built the
Browser View Controller with
privacy in mind since the very
beginning.
When the user installs your app,
you will only have access to all
the documents inside the app
container.
You will be able to import and
create new documents but only
the default safe location which
will be a [inaudible] for you.
So how are you going to access
to a file in any other place in
the system?
Well, you will do it via user
interaction.
The Browser VC is running in a
different process.
And once the user taps on a
document, the Browser VC will
forward to your app the access
of that document.
And now, let's take a look at
the UI Document Picker View
Controller.
As I said before, we'll get some
of the features of the Browser
VC.
For example, the Browse View and
the Recents View.
Also, it will support opening
and importing multiple documents
at the same time.
If you want to support it, you
need to set the allows Multiple
Selection to true.
In order to support multiple
documents, we are deprecating
the document picker with Pick
Document At URL delegate method
in favor of a delegate method
that support multiple URLs at
the same time.
Also this year, we are
deprecating the UI Document Menu
View Controller in favor of the
UI Document Browser View
Controller.
And now, we've seen an overview
of the browser APIs.
Let's take a look at how to make
use of this UI Document Browser
View Controller in your app.
So first things first.
You will have to configure the
Info.plist.
Here, you need to set the UI
Supports Document Browser key to
yes.
This will tell the system that
your app is a UI Document Brower
based application.
Then you will need to declare
the content types that are
supported by your app.
And this is important because
the Browser VC will use this
content type in order to know
what files to display in your
application.
It's important to note that the
UI Document Browser View
Controller needs to be the root
View Controller of your app.
It won't work otherwise.
As I said before, the Browser VC
supports appearance
customization.
By default, it will look like
this with a white background and
a blue tint color.
There are two properties that
you can use in order to
customize it further.
The browser Interface Style
which has three modes, dark,
white, and light, and tint
color.
If you use a dark style and an
orange tint color, your app will
look like this.
So now that we configured the
Browser VC, the first thing your
app will have to support is
Opening Documents.
So let's take a look at how it
works.
First, the user will tap on one
of these documents.
Here, the Browser VC will fetch
and download the information of
the document.
And once the document is ready,
it will forward the access to
your application and call the
did Pick Delegate method.
Here, you just need to load and
present the document.
When opening documents, the
Browser VC will give your app
persistent access to that URL.
Now, if you want to restore it,
it's not enough to store the
URL.
You need to store the bookmark
data associated to this URL
because this is the piece of
information that keeps track of
the URL access.
The code to Opening Document
looks like this.
You just need to implement the
document Browser did Pick
Document URLs and present the
view controller for the
document.
Like the UI Document Picker, the
Browser VC supports opening
multiple documents at the same
time.
If you want your app to support
this, you need to set the allows
Picking Multiple Items to true.
Now that your app is able to
open any file in the system, the
next thing is to be able to
create new documents.
There are two places where you
can create new documents.
The first one is the Recents
View.
If the user taps the Create
button here, it will create a
new document in the default safe
location of your app.
If you tap the Create button in
the Browse View, it will create
a new document in the current
location of the Browse View.
Now let's take a look at the
workflow.
Once the user taps on one of
these Create buttons, your app
will receive an import handler.
Now if you already have the
source URL, you can call the
import handler.
If not, if your app needs to
show some template chooser in
order to know what source URL to
choose, now is the moment.
You present a template chooser
and call the import handler.
The import handler will move
that file to the provider.
And once the file is in the
provider, it will call you back
with a succeed delegate method.
Here, as for the open case, you
just need to load and present
the document.
Now the import operation can
fail for many reasons.
And if that is the case, you
need to handle the error and
present some UI to the user.
Now let's take a look at how to
code this.
First you need to implement the
document Browser did Request
Document Creation.
Here, as I said before, you can
optionally present a Template
Chooser.
Now in this example, the present
Template Chooser will call us
back with the URL that the user
picked for the template.
And it will tell us if the user
canceled the document creation.
Once we get the URL, we just
need to call the import handler
with a mode.
There are two different modes:
copy and move.
If the user canceled the
document creation, we still need
to call the import handler with
nil as the URL and none as the
mode.
This is important.
This will tell the Browser VC
that the creation operation is
over.
Once the document is fully
imported, the document Browser
did Import Document At source
URL to Destination URL will be
called.
Here, you just need to load and
present the UI for the document.
As I said before, the import
operation can fail.
And if that is the case, the
Document Browser failed To
Import Document URL will be
called.
Here, you need to handle the
error and present some UI to the
user.
Now we are dealing with
documents that are operated by
different processes, different
apps, and different devices at
the same time.
And because of that, it's
important to use NS File
Coordination and NS File
Presenter in order to avoid risk
conditions between these
processes.
Now because the document is
outside your app container, the
Browser VC is using
Security-scoped URLs, which
means you have to start and stop
accessing that URL in order to
have the right to write and read
the URL.
We highly encourage you to use
UI Document.
By using it, you will get File
Coordination, File Presenter,
and Security-scoped URL support
for free, as well as other
features like Autosave.
If you want to know more about
UI Document, please take a look
at the Building Document-Based
Apps session from WWDC 2015.
And now I would like to
introduce my colleague Raffeal
to give you a demo on how to use
the UI Document Browser View
Controller in your app.
Raffael
[ Applause ]
.
>> Thanks, Pau.
Good morning, everyone.
So now that you've got to know
the API of the new UI Document
Browser View Controller, I would
like to walk you through and
show a demo of how easy it is to
build a great document-based app
for iOS 11.
We're going to build a very
simple particle editor with a
particle system on the left and
an inspect on the right side
that allows you to customize
some properties of the particle
system.
Now each particle system comes
within one document and,
therefore, using the UI Document
Browser View Controller is a
perfect choice for our
applications.
So now let's just switch to
Xcode.
Xcode 11 comes with a new
template for document-based
applications.
Let's try it out.
Going to call it particles and
create the new application.
Now once instantiated, this
template comes with everything
you need to build a
document-based application from
scratch.
First of all, the Info.plist of
our target is already set up the
way Pau mentioned it earlier
with the right key.
Next, we have a Document Browser
View Controller subclass that
has all the code already in
place that you might want to
customize later.
It also comes with a view
controller subclass, the
Document View Controller which
will be in charge of presenting
the contents of our files.
Next, as Pau mentioned also
earlier, we have the subclass of
UI Document that acts as the
model of our documents at
runtime.
And last but not least, our
storyboard is set up to have the
Document Browser View Controller
as the root View Controller
already set up and the Document
View Controller ready to be
instantiated when we create new
files or open existing files.
So let's just take a look at
what we get just by launching
this template in our simulator.
Now once started, we see the new
Recents view with your recent
documents that you might have
created before.
Of course, we haven't created
any files yet, so let's switch
to the Browse view.
We see our Cloud storage vendors
on the left side in the slide
bar next to the new On My iPad
storage.
We also see the Favorites and
our Tags that are synchronized
across all your devices.
In the middle of the screen, we
see a large Create Document
button that allows you to create
new documents.
So let's click it.
Well, nothing really happens yet
and that's expected.
That's because we haven't told
the UI Document Browser View
Controller yet what it means to
create new files in our
application.
So let's fix this.
Therefore, we switch back to our
UI Document Browser View
Controller subclass.
And as Pau mentioned earlier,
when the user tapes the Create
Document button, we'll get a
call back to the Document
Browser View Controller Delegate
function did Request Document
Creation With Handler.
Now what we have to do here is
we have to give back a URL of
the newly created file to the
Document Browser View
Controller.
Now in our situation, let me add
a new particles file to our
target.
We make sure that it's added to
our target and finish.
Now at runtime, we just go ahead
and obtain the URL of this added
document via our NS main bundle.
Once we get the URL, we pass it
to the input handler that we get
from our delegate function.
And we perform a copy operation
on the URL.
Now the UI Document Browser View
Controller will get this URL and
will do all the heavy lifting
for you in the background like
moving the file to the right
location and processing the URL.
Once it's done, it will give us
a call back to either did Import
Document At source URL or failed
To Import Document At URL.
Now if we fail to import the
newly created file, since we
want to be a good developer we
should go ahead and implement
proper error handling, for
example, by presenting an error
to the user.
However, if we succeeded, we can
go ahead and present the
document that we've just
created.
Now let's say the user has
picked an existing file, in that
situation, we're going to get a
call back to the did Pick
Document URLs function.
Same here, we just go ahead take
for example the first of our
document URLs that we get and
present it.
Now presenting a document in our
app means instantiating one of
these Document View Controllers
giving it a document that we
initialize with document URL
that we want to open and then we
just go ahead and present the
Document View Controller.
Now let's take a look at the
simulator again.
The app launches again.
We're in the Browse view and we
can tap the Create Document
button.
And the Document View Controller
appears with details about the
file that we've just created.
Once we are done, we can close
the Document View Controller
again to return to the root View
Controller or Document Browser
View Controller.
Now let me switch to a more
advanced version of this project
which has already all the code
pieces in place to render a
particle system on the left and
an editor on the right side so
that we can focus on the
Document Browser View Controller
related code parts.
Before I'm going to remove the
app that we've just created to
avoid any further conflicts.
Now this is still the same, it's
still the same project.
It's based on the template that
we've instantiated in the
beginning.
Let me show you some additions
that we made to our Particle app
Info.plist.
First, again, the key to
Document Browser View Controller
is still set to yes, just the
way Pau explained earlier.
But more than that, in the
Exported UTIs section, we are
creating a new UTI type for our
Particles files.
We're going to give it a
description particles.
We give it an identifier and we
let it conform to the UTI types
public data and public content.
That means our Particle files
are a stream of data and they
have a semantic of document
files.
Now in the additional exported
UTI properties, we defined that
our files should have, whoops,
sorry, should have the particles
extension.
That means that any file in the
system that has the .particles
extension will be recognized as
a file of our newly created UTI
type.
So now that the UTI type is
done, we can go ahead and tell
our application that we're
actually supported.
So in the Document Types, we
just mentioned our particles
file format again.
We identified the identifier and
any additional document type
properties.
We define our CF Bundle Type
Role to be editor and the LS
Handler Rank to be owner.
If you want to learn more about
this, check the documentation.
So now the UTI types are
properly set and that means that
the Document Browser View
Controller will make sure that
users are only allowed to pick
documents of our new file type.
It also makes sure that when you
search inside the Document
Browser View Controller, you
will only see search results
that make this UI type.
And last but not least, in any
kind of UI document interaction
control in a different
application for Particle files,
you'll see the action to open
the file in our app.
So now let's take a look at our
actual documents.
We switch to our UI Document
subclass.
Now UI Document is quite
powerful and we highly encourage
you to make user of it.
As Pau mentioned earlier, it
comes with a lot of great
benefits such as autosaving,
file coordination and NS File
Presenter, Versioning, and much
more and, therefore, the UI
Document and the UI Document
Browser View Controller are
literally made for each other.
So let's take a look at what we
are doing here.
Now the document represents the
document at runtime.
So obviously since we are
talking about Particle systems,
it should have a reference to
SCN Particle System.
Now the next thing we are doing
is we're implementing saving and
loading files.
Therefore, we have to overwrite
the function's content for type
and load from contents.
Now all we really have to do
here is archiving [inaudible] an
existing Particle system and
that works because our SCN
Particle System already
conformed to NS coding.
So we don't really have to do a
lot here.
We use a Keyed Archiver to
archive the data or we use NS
Keyed Unarchiver to unarchive an
existing one again.
Now that's all you have to do
about the document.
Let's take a look at the
Document View Controller.
Again, that's the one that is in
charge of presenting the
contents of a document.
So obviously, before we present
a Document View Controller, we
should [inaudible] reference to
a document.
Now to set document function in
our case is asynchronous and
that's because loading a
document should be asynchronous
because file [inaudible] is
involved.
We're reading from the disk and
you shouldn't do this on the
main thread.
So let's take a look at how we
should implement this.
First, we simply keep a
reference to our document.
We then go ahead and load our
view controller and then we call
the open function on our
document.
Now this will do all the work in
the background and will give us
a call back once it's back.
Now if anything went wrong
during the loading of the
document, we're going to get a
call to handle error user
interaction permitted on the UI
document subclass.
Since we want to be good
developers, we have to implement
this function.
If we succeeded, we can go ahead
and take the document and pass
it to our particle View
Controller and our editor View
Controller.
Now the Document View Controller
really is just a container view
controller with a particle
system on the left and the
editor on the right.
Now in any case, we have to call
the completion handler to
indicate that we're done with
setting the document.
Now that's about opening a
document.
But of course we also want to
dismiss our Document View
Controller at some point.
Same thing.
Instead of calling the open
function, this time we call
obviously the close function.
This is asynchronous again
because we are saving the
document if required.
And the completion Handler, we
just dismiss the Document View
Controller.
Now the Document View Controller
is pretty much done at this
point.
So we can go ahead and take a
look again at the Document
Browser View Controller.
This is the one that is in
charge of presenting our
document view controllers,
either when we create a new file
or when we open an existing
file.
Let's take a look at this again.
So when we create a new file, we
get a call back to did Request
Document Creation With Handler.
We obtained the URL from our NS
main Bundle and passed it back
via the import handler and a
copy operation.
We'll either get a call back to
did Import Document At URL or
failed To Import Document at
URL.
If we succeeded, we go ahead and
present the document, which is
just the same as when we open a
file that already existed
before.
Now when we want to present a
document, we instantiate the
Document View Controller from
the storyboard and we pass the
document via our function that
we've just completed, set
Document with a reference to a
newly created document instance.
Once that is done, we just go
ahead and present the Document
View Controller.
Let's take a look at this in the
simulator.
Switch back to the Browse view
and hit the Create Document
button.
A new file is created.
And there we go.
Our beautiful particles with an
inspector on the right side.
We can change the values a bit,
change the size, change the
color.
And once we are done with it, we
just close the document again by
pressing the Done button.
Great. So creating documents and
opening documents works like a
charm.
But there is one thing that I
don't really like yet, which is
the Document Browser View
Controller here has this white
appearance whereas the particle
View Controller has a really
dark appearance.
So let's fix this.
As Pau mentioned earlier, there
are three browser use interface
styles that you can choose from.
First, dark, light, and white.
Now obviously, dark seems like a
great choice for our situation
here.
So let's switch back to the
Document Browser View Controller
subclass.
Now the view Did Load method of
the subclass is a great moment
to configure the document
browser.
In this situation, what we can
do is set the browser User
Interface Style to dark and we
can also modify the tint Color
of the view of the Document
Browser View Controller.
Now in this situation, using a
bright orange probably will look
great with our fire particles.
So let's take a look.
There we go.
This is the same Document
Browser View Controller but in a
dark appearance which should
look much better than the one
before once we open the Document
View Controller.
Even the control URI now has the
updated appearance.
Let's create a new folder, call
it fire,
and open a new document.
Now the transition between the
two view controllers is much
smoother and looks much better.
So that's pretty much all I have
to tell you about the first
demo.
And to get an overview of what
we learned so far, I would like
to hand it back to Pau
[ Applause ]
>> So let's take a look at what
we've seen in the demo.
First, we saw how to create a
new document-based application
from the Xcode template.
Then, we saw how to create new
documents and how to open them.
And finally, we saw how to
customize the appearance of the
Browser VC to make it look like
the rest of our app.
And now that we have the basics
of this Browser VC, let's take a
look at how to get and provide a
great experience for our users.
In this section, I would like to
talk about three different
topics: open-in-place, how to
provide custom actions in the
Browser VC, and how to create a
great opening experience.
So first, let's talk about
open-in-place.
Open-in-place is a great feature
that came with iOS 9.
It allows apps to share files
between them without the need of
copying them.
Also because of this, you have
to be careful when accessing
those documents because other
apps might be already accessing
them.
Now the Browser VC makes use of
this feature in order to open
the files from the Recents
Popover, so if you're using the
Browser VC in your app, you
really need to make use of
open-in-place.
If you're starting from the
Xcode template, it's real easy.
You don't have to do anything.
If not, you will have to
implement support open-in-place.
So let's take a look at the
code.
First, we have to implement the
application open input URL
delegate method.
Here, first thing is to check if
the input URL is a file URL.
And if so, we can call the
Reveal Document method from the
Browser VC.
This method will reveal the
document in the Recents View and
call us back when it's ready.
Now we can load and present the
document as we did for open and
creation.
If it fails, we need to handle
the error and present some UI to
the user.
Now let's take a look at how to
add custom actions into this
Browser VC.
There are three different ways
of add custom actions.
The first one is the UI Document
Browser Action.
You can add these actions when
the user performs long press on
a document and when the user
enters selection mode.
In order to create them, you
need to give an identifier
localized Title and availability
in the handler.
The availability has two values:
menu and navigation bar.
Menu will make the action appear
when the user performs a long
press and the navigation bar
will make the action appear when
the user enters selection mode.
The handler will give you the
array of URLs that the user
wants to use for the action.
Now unlike the Open URL, this
method you will only have access
to these URLs until your
application gets killed.
Now that we have our action, you
need to set the supported
content types.
The Browser VC will use the
content types to know when to
display your action.
Then, you need to set the
supports multiple items to
specify if you can support
multiple items at once.
And you just need to set the
custom actions that you created
into the custom action array of
the Browser VC.
The second type of actions are
the UI Bar Button Items.
You can add these actions in the
navigation bar of the Recents VC
and the browse, sorry, the
Recents View and the Browser
View and you can add them in the
trailing or leading sides of the
navigation bar.
The third type of actions are
the ones that you can add in the
UI Activity View Controller.
The Browser VC will show this
view controller when the user
performs the share action.
The Browser VC will let you have
control of this activity view
controller before it gets
presented.
And also, it will let you add
custom actions when it's
creating this UI Activity View
Controller.
So let's take a look at the
code.
If you want to add additional
actions, you need to implement
the document Brower application
activities for document URL
delegate method.
If you want to have access to
this Activity View Controller,
you need to implement the
Document Browser will Present
activity View Controller.
And that's all for the actions.
Now as you've seen already in
Files, there's a great opening
transition that goes from the
thumbnail to the full screen.
And Files app is able to do this
thanks to the new UI Document
Browser Transition Controller.
This class will let you set
display loading progress on top
of the thumbnail while you are
loading the document.
And it will also let you animate
with Zoom transition when you're
presenting the Document View
Controller for the document.
So now, let's take a look at the
workflow.
First, you will have to get the
URL that the user just picked.
Here, you will start loading the
content of the document.
And while loading it, you will
have to update the Transition
Controller.
Once the document is fully
loaded, you just need to present
the document and use the
Transition Controller to drive
the animation for the
presentation.
So now, let's take a look at how
it works.
First, once you have the URL
that the user picked, you need
to create the progress object
that will track the loading of
the document.
Here, you create also the
transition Controller that will
track the loading and that will
drive the animation from the
thumbnail to the full screen.
Now you just need to set the
progress onto the transition
Controller.
Here, we are ready to load the
document.
In our example, the load
Document method will load the
document while updating the
progress that we created before.
And when the document is fully
loaded, it will call us back.
Here, we just need to present
the Document View Controller.
Now, if we stop here, we will
get the [inaudible] from UIKit
which is a slide from the bottom
but we want to have this nice
zoom transition.
And for that, we need to
implement the transitioning
delegate of the presented View
Controller.
The transitioning delegate needs
to implement the UI View
Controller Transitioning
Delegate protocol.
In this protocol, you need to
implement two main methods: the
animation controller for
presented view controller and
the animation controller for the
dismissed view controller.
Here, you just need to return
the transition controller that
we created before.
And now I will like to hand back
to Raffael to show you how to
implement all these advanced
features.
Raffael
[ Applause ]
.
>> Thanks, Pau.
So in this second demo, I'd like
to show you three cool things.
First, we're going to take a
look at open-in-place and how
easy it is to adopt it with your
Document Browser View Controller
application.
Next, we're going to take a look
at custom actions.
We're going to add a new action
that shows up in the long press
menu when you tap and hold a
document.
And last but not least, we're
going to implement a custom view
controller transition to improve
the user experience when we open
an existing file or create a new
one.
So let's just jump back right
into our project.
Now let's talk about
open-in-place.
Open-in-place is a great feature
that has been introduced with
iOS 9 and it allows you to work
on the file that the user has
chosen instead of on a copy of
it.
Now adopting it is super easy.
And, in fact, if you come from
the document based apps
template, you have literally
nothing to do.
The way it works is when the
user taps the document outside
of your app, iOS will make a
call to your app delegate to
open the URL with options.
So let's take a look.
Now in this function, what we do
is first we make sure that the
URL that we get from iOS
actually is a file URL.
If it's not, we should probably
return because we are not in the
situation that we expect.
Once we pass that test, we get
our document Browser View
Controller which is the root
View Controller of our
application.
And we take the URL and pass it
to the reveal Document function.
Now the Document Browser View
Controller again will do all the
heavy lifting for you in the
background.
It will process the URL, move it
if required, and once it's done,
we're going to get a call back
with our completion handler.
Now again, if we get an error,
since we want to be good
developers, we're going to
handle the error appropriately
for example by showing an alert
view to the user.
If everything went right, we
just go ahead and present the
document with that new reveal
Document URL.
That's literally all you have to
do to support open-in-place in
your document-based application.
Now let's take a look at custom
actions.
So our particle systems are
really beautiful, right, and we
might want to share them with
our friends.
So I'm going to add a new action
that shows up when you long
press a document to export this
particle system as a GIF file or
a GIF file.
Now let's take a look at the
Document Browser View Controller
again.
The view did load method is a
great moment to configure these
actions.
So, therefore, I'm instantiating
a new UI Document Browser
Action.
I give it an identifier that is
unique throughout the app, a
localized Title, and I set the
availability to menu only.
So this will make sure that this
action only shows up when you
long press a document inside
your Document Browser View
Controller grid.
We also have to give it a
handler which is the one that
will be executed whenever the
user taps our action.
In this situation, we just go
ahead and log [inaudible]to the
consol.
Next, we define the action
supported Content Types to be
com.example.particles with just
the UTI type we defined earlier.
So just make sure that only our
own files will get this action
in the menu.
And last but not least, all we
have to do is define the custom
actions of our Document Browser
View Controller to be array
containing this newly created
action.
Let's try it out in the
simulator.
Now on our existing file, we
perform a long press and we see
that there's a new action
showing up here, export as GIF.
Once tapped, we see that in the
console the handler of the
action has been executed.
That was pretty easy.
Now let's move to the third and
the coolest things, the coolest
thing that I wanted to show you,
which is custom view controller
transitions.
Right now when we present our
Document View Controller, we get
a simple slide up amination that
is provided by UIKit and that's
already pretty cool but it's not
really the way it should look
like.
Instead, the way it really
should look like is the user
taps the document thumbnail and
the thumbnail grows into the
particle system on the left side
of our Document View Controller.
So let's take a look at how we
can make this work.
Therefore, we switch back to the
present document function that
we created earlier.
Now the way custom View
Controller transitions work is
you register yourself as the
transitioning delegate of the
view controller that is about to
be presented.
Before it is presented, UIKit
will call us and ask for the
transitioning controller.
We give back the transitioning
controller and that object will
be in charge of driving the
animation from view controller A
to view controller B.
View controller A in our
situation is the Document
Browser View Controller.
View controller B is the
Document View Controller.
Now Pau mentioned that earlier
the Document Browser View
Controller already gives us this
transitioning controller for us.
We just have to keep a reference
and pass it back to the function
that UIKit will call.
So first, we register ourselves
as the transitioning delegate of
the document View Controller
that is about to be presented.
Next, we obtain a new
transitioning Controller by
calling the transition
Controller for Document URL on
our UI Document Browser View
Controller.
Now this object doesn't really
need a lot of configuration.
The only thing it really needs
is the target View.
The target View is the one that
we're going to animate to.
And in our situation, that's the
particle system on the left.
We keep a reference to the
transitioning controller that
we've just obtained via our
variable.
Now the last thing we really
have to do is implementing the
UI View Controller Transitioning
Delegate protocol.
Now, therefore, we implement the
two functions: animation
Controller for Presented View
Controller and also, because we
want to support closing
documents, animation Controller
for dismissed view controller.
In both functions, all we have
to do is return the
transitioning controller that
we've just obtained.
Let's try it out in the
simulator.
Beautiful, isn't it?
We get a nice transition from
the thumbnail to our particle
system.
And when we're done with the
file modifications, we tap the
Done button to close the file
again and we transition
beautifully back to our UI
Document Browser View
Controller.
So that's pretty much it for the
second demo.
Let's take a look at what we've
learned so far.
First, we've taken a look at how
easy it is to support
open-in-place in your
application.
The UI Document Browser View
Controller really does all the
heavy lifting for you.
Next, we've implemented a custom
action that shows up only when
you long press a document in the
Document Browser View
Controller.
And last but not least, we've
improved the user experience a
lot when opening and closing
documents by implementing a
custom view controller
transition using the UI Document
Browser Transition Controller.
Now that's pretty much it for
the second demo.
And to tell us what's new on the
Quick Look side, I would like to
hand it over to my colleague and
friend Maxime.
Maxime
[ Applause ]
.
>> Thank you, Raffael.
Good afternoon, everyone.
I'm sure you have all seen the
great thumbnails of the files
app and I'm sure you wish your
own thumbnails could show up in
any document browser based app.
You are now going to see how
this is possible thanks to the
new thumbnail extension.
Currently, [inaudible] particles
app that we're building
throughout this session, all we
can are generic icons.
We could highly improve the user
experience by displaying instead
representative thumbnails that
indicate to the user the content
of the files.
So how can you provide
thumbnails of files that have
been downloaded and are
available on the device?
This was already possible before
iOS 11 through UI Document.
What you have to do is create a
subclass of UI Document and
return the thumbnail from your
subclass.
This only works for files
created by your application and
this has good performance
because when iOS will ask your
subclass of the thumbnails, the
file will be already loaded.
Let's take a quick look at the
code.
What we have to do is implement
the file Attributes To Write to
URL for save Operation method in
your UI document subclass and
return a dictionary of
thumbnails from this function.
So this is nice but this again
works only for files created by
your application.
So how can you provide
thumbnails for files created by
[inaudible] applications and by
other applications?
For this we are providing you
with a new thumbnail extension
which is system wide.
It means that this extension,
means that any thumbnails
generated by [inaudible]
extension will be displayed in
any document files based app
that displays files that your
extension can provide thumbnails
for.
This extension works with all
cloud vendors and is part of the
Quick Look framework.
Let's see how this works.
First, your document
browser-based app is displaying
-- Let's say that the document
browser based app is displaying
a set of files.
And if we want to display
thumbnails for these files to
have a good user experience,
it's going to Quick Look for
thumbnails.
Quick Look, we notice that for
some of these files, [inaudible]
extension is the one that can
provide thumbnails, so it's
going to forward the request to
your extension.
Your extension will generate
thumbnails, return them back to
Quick Look which will finally
forward them back to the app
that asked for the thumbnails,
which will be able to display
them.
Let's see how you can get
started.
This is actually pretty simple
because we added a new template
in Xcode that contains some
sample code for you as well as
an Info.plist.
After creating your extension,
you will want to head to the
Info.plist file and edit it.
So first thing you will have to
do is add all the UTIs you can
[inaudible] to QL Supported
Content Types array.
Please note that you can only
provide thumbnails for UTIs you
own and export and that iOS will
check for UTI equality and not
UTI conformance.
So we'll have to make sure to
list all the UTIs inside
[inaudible] of the plist.
Now how can you actually provide
thumbnails for files?
There are two ways.
You can either draw the
thumbnail or return the image
file URL.
So the most preferred one is of
course the first one, drawing
the thumbnail, because it's the
most flexible one.
Let's see how it works.
So any method you will have to
implement in this extension will
receive a parameter of class QL
File Thumbnail Request which
contains three [inaudible].
The file URL, the URL of the
file we want to send a file, the
maximum size of the thumbnail
which is requested, as well as
the scale.
What do we have to return is a
QL Thumbnail Reply object
containing the Drawing Block and
context Size.
Let's see why you need to return
the context Size.
The maximum size parameter of
the request indicates to you the
maximum size of the CG Context
you can draw your thumbnail
into.
Now let's say that we want to
draw this image into our
context.
As you can see at full scale,
it's bigger than the maximum
size of the Context.
So what we'll have to do is
downscale it to make sure that
it can fit within the CG
Context.
But if we load this image into
the context we have on the left,
we'll end up returning a
thumbnail with unused
[inaudible], meaning a floating
thumbnail, which is not what we
want.
So we'll have to determine the
correct context size in which we
want to draw and pass it to the
QL Thumbnail Reply.
Thanks to that, our Drawing
Block will receive CG Context
correctly set with the requested
size, the context Size, and
we'll be able to draw the
thumbnail [inaudible].
Now if you don't want to draw a
thumbnail and you prefer
returning an image file URL
instead, this is quite simple.
You will receive the same QL
File Thumbnail Request and all
you have to return is a QL
Thumbnail Reply containing an
image file URL.
In this case, Quick Look will be
the one that will take care of
downscaling or upscaling of
thumbnail.
It will keep the aspect ratio of
your file so that the thumbnail
will [inaudible].
Let's now take a look at how
this works in code.
The only method you have to
implement is called provide
Thumbnail for request handler.
The first thing we do in this
example is extracting all the
parameters of the QL File
Thumbnail Request.
This means the file URL, the
maximum size, and the scale.
Out of these parameters, we
determine the context Size in
which we want to do our
thumbnail, just like in the
example we saw before.
After that, as we said, we need
to provide a drawing Block.
So here we create it and this is
[inaudible] that we'll have to
draw a thumbnail.
So drawing Block has to return a
success value to indicate Quick
Look [inaudible] it was actually
able to provide a thumbnail.
Finally, we create the QL
Thumbnail Reply out of the
context Size and the drawing
Block and we call the completion
handler with our reply as well
as [inaudible].
Here we [inaudible] nil because
we always want to provide a
thumbnail but if for some reason
you don't want to always return
a thumbnail for all the
requests, you will have to
provide an [inaudible] to
indicate quickly that you don't
want to provide a thumbnail for
this request.
If you'd like to return an image
file URL instead of drawing a
thumbnail file request, you
implement the same method but
you call the completion handler
with a QL Thumbnail Reply
containing the image file URL.
In this simple example, we just
return an image from our main
vendor.
After creating your extension,
you will of course want to see
your beautiful new thumbnails.
You can see them in any document
browser based app that displays
your files.
So here, what we can see on the
screenshot are thumbnails that
come from the extension of
Particles app but we are inside
the Recents [inaudible] Files
app but still we see them.
You now know how to build great
document-based applications
thanks to the UI Document
Browser View Controller and the
thumbnail extension.
So how can you improve the user
experience even further?
[Inaudible] UTIs, you will
likely want to be able to
provide previews that iOS can
display in any application.
We are now going to see how this
is possible thanks to the new
Quick Look Preview extension.
By default, Quick Look
[inaudible] set of file types.
This means that Quick Look by
default cannot preview your
custom file types.
But I have good news because
starting with iOS 11, you will
be able to provide previews to
Quick Look and extend the
capabilities of Quick Look
because we are opening Quick
Look to [inaudible].
We are opening QuickLook
[inaudible] so when you preview
extension which is system-wide,
this means that again any
application that uses Quick Look
will be able to display your
previews and you can also decide
to provide previews for
Spotlight items [inaudible] by
your application.
These previews will be visible
when peeking on Spotlight
[inaudible].
On the iPhone, that's
[inaudible].
Your previews will be
[inaudible] in Quick Look.
They will benefit from the full
Quick Look experience and the
previewed as part of QL Preview
Controller just like any other
[inaudible] preview.
Quick Look will take care of
displaying a loading spinner
while waiting for your extension
to return the preview.
Let's see the flow.
First, Quick Look notices that
it can't preview file by itself
but will ask for extension for
preview.
Your extension will take some
time to generate a preview.
Meanwhile, Quick Look displays a
loading spinner.
You don't have to take care of
this.
And when your extension is ready
to display the preview, you will
have to call the completion
handler in your code to notify
Quick Look that it can actually
display your preview.
Just like [inaudible] extension,
you can get started pretty
easily because, again, we have a
new template ready for you that
contains some sample code, a
storybook, and an Info.plist.
After creating your extension,
again you will want to head to
this Info.plist and edit it, add
edit it, add all the UTIs
[inaudible], sorry, all the UTIs
[inaudible] to the QL Supported
Content Types array.
Just like for the thumbnail
extension that you can only
provide previews for images you
own and export and that again,
iOS will check for UTI equality
and not UTI conformance.
If you wish to provide previews
for Spotlight items indicated by
your application, you will have
to set the QL Supports
Searchable Items key to yes.
Now let's take a quick look at
how we can [inaudible].
If you want to provide previews
for file, you will have to
implement the prepare Preview of
File at URL completion handle
[inaudible].
And all you have to do here is
load the file and call the
completion handler so that Quick
Look displays your preview.
You can call the completion
handler asynchronously which is
the case in this example.
If you wish to provide Spotlight
previews, you will have to
implement the prepare Preview of
Searchable Items identifier
query String, completion Handler
method.
The query String parameter can
be used to highlight any part of
the preview for the user.
This is the query String that
the user [inaudible] in
Spotlight before interacting
[inaudible] that you index with
your application.
Just like with file example, all
you have to do is prepare your
controller and call the
completion handler.
You can test your preview in any
application that uses Quick
Look, for example mail or
messages or in Spotlight if
[inaudible] which is the case in
this example.
We are here peeking on the
result index by the particles
app.
I'd like to finish this
extension tour with a few
performance recommendations.
When dealing with extension, you
always have to make sure to be
fast and in this case it's very
important.
You will have to load the
thumbnail quickly especially
think of a case for instance of
the user calling in the document
browser you want your thumbnails
to be there as fast as possible
for a good user experience.
For the Quick Look previews, you
will also have to make sure to
load your previews fast because
Quick Look is expected to be
quick.
Also not that you shouldn't have
any background job after calling
the completion handler.
Keep in mind that with extension
memory is very limited, so avoid
linking against two large
libraries and check for leaks.
Let's now recap quickly
everything we talked about
today.
First, we talked about some
document browser APIs.
We mainly talked about UI
Document Browser View Controller
and how you can make use of it
to create a great document-based
application.
You learned about its basic and
advanced features.
We then saw how you could make
your custom file tags
[inaudible] on iOS 11 thanks to
the new thumbnail and Quick Look
preview extensions.
Now let's take another look at
the requests we have received
from you in the past two years
and see how we addressed them,
so everything we talked about
today.
UI Document Browser View
Controller provides you with a
unified UI for file browsing.
The new local storage and other
cloud providers give you access
to files from other applications
in [inaudible].
The new file provider extension
allows you to have seamless
access to other Cloud Providers.
And iOS now has a deep
integration of custom file
types.
As usual, if you wish to have
more information about our
session, you can visit Apple's
website.
We invite you to check out these
related sessions, the Drag and
Drop session that was earlier
this week and the upcoming
What's new in Core Spotlight for
iOS and macOS and File Provider
Enhancement sessions.
You can also check out previews
Building Document-Based Apps
from 2017.
Thank you all for your
attention.
[Inaudible].
Bye.
[ Applause ]