Transcript
[ Music ]
>> In this session we are going
to tell you all about Quick
Look.
Welcome to previews from the
ground up.
My name is Raffael and I'm going
to present together with Maxime,
both software engineers at
Apple.
We are going to start with a
brief overview of what Quick
Look is.
Then we're going to show you how
to adopt the Quick Look Preview
Controller in your application.
And then we're going to explain
how to provide custom Quick Look
previews and custom thumbnails
for your own file formats.
Let's jump right into it, what's
Quick Look?
Quick Look is all about
previewing documents, it allows
you to present documents without
the hassle.
More precisely, Quick Look is an
iOS framework that provides
multiple core features to you as
a developer.
It allows you to preview
documents of several commonly
used file formats, to provide
custom previews for files of
your very own file format, and
to provide thumbnails to the
system for files of your own
custom file format.
Quick Look is in fact already
used by many of Apple's first
party applications.
For example, in files to present
your documents that you have in
the Cloud.
Or in Mail and Notes to preview
your attachments.
And in Messages to show your
pictures and videos that you've
sent.
So who is this session for?
Well if you want to know how to
present documents in your
application without having to
implement all the common
features the users are used to
you're in the right session.
You also might own a custom file
format which iOS doesn't support
natively and you want to make
sure that your file format is
properly handled by iOS with
custom thumbnails and previews
stay here if you want to learn
more about this.
And no matter if you're a
newcomer to iOS or if you
already have an app we're going
to guide you step-by-step.
By the way, if you haven't
checked it out yet you should
definitely take a look at last
year's session, Building Great
Document-based Apps in iOS in
which we have introduced the UA
document browser view controller
and also have covered the basics
of Quick Look preview and
thumbnail extensions briefly.
There's also going to be a
document browser one-on-one
session this year which we
highly encourage you to attend
if you're interested in file
handling on iOS.
Quick Look has been around for
quite a while already.
It's been introduced with the
iOS 4 SDK.
The main class you're interested
in is to [inaudible] preview
controller which is a view
controller to preview documents.
It uses the classic data source
and delegate pattern that you
already know from your UIKit and
other frameworks.
And presenting Quick Look with a
beautiful [inaudible] transition
couldn't be easier with the API
that we give you.
Why would you want to use Quick
Look?
Well if you have a similar use
case to files, mail or the other
apps we've shown you before
Quick Look is the perfect choice
for you.
Quick Look comes with everything
you need out of the box.
It supports the commonly used
file types and it provides that
native user experience that your
users are used to from other
first party iOS apps.
We made sure Quick Look has a
create performance on all
devices, so that all the
animations and gestures are
fluid.
And you might be dealing with
files from untrusted sources,
but don't worry we got your
back.
Quick Look comes with a
sophisticated security model
that keeps your application
safe.
Let's take a look at the
supported file types.
As you can see all the common
types are in here.
Media files such as images,
audio files and videos,
documents such as PDFs and
office files, but also zip
archives.
Previewing a zip archive lets
you look into the contents of
the archive and view the
contained files individually and
share them for example.
Now if your custom file format
is missing in this list don't
worry.
Last year we introduced a new
extension point for implementing
Quick Look preview extensions.
Preview extensions allow you as
a developer to create a preview
for files of your very own
custom file format.
We will cover this in the second
part of the session.
And this year with iOS 12 we
have also added support for the
new AR file format USDC, so with
just a few lines of code you get
a fully immersive augmented
reality experience in your
application.
Okay, now let's talk about user
experience.
For each of the file types shown
before we made sure that Quick
Look provides the best possible
preview on your mobile devices.
For example, when previewing
images you're able to zoom into
the images conveniently.
You're also able to close Quick
Look with a swipe down gesture.
In PDF documents you get a
sidebar with thumbnails for
easier navigation.
In spreadsheets you can switch
through the individual pages of
the document.
And in media files we show a
scrubber that allows you to go
back and forth and so on.
You get the idea.
So when you choose Quick Look
your users get all the gestures
they are used to from other
applications.
So what are some common use
cases for using Quick Look?
For example, you might want to
let the users zoom into photos
or you want to be able to flick
through a collection of photos
left and right.
You want to play audio or video
files without having to deal
with lower-level frameworks.
Or you want to present for
example a scrollable and
zoomable user agreement PDF to
the user.
Use Quick Look for this.
But Quick Look shouldn't be
misused, here's when not to use
Quick Look.
Quick Look is all about
previewing but doesn't provide
editing features.
So if you need to provide
functionality such as image
editing, PDF management or movie
trimming you need to choose a
different approach.
Similarly, if you need more
advanced playback control for
your videos Quick Look is
probably not the best choice,
you can use AVPlayer instead.
Quick Look is meant to be
presented full screen.
If you simply want to present an
image, a video or a document
embedded in your layout together
with other views surrounding it
you probably want to use
UAImageView, AVPlayer, WKWebView
or other kind of views instead.
Also note that it's not
supported to customize the view
hierarchy of Quick Look.
Please don't try to add views on
top of the previews the
navigational toolbar, this is
simply not supported.
So now that we've introduced
Quick Look, let's take a look at
how to actually make use of our
APIs.
If you want to present documents
to the user as a first step you
instantiate a new
QLPreviewController which is
basically a UIViewController.
Next, in order to tell the
preview controller which
documents to preview, you need
to assign a data source to it.
The data source is an object
that conforms to the
QLPreviewController data source
protocol.
We'll take a look at this in a
second.
And as a third and last step,
all you have to do is present
the view controller.
Let's take a closer look at how
the data source works.
Your data source has to conform
to the QLPreviewController data
source protocol.
This is a protocol that requires
two methods.
First, you need to return the
number of items that your
preview controller should
preview.
It should provide more than one
item the users will be able to
swipe left and right to flick
through the documents.
Next, Quick Look then will ask
you for one or more
QLPreviewItems depending on what
number you've previously
returned.
Okay what's a QLPreviewItem?
It's a protocol that acts as an
abstraction for your documents.
For Quick Look a preview item is
basically the URL, where to find
the document on disk and
optionally a title that Quick
Look will show in the navigation
bar.
The class representing documents
in your app needs to conform to
the QLPreviewItem protocol.
But by the way, NSURL already
conforms to the QLPreviewItem
protocol, so if you don't need
custom titles you can simply
return NSURL instances in your
data source without implementing
the protocol yourself.
Let's take a look at an example.
In this scenario our view
controller that presents Quick
Look acts as the data source of
the QLPreviewController.
Therefore, we let it conform to
the QLPreviewController data
source in an extension and we
implement the two methods.
Here we are using an area of
file URLs that acts as the
model.
We return the number of URLs
that we have in the number of
preview items in controller
method.
And then each URL respectively
referenced by the index in the
previewController controller
previewItemAt index method.
Okay we've set up our preview
controller and it knows what
files to preview, so we are
ready to actually present the
view controller.
There are two ways for doing
that.
You can either present the
preview controller modally on
top of the current context or
you push the preview controller
into a UINavigationController.
Both ways work great and you
need to decide what fits best in
your situation.
To present it modally you do
what you do with any view
controller you call present.
Here's an example of what a
modal presentation can look
like.
If you have a
UINavigationController and
prefer to push the preview
controller instead you use
pushViewController.
This is what it looks like.
The QLPreviewController class
provides a few more methods that
I would like to highlight.
First, if you want to know if
Quick Look is capable of
previewing a certain document
use the canPreview item class
method, this will return true if
the document matches any of the
supported default file types or
if there is a preview extension
available that can handle the
file.
The data source we've already
covered.
Reload data reloads the list of
documents your preview
controller should present.
If this list ever changes while
the preview controller is
currently presented use this
method to trigger a reload.
If you need to obtain the index
of the currently previewed item
in your list of preview items
remember the user can swipe left
and right to switch to a
different one, use the current
previewItemIndex variable.
This is both a getter and a
setter, so if you want Quick
Look to start with a particular
item when it's being presented
set the index to the right
value.
Last but not least, preview
controllers also have a
delegate.
Let's take a look at the
QLPreviewController delegate
protocol now.
If you assign a delegate to your
preview controller you get more
ways to control how Quick Look
behaves.
It also lets you react to Quick
Look presentation events.
Note that all of the methods in
the QLPreviewController delegate
are optional.
You don't have to implement them
and in fact you don't even have
to assign a delegate at all.
The protocol hosts a bunch of
methods you can implement.
The first two methods lets you
react to the event that Quick
Look is about to be dismissed by
the user and also that the
dismissing is now complete.
You might want to use these
methods to update the view
controller that is presenting
Quick Look right now.
Next, the preview controller
should open URL for item method
allows you to prevent Quick Look
to follow a link contained in
previewed documents.
With this method you can for
example prevent the user from
leaving your app when tapping a
URL or a phone number contained
in a PDF.
And last but not least, as
promised before the
QLPreviewController delegate
protocol also provides API to
get a smooth zoom animation when
Quick Look is presented and
dismissed.
With these methods a thumbnail
that is on screen in your user
interface can transition into a
full Quick Look preview when
tapping it.
Imagine an email attachment or a
photo inside a conversation view
which you can tap to show it
full screen with Quick Look.
We made it super easy for you to
get this cross fade zoom
animation in your application.
If you implement one of the two
approaches in your delegate
Quick Look will ask for the
information that is needed for
performing the zoom.
This is basically the
rectangular area the animation
should start from when
presenting or end in when
dismissing Quick Look.
Either you provide the frame and
the image of the thumbnail or
and this is the preferred way of
doing it, you use our mode and
method in which you simply
return the thumbnail as a view.
With this approach you don't
have to worry about coordinates
Quick Look will do all the heavy
lifting for you.
And this is what it can look
like.
Note how the thumbnail
transitions into the full-screen
Quick Look preview.
All right now it's time for a
demo in which we would like to
show you what we've just
covered.
Okay, here's an iOS project and
instead of talking about it
let's just press the play button
to see what we've already
prepared and what we are dealing
with here.
We are calling this Wildlife
Explorer and it's a very simple
app.
It basically displays a grid of
photos and each of these photos
that we see here acts as a
thumbnail for what's behind it
once you tap it.
For example, tapping the
elephant should show a large
photo of the elephant in full
screen and tapping the giraffe
should preview an entire PDF
about all sorts of giraffes.
Right now we can't do anything
else than just looking at it,
tapping won't do anything yet so
let's fix this.
Now this application is fairly
simply structured.
For displaying the grid of
photos we use a
CollectionViewController.
When initializing it we obtain a
list of URLs of documents that
are bundled with the application
like the elephant we've just
seen.
We use that list to initialize
what we call a document data
source.
This object serves as the model
for the collection view in the
implementation of the
UICollectionViewDataSource
protocol.
Here we return the number of
documents we have just gathered
and then create a cell for each
of the documents with a
thumbnail as the image of the
cell respectively.
And that's pretty much the core
of the application so far.
Now let's add what we've talked
about before.
When tapping a cell we would
like to show Quick Look with the
right document.
We've already made sure that we
have a method that is called
when the user has just tapped a
cell.
To show Quick Look we create a
new QLPreviewController in here
and configure it.
We create a new controller, we
assign the document data source
to it as the data source and
then make sure Quick Look shows
the correct preview when it's
presented by setting the right
CurrentPreviewItemIndex.
Great, now Xcode is already
complaining about our new code,
it doesn't know
QLPreviewController yet.
We need to import Quick Look
first and therefore we return to
the top of the file and import
Quick Look.
Done. The next thing Xcode
complains about is the data
source.
The document data source that we
assigned to the new preview
controller doesn't seem to
conform to the
QLPreviewController data source
protocol yet which we have
talked about earlier.
To fix this let's switch to the
implementation of the document
data source.
The document data source is a
very simple kind of object, it
simply owns an area of URLs so
far.
We need to add the
QLPreviewController data source
protocol to the list of
protocols that this class
implements.
Next, we implement the missing
methods.
As you can see the way we use
the document data source here is
very similar to the way we use
it for the collection view.
In the numberOfPreviewItems
method we return the number of
URLs that we have gathered
before from our documents
folder.
And then Quick Look asks for the
individual QLPreviewItems and we
return the right URL referenced
by the index.
Great, the data source has been
properly set up so we can go
ahead and actually present the
preview controller.
Therefore, we return to the
didTapCollectionCell method and
add the missing method call.
Let's check out how this looks
like.
All right we are back in grid
and now when tapping a cell
Quick Look appears displaying
the right document in full
screen.
Note how easy it is to present
images and even PDFs in full
screen with all of the gestures
that you are used to.
We can zoom into the document
with two fingers, we can select
text, and even copy it.
And once we are done we can use
a pinch gesture to dismiss Quick
Look again.
So what we are using here to
present Quick Look is a modal
presentation style.
As I've explained earlier, we
can also present Quick Look with
a push animation.
Therefore, we simply tell the
application's navigation
controller to present the
preview controller by pushing it
on top of the current one.
Let's take a look.
As you can see, this is a
different style of presenting
Quick Look and it works just as
fine as presenting it modally.
Okay Quick Look works and now
the last thing I would like to
show you is how to use the Quick
Look delegate in order to get a
beautiful zoom animation when
tapping a thumbnail in our grid.
First, we switch back to the
modal presentation style which
is needed for the zoom
transition to work.
Then we need to assign a
delegate to the preview
controller and in this case, we
assign self.
However, self doesn't conform to
the QLPreviewController delegate
yet, so let's add it to the list
of protocols.
And now as the last step we
implement the magic method which
tells Quick Look which view to
use as the source for the zoom
animation when it is about to be
presented.
As you can see, we are using the
image view of the most recently
tapped cell which we keep a
reference of and return it to
Quick Look.
That's literally all we have to
do to make the zoom animation
work.
Quick Look will call this method
when it's presented and when
it's dismissed.
Let's try it out.
Now when we tap a thumbnail
notice how the thumbnail is
animating to the full-screen
preview.
Also observe no matter how we
dismiss the preview it
beautifully transitions back to
the right origin.
Great, that's it for the demo,
back to the slides.
And now I would like to hand it
over to Maxime who is going to
tell you all about previews and
thumbnail extensions.
>> Thank you Raffael.
So as you have seen, Quick Look
makes it super easy to add a
powerful previewing feature to
your app.
But there is more to talk about.
The first thing I want to show
you is how to extend Quick
Look's previewing capabilities
by providing a preview for your
own file format.
We have listed the file types
that Quick Look supports
natively before.
However, since iOS 11 this list
can be extended by bundling a
preview extension with your iOS
app which allows you as a
developer to provide previews
for your custom file formats.
You should provide a preview if
you're in a custom fil format
and you'd like this one to be
previewed by Quick Look just
like any other native type.
File types that are meant to be
shared are usually good types to
create an extension for,
especially if you want your
users to preview the content
easily after receiving a file in
an app like Mail, Messages or in
a Note for instance.
And then everything works
together and your application
that is using a
QLPreviewController with a file
that is not natively supported
will benefit from your preview
extension.
Here is an example of what you
can achieve thanks to a preview
extension.
We have built a sample app that
can be downloaded from Apple's
website that allows one to
create customized and interact
with Particles.
Since we wanted to share our
cool Particles to other users we
created a new file format, the
particles file format.
Each file represents a particle
system and you can configure all
sorts of [inaudible] systems.
Now let's say you share a
particles file with your
friends.
When previewing them in messages
or as an email attachment for
instance [inaudible] get to see
is a blank screen, that is
certainly not what we want.
But by implementing your preview
extension for our particles file
format it will replace that
blank screen with a beautifully
rendered three-dimensional
interactive particle system.
How good is that?
I am sure you now want to learn
how you can make your own
preview extension for your file
formats.
First, you will need to add a
new target in your existing
application project.
To do so you will have to select
the Quick Look Preview Extension
template in Xcode.
After that several files will be
generated for you by Xcode.
The PreviewViewController class
with a basic implementation.
This is where you will have to
add code for your preview.
The storyboard that has the
PreviewViewController as its
entry point.
And an Info.plist that's the
first thing you will want to
edit.
Let's take a closer look at it.
To get started the attribute we
are the most interested in is
named QLSupportedContentTypes.
This is the one that is
highlighted on the screen shot.
This is an array in which you
list all the file types for
which your extension can provide
previews.
Please note that you can only
provide previews for UTIs you
own and export.
When Quick Look can't natively
preview a file type it will make
use of the content types added
to this array and select an
extension that can handle
previewing it.
So make sure to list all file
types [inaudible] extension
support.
Let's see how we achieve this
with our Particles app.
As you can see Particles
declares and exports a new
particles file type.
Its identifier is [inaudible]
example.applesample
code.particles.particles.
Since we wanted our extension to
support particles previews we
added this identifier to the
QLSupportedContentTypes of its
Info.plist.
By the way, if you're interested
in UTIs you should check out the
Documents Manager session of
this year.
When a new preview has to be
generated for a file type
[inaudible] Quick Look will
create a new
PreviewViewController instance
and calls it
preparePreviewOfFile at URL
completionHandler method.
This method is part of the
QLPreviewingController protocol
and is mandatory to provide
previews for a file.
Quick Look will display
[inaudible] while waiting for
your extension to be ready to
display the preview.
All you have to take care of is
loading the contents of your
preview and calling the
completion handler as soon as
your extension is ready.
All right that's it for the
preview extensions, let's go one
step further.
Similarly to previews you can
also provide thumbnails for
files of your own file format.
Let's talk about Quick Look
thumbnail extensions.
A thumbnail is an image of a
limited size that represents the
contents of a file.
There is throughout iOS and
macOS to allow users to identify
files officially without having
to open them to the file
contents.
For instance you can see on the
screenshot how iOS makes uses of
them in the file tap.
iOS can generate thumbnails for
different file types, images,
videos, PDFs, text files, and
USDZ files.
Now you may have noticed the
blank icons on the left.
This is because these are
particles files and iOS doesn't
know how to generate thumbnails
for this file natively.
But don't worry we are going to
show you how to create a
thumbnail extension that you can
use to improve this situation
for your custom file types
easily.
Look at how great these
thumbnails look for particles
files thanks to the thumbnail
extension we have added to our
app.
Thumbnails provided by this
extension appear in the Files
app, as well as in any
UIDocumentBrowswer
ViewController-based app.
They also appear in the Quick
Look list, that you can see when
tapping the list button when
previewing multiple files in
Quick Look.
If you have custom file types
that the user can share and
interact with you will likely
want to provide a certain
extension with your app.
Let's now see how you can do so.
Creating a thumbnail extension
is as just creating a preview
extension.
To do so add a new target in
your existing application
project and select the Thumbnail
Extension template.
Xcode will generate for you two
files, the ThumbnailProvider
class with a basic
implementation.
This is where you will have to
add the code that takes care of
generating thumbnails.
And an Info.plist this is just
like for the preview extension,
the first thing you will have to
edit after creating your
extension.
As in the Info.plist of the
preview extensions the
Info.plist of the thumbnail
extensions have a
QLSupportedContentTypes array
that needs to be filled with the
content types that your
extension supports.
So make sure to include in
QLSupportedContentTypes all the
content types for which your
extension can generate
thumbnails.
After setting up your extension
you will be able to start
implementing your
QLThumbnailProvider subclass.
You have two ways to provide a
thumbnail for a file.
You can [inaudible] use it
CoreGraphics or UIKit
[inaudible] techniques or you
can return an image file URL.
You will have to override the
provideThumbnail for request
handler method in your
QLThumbnailProvider subclass.
We extensively covered this part
of the Quick Look API in your
session for WWDC 2017, Building
Great Document-Based Apps in iOS
11.
So if you'd like to provide
thumbnails for your custom file
types I highly encourage you to
check it out.
In a nutshell, you will need to
make use of the parameters
contained in the
QLFileThumbnailRequest of the
method.
The URL of the file, the maximum
and minimum sizes of the
thumbnail, and its scale.
For each thumbnail request the
API expects you to create a
QLThumbnailReply object.
This object will have to take
care of generating the
thumbnail.
You will have to provide it to
Quick Look through the
completion handler of the
method.
All right let's see all of this
in action it's demo time.
Let's start by taking a look at
how things look like after
installing the Particles app
without any Quick Look
extension.
All right we don't have any file
yet, let's create a new one by
pressing the + button.
What you can see here is the
particle editor.
Let's create a file particle
system, we change the color a
bit, and save the document.
Well as you can see we don't get
to see the beautiful particle
system we just designed.
[Inaudible] of that by adding a
thumbnail extension to our
application.
Now let's save the file to a
[inaudible] and see how the
preview looks like in Quick
Look.
All right let's open the file
format.
All we see is a blank screen, we
can do better, let's improve
this too.
Let's switch to Xcode and
implement a preview and a
thumbnail extension.
We already have an existing
project containing the extension
setup.
We are going to use these as a
starting point and add the two
extensions.
As mentioned previously we need
the Info.plist of our extensions
to be configured so that the
system knows we are able to
provide previews and thumbnails
for particles files.
So Particles app defines its own
file format in the exported UTIs
section of the application
target.
We need to configure the
extensions to use that UTI in
the Info.plist.
As you can see the
QLSupportedContentTypes of the
Info.plist of the preview
extension does contain the
identifier of the UTI of the
particles file format.
And this is also the case of the
Info.plist of the thumbnail
extension.
So the only thing left to do is
to actually implement these
extensions.
Let's start with the preview
extension.
As mentioned in the presentation
we need to implement this
method, preparePreviewOfFile at
URL completionHandler.
Our main app Particles already
has a view controller class
which [inaudible] the particle
system on screen.
We are going to reduce
[inaudible] controller in our
extension.
We are going to create a helper
method that will take care of
loading such a view controller
and adding it to the view
hierarchy.
As you can see present
particleViewController for a
document simply creates a
particleViewController and
passes it to the document it
received so that the
particleViewController can
render the particles that the
document represents.
We still need to call this
method from preparePreviewOfFile
at URL, so let's do it.
We first create a document that
is a subclass of [inaudible]
document.
We open it and once it is open
and usable we call our helper
method that will displace a
particleViewController.
Finally, we may not forget to
close the completion handler to
notify Quick Look that our view
controller is loaded and ready
to appear on screen.
Our preview extension is now
ready.
Let's implement the thumbnail
extension.
All we have to do here is to
implement the provideThumbnail
for request handler method.
So request provides several
properties that you need to
consider when rendering a
thumbnail.
In this example we will make use
of the file URL as the maximum
size of the thumbnail.
Note that there are also a scale
and minimum size properties, but
in the case of our particle
system we don't use them.
We then create a drawing block
that we are going to provide
later [inaudible] completion
block.
In this case, we call the helper
method that will take care of
drawing the thumbnail,
drawThumbnail for fileURL,
contextSize.
We are going to implement this
helper method in a second.
You may have noticed that our
drawing block returns a Boolean,
this flag indicates if the
thumbnail was successfully drawn
or not once this block will be
used to generate the thumbnail.
Let's now see how we draw our
particle thumbnails.
To draw the thumbnails we make
use of the URL of the file and
of the size of the context we
will draw into.
In this case, we all know the
maximum size of the thumbnail
request since we can generate
particle thumbnails of any size.
Our method first creates a
document that represents the
file and attempts to open it.
If this fails it returns false
to indicate that it could not
generate a thumbnail.
After opening the file it then
creates a particleViewController
that will be used to render the
particles file.
Then it takes a snapshot of the
particleViewController and uses
it to draw the thumbnail.
We close the document before
returning true to indicate that
we successfully have generated a
thumbnail.
Now that we have [inaudible] to
generate thumbnails we need to
create our [inaudible] reply.
We created out of the context
size, which in this case is the
maximum size and the drawing
block.
Also we have our reply object we
provided through the completion
handler [inaudible] parameter,
which in this case is new since
we always add them to draw
thumbnails for particles
documents.
If [inaudible] while drawing it
the thumbnail block success
value will indicate it, so the
thumbnail can be discounted
later.
We are finally all set, let's
run this code and see how this
looks like.
Wow. We now see a beautiful
thumbnail for our fire particles
file.
This looks so much better than
before.
Now let's check our preview
extension.
Okay.
So we are in Note and Quick Look
is still showing the blank
screen from the previous time we
tried to previewing your file.
Let's dismiss Quick Look and
present it again.
We now see our great particles
preview, note how easy it was to
make our custom file format
[inaudible] in iOS.
And that's it for the demo.
So what have we learned today?
First, we have shown you how
easy it is to add powerful
previewing capabilities to your
application by using the
QLPreviewController of Quick
Look.
Then we have taken a look at
Quick Look's extension points.
Preview extension allows you to
have your custom files preview
by Quick Look just like any
native file type.
While the thumbnail extension is
used to provide thumbnails of
your own file types to iOS when
needed.
Together these extensions make
your file formats first-class
citizens in iOS.
And that's it for this Quick
Look session.
If you would like to have more
information you can check out
Apple's website.
Thank you for your attention.