Transcript
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
>> RICKY MONDELLO: Good
afternoon everyone.
Welcome. Before we get
started I just want
to get a little feel
for the crowd.
Little show of hands.
Please raise your hand
if you have an app that's
currently being distributed
on one of the App Stores.
That's a lot of you.
Welcome, you're at the
right place, it's WWDC.
And how many of you are just
learning how to write iOS, Mac,
or Watch apps now and
just getting started?
A few of you.
Welcome to you as well.
And of all of those apps that
you've built or you're thinking
about building, how many of them
are a dedicated web browser?
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
about building, how many of them
are a dedicated web browser?
Okay. A few of you.
Not that many.
But how many of you have a
miniature web browser that's
within your application that you
show whenever a user taps on --
oh my God, all the hands are up.
Yes, my name is Ricky Mondello,
I'm an engineer on the Safari
and WebKit team, and my goal for
the next half hour is to get all
of you out of the business
of writing those
miniature web browsers.
(Cheers and applause.)
>> RICKY MONDELLO: I'm going
to show you how you
can use either Safari
or the new Safari View
Controller to give you more time
to focus on the parts
of your app
that are special to your app.
And to give your users features
that they already
love from Safari.
So if you're ready,
let's get started.
At the center of this
topic is web content.
And web content comes in all
sorts of different shapes
and sizes, but for today's
discussion I'm going to lump it
into two different buckets.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The first bucket is
content within your app
that just happens to be written
in HTML, JavaScript, and CSS.
It's content that
you own or content
that you're giving a
special presentation to.
The important part, is that
it's not content that looks
like a traditional web browser.
It's not when a user is
browsing on a website.
Which brings us to
the second case.
When a user taps a link
in your app and you want
to show them a view
that's kind of like Safari,
so they can do some
short-term browsing.
This session is primarily
focused on the second use case.
We're going to see
how both Safari
and Safari View Controller
can add years of features
and polish to your applications.
But before we do
that I want to touch
on that other use
case real quick.
If you're using web content
within your app but in a way
that doesn't look
like a traditional web browser
you might be using WKWebView
or UIWebView, but WKWebView
is the preferred tool
to do this; it's your friend.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to do this; it's your friend.
It was introduced in
iOS 8 and OS X Yosemite,
and basically it's just a
rectangle around web content.
You load a page into it,
you can evaluate JavaScript
and get a result
from that JavaScript
against the current page.
You can modify navigations
or outright block them.
And it's up to you to add
your own user interface.
Back, forward buttons,
communicate progress, et cetera.
And new on iOS 9 and OS X
El Capitan we've heard your
feedback and we've
incorporated some of the pieces
of WKWebView that were missing.
First and foremost, you can
securely loadFileURLs now.
(Applause.)
>> RICKY MONDELLO:
You can also loadData,
say literal HTML string
that you wanted this way.
No need to spin up a server.
And if you like, you can set
your own customUserAgent string.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And if you like, you can set
your own customUserAgent string.
(Applause.)
We've also added a new API to
manage the data that is stored
by websites like cookies
and caches and other stuff.
And it's called
WKWebsiteDataStore.
It's a read/write property
on your web view's
WKWebViewConfiguration.
And with the data store you
can remove data by its type
or you can do something like
remove all data that was added
in the last hour,
which is pretty cool.
And because the property,
the store on your configuration
is writable you can replace it
with a configuration
that's non-persistent
which is exactly how you'd go
about implementing
private browsing.
So for web content that's
in your app that you own,
you control, or you're
customizing,
WKWebView is the right
tool for the job.
And in iOS 9 and OS X El Capitan
we've given you more flexibility
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And in iOS 9 and OS X El Capitan
we've given you more flexibility
than ever before.
But if you've have been sitting
here thinking: I don't need
that flexibility, I don't want
to evaluate JavaScript
against the page.
I don't need to modify
navigations.
I don't want to wire up my
own back and forward buttons,
then the rest of
this talk is for you.
We're going to talk about
how you can use either Safari
or Safari View Controller
to get a better experience
for your users and to give
you less code to write.
And your first option is
to simply delegate
the responsibility
of showing web content
to Safari itself.
And this is super easy to do.
You just call UIApplications,
openURL method
and iOS will switch away from
your app and over to Safari.
And new to iOS 9,
the system affordance
that you saw yesterday for
going back to the last app,
makes this a better
option than ever.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
makes this a better
option than ever.
It's more lightweight
than iOS 8 was.
(Applause.)
>> RICKY MONDELLO: And
delegating the responsibility
of showing web content
to Safari ensures
that users get a
first class experience
with that web content.
That's what Safari is all about.
But if you'd like to maintain
your app's current experience,
where users never even leave
your app, then you're going
to be interested in
Safari View Controller.
Let's take a look.
This is Safari View Controller
with the page from apple.com
with the web contents
slightly grayed out.
The first thing you'll
probably notice is
that Safari View Controller
looks a lot like Safari
with a few intentional
differences.
Safari View Controller's
job is to make it fast,
easy and enjoyable for users to
tap on a link within your app,
view a web page and press done
to go right back to your app.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Safari View Controller
eliminates distractions.
The URL field that you see
up there, it's read only.
You can't change it.
And there's just this one page.
No other tabs to
distract the user.
And with Safari in the name,
Safari View Controller
brings features
that your users already
love from Safari,
but now they're in your app.
Let's start off, first
and foremost Safari View
Controller shares cookies
with Safari and other
website data.
So what this means is if one
of your users is already logged
into a website in Safari, if
they tap a link in your app
and Safari View Controller comes
up they might still
be logged in.
But if they're not
logged in already,
we've got that covered too,
because Safari View
Controller allows you
to use Password Autofill to
fill any of the passwords synced
across all of the user's
devices with iCloud Keychain.
But before we go further it's
really important to point
out this is completely
safe for your users.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
out this is completely
safe for your users.
And the reason that
this is safe is
because we're giving your users
access to their credentials,
their user names and passwords,
but we're not giving access
to the host app to this data.
In fact, Safari View Controller
runs in a separate process
from your application.
Which categorically frees
you from the responsibility
of thinking about this
important sensitive user data.
That's on us.
All right, let's go
back to features.
When a user wants to have
something shipped to their home
or to their work they'll be able
to use Contact Card Autofill
to fill that information just
like they could in Safari.
And when it comes time to make
a purchase they'll be able
to fill their credit
cards as well.
And if one of your users comes
across an article that's
interesting, compelling,
but difficult to
read, she will be able
to use the Safari
Reader button in order
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to use the Safari
Reader button in order
to show a simplified cleaned
up version of that content.
Super great.
And new to iOS 9 in both
Safari and, of course,
in Safari View Controller,
Reader is customizable,
offering a bunch of themes
and some fonts to choose from.
So it's never been
easier to read articles
on the web exactly the way you
want to and your users want to.
From the share button you'll
find exactly what you expect.
You'll find the system
wide options for sharing
to social networks and you'll
also find the ability to add
to one's reading list,
but that's not all
that you'll find here.
Because alongside these
activities are activities
that your app provides to
Safari View Controller.
So if your app is
a social network,
you can have a dedicated
button in the share sheet
to share the current web
page to the social network.
Really cool.
And while we're on the
topic of customization,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Safari View Controller will
respect a custom tint color
that your app sets on it.
So in this case up on the slide
the tint color has been changed
from Safari's default
blue to orange.
This is a great way to let
users know which app they're
in when using Safari
View Controller.
This next feature is really
awesome and it's new to iOS 9.
It's called Content
Blocking -- go ahead!
(Chuckles.)
(Applause.)
>> RICKY MONDELLO: So the big
idea behind Content Blocking,
is that it's possible to add
something to the experience
of viewing a web page by
taking something away.
In iOS 9, any app can write
a description of web content
that Safari and Safari View
Controller should block
as the user browses the Web.
So lets take a look
at an example.
Here's a web page that has
some pretty cool content,
but in my case I
really don't like all
of the clickbait headlines
that are in that side bar.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of the clickbait headlines
that are in that side bar.
So if you install the right
content blocker you won't
believe what happens next.
(Chuckles.)
Oh, well, you will.
The content disappears.
(Applause.)
>> RICKY MONDELLO:
But that's not all
that Content Blocking
is capable of.
Content Blocking
can do a lot more
than hiding elements on a page.
You can out right block
loads from happening.
You can block all
images or all scripts
from a third-party domain that
you're not really fond of.
And all of the content
blockers that a user turns
on in settings will
apply in both Safari
and in Safari View Controller.
So what this means for you is
after you've switched
your miniature web browser
implementation over to using
Safari View Controller you won't
get any complaints that
your users' ad blocker is
not working.
Pretty cool.
So that's a bunch of features.
Let's talk about safety.
I mentioned a moment ago that
Safari View Controller runs
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I mentioned a moment ago that
Safari View Controller runs
in a separate process from your
app which frees you from a lot
of responsibilities of thinking
about important user data.
But when it comes to
browsing web content,
it's just as important to
have an expressive interface
that communicates
security to a user,
and Safari View Controller
does the same exact job
that Safari does in this regard.
First and foremost secure pages.
Safari View Controller
communicates the validity of SSL
to your users just
like Safari does.
But if the user is having
a bad day and they come
across a phishing page,
Safari View Controller will
also warn them about that
and ask them to turn around,
exactly the same way
that Safari would.
So to recap, Safari View
Controller has all the great
features of Safari itself.
The features that your
users already love.
Like the ability to fill their
passwords, have shared cookies,
clean up articles
with Safari Reader
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and in iOS 9, Content Blocking.
There are also a few
other minor things
like correctly communicating
progress while progress is
loading with a nice
progress bar.
And showing informative
error pages
when something goes
wrong during a load.
Your miniature web browsers
may or may not be doing all
of these things, but with Safari
View Controller it doesn't have
to, because adopting it will
add years of Safari features
and polish to your
apps and future years
of polish in the future.
I'm happy to say that adopting
Safari View Controller is
really easy.
Let's take a quick
walk through the API.
In code, Safari View
Controller is known
as SFSafariViewController.
It's part of the Safari
Services Framework.
And as you might have
guessed it's a subclass
of UIViewController.
It has a delegate which
I'll get to in a moment,
and initializer which
takes a URL.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and initializer which
takes a URL.
This is the URL of the web
page that your user tapped on,
the web page that
you want to show.
Let's look at that
delegate real quick.
The first method in the delegate
is how you can provide your own
custom activities
to the share sheet
when the user taps
on the share button.
And the second delegate method
is called when the user taps
on the done button, when
they're done browsing.
You're going to want to
implement this in order
to dismiss the View Controller.
Taken all together it's
a pretty simple API.
And to show you just how
powerful this simple API can be
and how many lines of code it
will remove from your apps,
I'm delighted to invite
my colleague Yongjun
to the stage for a demo.
Yongjun.
>> YONGJUN ZHANG:
Thank you, Ricky.
Hi, everyone.
My name is Yongjun.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
My name is Yongjun.
I'm a Safari and
WebKit engineer.
I don't know about
you, but I really want
to have some pizza today.
So I'm writing an app to
find pizza stores around me.
Here it is.
I call it pizza finder.
I got a list of pizza stores.
If I select the first store, I
got the phone number, address,
I also get a link to the
website of the store.
My task now is to make
my app show the website
so I can know more
about a store.
As Rick mentioned we
got three options.
Option one, use openURL and let
Safari open the website for us.
Option two, you establish
a web view
and make our own browsing app.
And option three, use
Safari View Controller.
I am going to try
option one first.
So I go to my Xcode project.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And here in my store view
controller I got a function
here, showStoreWebsite.
I just need to drag one line
of code UIApplication, openURL.
This will let Safari
open the URL.
Lets test it.
I run the app and select
the first store, left click.
Now, Safari opens
the website for me
and I can see this
page has a Reader.
And if I try to order
pizza, I got my user name
and password autofilled.
So I must have been
to this site before
and maybe I ordered
a pizza before.
Now I'm in Safari.
What I really want is my users
to always stay in my app.
I don't want them to
switch to Safari just
for visiting one
or two websites.
Because they can get distracted
and might not come
back to my app later.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and might not come
back to my app later.
So I really need a
browser in my app.
I'm going to try option 2
now to make my own browser.
So first thing I want to do,
I want to go back to my app.
So as we know, if we have
some web content in the app
and if the web content happens
to be my UI or part of my UI,
WKWebView is the best
tool for that job.
In my case I wanted
to use WKWebView
to load web pages
certainly, but I also want
to have some UI around that.
For example, I want
to have a URL bar
on the top to show the URL.
I also would like to have
a toolbar in the bottom
to do back and forth navigation.
WKWebView is a very rich
API, it provides a number
of delegates I can use to listen
to page load events
or navigation events.
I can use this delegate
to drive my UI.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I can use this delegate
to drive my UI.
So to save us some
time for this demo,
I already have a single browser.
Let's take a look.
So in the Xcode project I
switched to another tab.
I wrapped my simple browser
into one view controller.
And in the middle
I got WKWebView.
On the top I got
the navigation bar.
I use the navigation bar's
title to show the URL.
In the bottom I have a back
and forth button to do back
and forward navigation.
Now this is a simple class.
It has about eighty
lines of code.
It took me about one hour.
I believe we can do better.
But anyway, let's
test this browser.
So I go back to my
store view controller,
remove this line we just added
and drag a couple lines here.
What I am doing now is I
load my view controller
from the story board assigned
a URL to it and presented it.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
from the story board assigned
a URL to it and presented it.
Now let's take a look.
I run my app.
Select the first store
and tap the link.
This is my browser.
It runs in my app.
I don't have to switch to Safari
to visit this site anymore.
That's good.
The URL bar is actually
grayed out.
So it won't be distracting.
But also notice when I drag the
page I don't have the dynamics
of Safari's UI.
And this page doesn't
have a Reader.
It will be harder
for me to read now.
And if I try to order pizza,
I don't have my user name
and password autofilled.
So it will be harder for me
to order pizza now especially
when I'm hungry, and impatient,
and I don't have my password.
(Laughter.)
>> YONGJUN ZHANG: So, what
I really need is some simple
and easy way to show
a website from my app.
I don't want to spend my time
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I don't want to spend my time
to implement missing
features like progress bar.
Even though I want to spend time
there are some features I will
never get to.
For example, Password Autofill.
I would never get users'
passwords for this website.
Luckily in iOS 9 we have
a Safari View Controller.
Let's take a look.
So to take Safari View
Controller into use,
first thing I need to do is
import Safari Services Framework
and then I need to make
my view controller conform
to
SFSafariViewControllerDelegate
protocol.
In the code, let's go
back to showStoreWebsite.
I don't need my browser
anymore, so I remove that.
And just drag a couple
of lines here.
What I'm doing now
is I instantiate my
SafariViewControler object,
gives delegate and present it.
Before we test it I also need
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Before we test it I also need
to implement
safariViewControllerDidFinish,
when the user taps
the done button,
and we can dismiss
the view controller.
Since we are here we don't
need our browser anymore,
so we can delete the whole
thing, move to Trash, yes.
Eighty lines of code
down and one hour saved.
Let's run again.
Select the first store.
Look! I have Safari in my app.
So I got Reader back.
The same dynamics as
Safari, and if I try
to order pizza now I have my
user name and password back.
As you see, with a couple lines
of code I have Safari in my app.
You can do that for
your app, too.
And the user would be
really happy about it.
Thank you.
(Applause.)
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
>> YONGJUN ZHANG:
Back to you, Ricky.
>> RICKY MONDELLO:
Thank you, Yongjun.
That is awesome.
So Yongjun just showed you
that although it's easy
to write your in-app web browser
in WKWebView, it's kinda hard
to get all of the details right.
He also showed you by
changing about seven lines
of code he was able to
replace the whole thing
with Safari View Controller.
You got to see how Safari
View Controller has features
like Password Autofill and
Reader and little touches
like the dynamics when you
scroll down on a web page.
When we started a few moments
ago I divided the world
of web content into two buckets.
The kind of stuff that
is custom within your app
that you're going to
use WKWebView for,
or actual websites when a user
taps on a link in your app
which you'll use Safari or
Safari View Controller for.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
which you'll use Safari or
Safari View Controller for.
But for a number of you
in the audience there's actually
a third use case for web content
that I would like to
talk about real quick.
That's doing Web-based
authentication using
web content.
So you've all probably
seen this before.
You're in an app
and the app wants
to use some third-party
website's accounts.
The app pulls up a web view.
You type in your user
name and password.
Log in. Then you accept
or deny the app's request
for the resource from
the third-party service.
You've all probably
done this before.
But one flow that
does this is OAuth.
I would like to walk through
at a high level exactly how
that works.
So in this flow there are
three different actors.
The first actor is an app.
Let's say that it's your app.
The second actor is a user.
Let's say it's one
of your users.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Let's say it's one
of your users.
And of course, there is
the third-party web service
that your app would like
to authenticate against.
So what will happen is in this
flow while the user is using the
app, presumably they'll tap
on a button somewhere
that says log in.
The app is going
to package the user
up with a token representing
what it wants
to request from the website.
And then, the app is
going to present, somehow,
a web page to log in against.
And the user will enter
their credentials,
log in and accept
or deny the request.
And then be sent
back over to the app.
At that point the website is
going to remember that token
and know whether it was
approved or denied for use.
And when the app
wants to connect
to that third-party service
in the future it will
do it using that token.
The major goal of a
scheme like this is
to protect a user's credentials
so that an app doesn't
have to remember them.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Instead the app gets a token.
That token can be used at a
later date to request resources
or the user could revoke
the token without having
to change their password.
This is great for users.
If you are implementing
this today,
you are probably using
UIWebView or WKWebView to do it.
But I'm happy to tell you
that Safari View Controller
is great for this purpose.
It's awesome for
web-based authentication.
One of the reasons it is awesome
for web-based authentication
is the security story.
It's just as secure
as Safari itself.
Because it runs out of process,
and Apple will never get
to see a user's user name
and password while
they're logging in.
And when it comes to
protecting a user's data,
one of the best ways to do
that is never to have access
to it in the first place.
That's our approach
whenever possible at Apple.
But it is also an
awesome user story.
Because since Safari View
Controller has access
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Because since Safari View
Controller has access
to a user's credentials, synced
across all of their devices
with iCloud Keychain, logging
in is going to be a breeze.
They may not need
to use Autofill.
They might already be logged
into that third-party
web service.
Simply put, users will be much
more likely to authenticate
against that third-party
web service,
if you are using Safari View
Controller compared to something
that you rolled yourself.
And I'm happy to say this
is also super easy to adopt.
It takes two steps.
The first is where you would've
used your own in-app browser,
just present an instance
of SFSafariViewController.
And once the user is
finished logging in
and the third-party web service
redirects back to your app
with the custom URL scheme
that you fed it, you can accept
that in your AppDelegate's
handleOpenURL method.
From there you can
inspect the response
and dismiss the instance
of SFSafariViewController
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and dismiss the instance
of SFSafariViewController
because you know that the
authentication is done.
That's it.
Two steps.
And you've replaced your in-app
browser with one that has all
of the user's user names
and passwords available
for Autofill.
Users are going to be delighted
by this and you are going
to have more users log into
that third-party web service.
Okay, let's cover everything
we talked about today.
Web content is everywhere
and it comes
in all sorts of shapes
and sizes.
But if you are using it within
your app in a custom way
where you own the experience
or you're customizing it,
WKWebView is the right
tool for the job.
You might still be using
the older UIWebView,
but WKWebView is modern
and includes the
modern JavaScript engine
that Safari itself
uses, it's much faster.
And now in iOS 9
and OS X El Capitan,
it has much more
flexibility for you.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
it has much more
flexibility for you.
If you'd like to learn more
about adopting WKWebView,
you can see last year's session,
Introducing the Modern
WebKit API.
But if your task with
web content is different,
if your task is to show a
website when a user taps
on a link, your use case and
needs are completely different.
In the past, you may have built
your own in-app web browser
with UIWebView or WKWebView,
but that's always had downsides,
it didn't have any
of the features
or state that Safari has.
And more likely than
not through no fault
of your own your app's
implementation was different
than that of other apps
that the user has installed,
which leads to a confusing
experience sometimes.
Your first option forgetting
out of the scenario is
delegating the responsibility
of showing web content
to Safari itself.
And the system wide
ability to go back
to the last app makes
this much better
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
to the last app makes
this much better
than it has ever been before.
But if you would like to
maintain your current user
experience where users
never leave your app,
Safari View Controller will add
years of features and polish
and features and
polish in the future.
For you, it'll mean having
more time to work on the parts
of your app that are
special about your app,
the parts that you
want to work on.
For your users, it will
mean having new features
like Safari Autofill, Safari
Reader and Content Blocking.
And while I still have your
attention I have a quick favor
to ask of you.
Please keep filing bugs
and feature requests,
when there is a gap between what
is and what you think should be
on the platforms that
you are developing on.
One of the reasons that Safari
View Controller exists is
because so many of you
told us that you wanted it.
And now that it does
exist as you're trying it
out over the next few months,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
out over the next few months,
please let us know how we can
make it more useful to you.
We really do appreciate
your feedback.
Okay. You can get
more information
about anything we covered
today at the usual places.
Or you can hit up
John Davis, the Safari
and WebKit Evangelist.
And we have some
related sessions
that you might be interested in.
To call out two in
particular, in Seamless Linking
to Your App you'll learn about
Apple's solution to the problem
of inner app linking
which involves taking
your website's URLs
and making them universal,
allowing them to open your app
on your users' iOS devices.
It's really cool.
In Safari Extensibility,
you'll learn to write one
of those content blockers
that I mentioned earlier,
that will apply to all pages
that are loaded in either Safari
or in Safari View Controller.
If you want help with anything
I covered today, the Safari
and WebKit Labs are
the right place to go.
And the first one is happening
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And the first one is happening
in about a half an
hour in Media Lab A.
Alright, thank you
so much everybody.
I hope you have a
fantastic WWDC.
(Applause.)