1
00:00:08,416 --> 00:00:09,326
>> Good morning.


2
00:00:10,266 --> 00:00:12,406
My name is Jon Lee.


3
00:00:12,406 --> 00:00:15,576
I am a manager on the
Safari and WebKit team.


4
00:00:16,356 --> 00:00:18,936
This is Session 614 and
you are here to learn


5
00:00:18,936 --> 00:00:23,126
about Implementing OS X Push
Notifications for Websites.


6
00:00:23,896 --> 00:00:28,526
You know, since iOS 3 and
OS X Lion, you've been able


7
00:00:28,526 --> 00:00:32,375
to integrate push notifications
into your native apps.


8
00:00:32,546 --> 00:00:34,576
And boy, do users love them.


9
00:00:34,876 --> 00:00:40,026
Apple has sent over 7.4 trillion
push notifications to users.


10
00:00:40,436 --> 00:00:43,096
So, clearly, users love
getting push notifications


11
00:00:43,396 --> 00:00:44,396
on their devices.


12
00:00:45,046 --> 00:00:45,706
So why is that?


13
00:00:45,706 --> 00:00:48,066
Well, I love push notifications


14
00:00:48,106 --> 00:00:51,246
because push notifications
gives me the information


15
00:00:51,246 --> 00:00:54,136
that I really want to know
about and the app tells me


16
00:00:54,286 --> 00:00:56,326
that information at
the best time it is


17
00:00:56,326 --> 00:00:57,986
for me get it which
is immediately.


18
00:00:58,116 --> 00:01:00,816
I don't have to open
up the app every time


19
00:01:00,816 --> 00:01:01,836
that I want to see an update.


20
00:01:02,406 --> 00:01:04,556
So, like for example I was
doing a dress rehearsal


21
00:01:04,556 --> 00:01:05,726
for this session last week


22
00:01:05,726 --> 00:01:08,326
and I was having some trouble
finding the conference room


23
00:01:08,326 --> 00:01:10,746
that I needed to be at, and so I
was trying to go through my mail


24
00:01:11,116 --> 00:01:13,576
to find those directions to
get to the conference room.


25
00:01:14,256 --> 00:01:17,296
And a friend of mine actually
texted me, telling me exactly


26
00:01:17,296 --> 00:01:20,366
where I needed to go and that
was great because I didn't have


27
00:01:20,446 --> 00:01:23,466
to be in the messages app in
that conversation in order


28
00:01:23,466 --> 00:01:26,256
to be able to know where
to go and for me to get


29
00:01:26,256 --> 00:01:27,416
to my dress rehearsal on time.


30
00:01:28,576 --> 00:01:34,386
Push notifications are fantastic
because even if I'm asleep


31
00:01:34,386 --> 00:01:37,166
or my phone's on silent, or
it's just not a good time for me


32
00:01:37,166 --> 00:01:38,106
to attend to my phone,


33
00:01:38,396 --> 00:01:40,076
I know that all those
notification are going


34
00:01:40,076 --> 00:01:41,686
to be grouped to in
Notifications Center


35
00:01:41,906 --> 00:01:43,846
and that place is
super easy to access.


36
00:01:44,126 --> 00:01:49,366
Anywhere on iOS, I can
just swipe down on my phone


37
00:01:49,696 --> 00:01:52,206
and I will see that
push notifications


38
00:01:52,376 --> 00:01:55,436
that were most recently posted
per app grouped together


39
00:01:55,696 --> 00:01:56,776
in Notifications Center.


40
00:01:56,976 --> 00:01:59,666
And this is great, not
just because I know exactly


41
00:01:59,666 --> 00:02:01,426
where to go to get
my notifications,


42
00:02:01,876 --> 00:02:04,456
but because seeing
the collection


43
00:02:04,456 --> 00:02:07,486
of those notifications
per app kind of gives me--


44
00:02:07,486 --> 00:02:09,346
it tells me a story, it
gives me some context


45
00:02:09,596 --> 00:02:11,246
about what the app
is trying to tell me.


46
00:02:12,336 --> 00:02:15,416
And if one of those
notifications are of interest


47
00:02:15,416 --> 00:02:18,046
to me, I can just swipe on
that notification or tap on it


48
00:02:18,256 --> 00:02:21,706
and iOS will take me
right back to the app


49
00:02:22,006 --> 00:02:24,376
and show me more details
about that notification.


50
00:02:24,596 --> 00:02:28,916
Finally, I love push
notifications because I get


51
00:02:28,916 --> 00:02:32,056
to fully control when
and how I receive them.


52
00:02:33,206 --> 00:02:35,536
So, like I want to install
a new app and I launch it,


53
00:02:35,866 --> 00:02:37,926
I don't automatically
get subscribed


54
00:02:38,136 --> 00:02:41,096
to that app's push
notifications, I get asked.


55
00:02:41,506 --> 00:02:45,226
And if I accept the invitation
to get those push notifications


56
00:02:45,636 --> 00:02:49,336
and the app ends up
sending me too many of them,


57
00:02:49,666 --> 00:02:51,096
I have so many different
choices.


58
00:02:51,096 --> 00:02:54,556
The app might provide me
some granularity over like


59
00:02:54,556 --> 00:02:56,836
when I want to receive
those push notifications.


60
00:02:57,066 --> 00:03:00,416
I could turn those
notifications off completely.


61
00:03:00,446 --> 00:03:02,056
If it's just that
the time isn't right,


62
00:03:02,056 --> 00:03:03,816
I can turn on "do not disturb"


63
00:03:04,136 --> 00:03:06,436
or as a last resort
I could delete


64
00:03:06,436 --> 00:03:07,886
or uninstall the
app on my phone.


65
00:03:09,486 --> 00:03:14,446
So, those are the reasons that I
love push notifications for all


66
00:03:15,596 --> 00:03:17,286
of the native apps
that you write.


67
00:03:17,956 --> 00:03:20,686
But I bet for many of you,


68
00:03:20,686 --> 00:03:24,496
not only do you have
amazing native apps,


69
00:03:24,766 --> 00:03:27,136
but you also have
amazing websites.


70
00:03:28,526 --> 00:03:33,486
So, new in Safari 7 on OS X
Mavericks, I'm really excited


71
00:03:33,486 --> 00:03:37,606
to announce that your website
can now send push notifications


72
00:03:37,606 --> 00:03:38,786
to your Mac users.


73
00:03:39,006 --> 00:03:41,896
This is great because just
like push notifications


74
00:03:41,896 --> 00:03:44,416
on native apps, your users
can fully control when


75
00:03:44,416 --> 00:03:46,946
and how they receive
their push notifications.


76
00:03:47,956 --> 00:03:52,456
And push notifications are just
the thing to put in your website


77
00:03:52,486 --> 00:03:54,586
to get users to return
to your website.


78
00:03:54,586 --> 00:03:57,026
And for those of you with
websites that are ad supported,


79
00:03:57,286 --> 00:03:58,346
that means real revenue.


80
00:03:58,346 --> 00:04:02,796
So, in this morning
session, I like to go


81
00:04:02,796 --> 00:04:03,466
through the four things.


82
00:04:04,026 --> 00:04:08,276
The first is to get some
background about notifications.


83
00:04:08,466 --> 00:04:13,186
The second is to learn how
it works behind the scenes.


84
00:04:13,326 --> 00:04:14,976
And third is to see how


85
00:04:14,976 --> 00:04:17,026
to implement push
notifications for your website.


86
00:04:17,026 --> 00:04:20,386
And the fourth is to talk
about some best practices.


87
00:04:20,966 --> 00:04:22,486
So, let's get started.


88
00:04:23,426 --> 00:04:26,056
One thing you may
not already know is


89
00:04:26,056 --> 00:04:28,386
that you actually can
send notifications


90
00:04:28,386 --> 00:04:33,276
to your websites on-- can send
notifications to your users


91
00:04:33,556 --> 00:04:36,656
on their desktop in
Safari 6 on Mountain Lion.


92
00:04:36,906 --> 00:04:39,436
They're called "Local Web
Notifications" and it's based


93
00:04:39,436 --> 00:04:43,456
on the specification by the W3C
Web Notification Working Group.


94
00:04:43,716 --> 00:04:47,396
Local Web Notifications and
Push Notifications are websites


95
00:04:47,396 --> 00:04:49,616
that are actually
quite different


96
00:04:50,286 --> 00:04:52,636
from like assistance
perspective.


97
00:04:52,906 --> 00:04:55,056
So when the user goes
to your web page,


98
00:04:55,116 --> 00:04:57,526
your web page will
contain some JavaScript


99
00:04:57,526 --> 00:05:01,036
that actually tell Safari
to send those notifications


100
00:05:01,036 --> 00:05:03,266
to the user's Notification
Center.


101
00:05:03,676 --> 00:05:07,336
Whereas with push notifications,
it's actually your server,


102
00:05:07,336 --> 00:05:10,346
which we call a Push Server
that send those notifications


103
00:05:10,346 --> 00:05:13,486
to a service that Apple controls
called Apple Push Notification


104
00:05:13,486 --> 00:05:14,626
Service or APNS.


105
00:05:15,316 --> 00:05:19,276
And APNS knows how to directly
connect to your user's Mac


106
00:05:19,656 --> 00:05:21,286
to send that push notification.


107
00:05:21,926 --> 00:05:26,136
But more than just from
like assistance perspective,


108
00:05:26,456 --> 00:05:29,786
local notifications
and push notifications


109
00:05:29,786 --> 00:05:33,686
on websites are actually
managed very differently for--


110
00:05:33,726 --> 00:05:35,406
on the user's Macs.


111
00:05:35,636 --> 00:05:40,436
For example, a web page can only
send a notification while the


112
00:05:40,436 --> 00:05:42,246
user is open to your website.


113
00:05:42,826 --> 00:05:45,926
Whereas with push notifications,
they can be send at any time.


114
00:05:45,956 --> 00:05:48,016
The user doesn't have
to be on your website.


115
00:05:48,206 --> 00:05:50,276
The user doesn't even
have to have Safari open.


116
00:05:51,256 --> 00:05:55,686
And likewise, if the user
exits out of your website


117
00:05:55,686 --> 00:05:58,146
or quit Safari, all
the local notifications


118
00:05:58,146 --> 00:05:59,736
that you posted actually
disappear.


119
00:06:00,166 --> 00:06:02,736
Whereas with push notifications,
it doesn't matter,


120
00:06:02,936 --> 00:06:06,156
they're always are right for
them for your users to see.


121
00:06:07,416 --> 00:06:09,966
Next, the notifications
that get shown


122
00:06:09,966 --> 00:06:12,596
on the desktop are a little--


123
00:06:12,596 --> 00:06:13,956
are presented a little
bit differently.


124
00:06:13,956 --> 00:06:18,096
For local notifications, because
it's Safari that's sending those


125
00:06:18,096 --> 00:06:20,926
notifications that actually
gets the Safari icon,


126
00:06:21,366 --> 00:06:23,376
and to give some more
detail about like


127
00:06:23,376 --> 00:06:25,876
where that notification
came from, we kind of put


128
00:06:25,876 --> 00:06:28,426
in the subtitle of the
notification, your domain name.


129
00:06:29,266 --> 00:06:31,386
A contrast that would
push notifications


130
00:06:31,386 --> 00:06:34,066
which actually use your website
icons, so there's no need


131
00:06:34,066 --> 00:06:37,636
to have kind of add this extra
information, they know exactly


132
00:06:37,636 --> 00:06:39,596
where that push notification
came from.


133
00:06:40,066 --> 00:06:43,686
Next, local notifications end


134
00:06:43,916 --> 00:06:47,476
up all being group underneath
the section for Safari,


135
00:06:48,686 --> 00:06:51,586
which means that like if the
user has a lot of websites open


136
00:06:51,586 --> 00:06:54,556
that are using local
notifications, they all end


137
00:06:55,086 --> 00:06:57,276
up getting kind of
shuffled together


138
00:06:57,276 --> 00:06:59,446
and your notification
might get lost in the mix.


139
00:07:00,276 --> 00:07:02,976
Contrast that with
push notifications,


140
00:07:03,216 --> 00:07:07,006
your website actually gets
its own dedicated center


141
00:07:07,266 --> 00:07:08,736
in Notification Center.


142
00:07:08,736 --> 00:07:11,066
So, you website is actually
treated just the same


143
00:07:11,066 --> 00:07:13,216
as your apps.


144
00:07:14,156 --> 00:07:17,216
Finally, when you click
on a notification,


145
00:07:17,666 --> 00:07:21,406
for local notifications,
it actually takes the user


146
00:07:21,406 --> 00:07:23,616
to the tab that actually
sent that notification


147
00:07:23,616 --> 00:07:27,206
that makes it front most
on the user's desktop.


148
00:07:28,596 --> 00:07:31,126
With push notifications,
since Safari might not have--


149
00:07:31,206 --> 00:07:34,676
be actually be open, clicking
on that notification is exactly


150
00:07:34,676 --> 00:07:35,916
like clicking on a link.


151
00:07:35,996 --> 00:07:39,486
And so, it just opens it up
to your website to a web page


152
00:07:39,486 --> 00:07:44,086
that provides more detail
about that notification.


153
00:07:44,936 --> 00:07:47,116
All right, so we just
talked about the differences


154
00:07:47,176 --> 00:07:48,946
between push notification--


155
00:07:49,006 --> 00:07:52,506
local notifications and push
notifications for websites.


156
00:07:52,876 --> 00:07:55,316
What about the difference
between push notifications


157
00:07:55,366 --> 00:07:58,646
for your native apps and push
notifications for websites?


158
00:07:59,236 --> 00:08:00,376
Well, you don't even
have to worry


159
00:08:00,376 --> 00:08:01,876
about memorizing this table


160
00:08:01,876 --> 00:08:03,336
because they're actually
the same.


161
00:08:03,766 --> 00:08:06,936
We've done everything we
can from your point of view


162
00:08:07,086 --> 00:08:10,756
as a developer to make
push notifications


163
00:08:10,756 --> 00:08:13,316
between your native app and your
website the exact same thing.


164
00:08:14,106 --> 00:08:17,176
So, just to go through it
quickly, for native apps


165
00:08:17,176 --> 00:08:20,506
and websites, your push
notifications can be delivered


166
00:08:20,506 --> 00:08:24,046
at any time, the Apple website
does not have to be open.


167
00:08:24,046 --> 00:08:27,606
The notification gets labeled
with your app or websites' icon.


168
00:08:28,256 --> 00:08:33,106
They get grouped together
based on their app or website


169
00:08:33,426 --> 00:08:36,076
to their own dedicated section
and Notification Center,


170
00:08:36,385 --> 00:08:39,066
and clicking on them opens up
the app or the website to take--


171
00:08:39,066 --> 00:08:41,956
to give them more detail
about that notification.


172
00:08:43,236 --> 00:08:44,996
So, my last thing
about background,


173
00:08:44,996 --> 00:08:48,126
I just kind of wanted to talk
about how the operating system,


174
00:08:48,126 --> 00:08:52,046
make sure that nobody else is
trying to forge anything you do


175
00:08:52,046 --> 00:08:55,626
and talking about basically
verifying your identity.


176
00:08:56,586 --> 00:08:59,936
And the best way to talk
about this with respect


177
00:08:59,936 --> 00:09:02,576
to push notifications
for website is


178
00:09:02,576 --> 00:09:04,196
to see how it works in apps.


179
00:09:04,726 --> 00:09:07,366
So, in order for user to
have push notifications


180
00:09:07,366 --> 00:09:09,096
for your apps, there are two
things that you need, right?


181
00:09:09,186 --> 00:09:13,176
You need your app that you've
submitted to the App Store


182
00:09:13,726 --> 00:09:15,916
and then you need your
server, your push server


183
00:09:15,916 --> 00:09:18,186
that actually sends
those push notifications


184
00:09:18,496 --> 00:09:20,096
to the user's devices.


185
00:09:20,566 --> 00:09:22,786
So how does Apple
know that the app


186
00:09:23,226 --> 00:09:25,356
and the server actually
both come from you?


187
00:09:25,736 --> 00:09:30,166
Well, Apple does this through
the use of certificates.


188
00:09:30,386 --> 00:09:33,126
With the private key of a
certificate that you get


189
00:09:33,276 --> 00:09:37,556
from the developer portal, you
can create a digital signature


190
00:09:37,556 --> 00:09:41,576
that only you can create and
that Apple verifies in order


191
00:09:41,576 --> 00:09:43,666
to make sure that you
are who you say you are.


192
00:09:44,526 --> 00:09:48,586
And when it's time to actually
send a push notification


193
00:09:48,586 --> 00:09:53,736
to APNS, your push server uses
a second certificate but also


194
00:09:53,736 --> 00:09:57,856
from the developer portal to
that-- to connect to APNS.


195
00:09:58,206 --> 00:10:02,616
And when those notifications
are sent, APNS knows that--


196
00:10:03,046 --> 00:10:04,516
from that certificate that you--


197
00:10:04,636 --> 00:10:07,936
that the push notifications
are coming from you.


198
00:10:08,586 --> 00:10:16,236
So together, Apple knows that it
is you that's controlling your


199
00:10:16,236 --> 00:10:20,706
user's experience with your
app and its push notifications.


200
00:10:21,856 --> 00:10:24,896
So now, what about
website identity?


201
00:10:25,226 --> 00:10:28,066
You don't bundle your
website together, right?


202
00:10:28,066 --> 00:10:29,756
Like anybody can
create a website


203
00:10:29,756 --> 00:10:31,576
and you don't submit
your website


204
00:10:31,576 --> 00:10:33,276
to a Apple Website Store.


205
00:10:33,666 --> 00:10:37,296
So how does Apple
know that it is you


206
00:10:37,296 --> 00:10:39,306
and that you are authorized


207
00:10:39,306 --> 00:10:40,936
to actually send
push notifications?


208
00:10:43,576 --> 00:10:48,246
Well, what we do is we ask your
web server to create an identity


209
00:10:48,246 --> 00:10:51,726
that represents your website and
we call that a "push package".


210
00:10:51,966 --> 00:10:56,126
And it's that push package
that you sign using something


211
00:10:56,126 --> 00:10:58,436
that we call a website
Push Certificate


212
00:10:58,436 --> 00:11:01,796
and you create your digital
signature and this signature


213
00:11:01,796 --> 00:11:03,616
and the push package
gets sent to Safari


214
00:11:03,616 --> 00:11:06,806
and Safari will actually
do that check to make sure


215
00:11:06,806 --> 00:11:10,186
that you are authorized to
send push notifications.


216
00:11:10,866 --> 00:11:14,306
And then when it's time to send
those notifications to APNS,


217
00:11:14,836 --> 00:11:16,746
you use that exact
same certificate


218
00:11:16,746 --> 00:11:17,986
to connect to the service.


219
00:11:17,986 --> 00:11:20,676
So it's actually easier to
implement push notifications


220
00:11:20,866 --> 00:11:23,866
on websites because you only
have to manage one cert whereas


221
00:11:23,866 --> 00:11:25,006
with apps, you have
to manage two.


222
00:11:25,276 --> 00:11:31,696
All right, so that's a
little about the background.


223
00:11:32,496 --> 00:11:34,826
Let's talk about how it works.


224
00:11:36,486 --> 00:11:39,296
I'm going to take your through
two important things I need


225
00:11:39,296 --> 00:11:39,796
to happen.


226
00:11:39,976 --> 00:11:41,286
If you understand
these two things,


227
00:11:41,286 --> 00:11:42,396
you understand the feature.


228
00:11:43,536 --> 00:11:45,726
The first is how users subscribe


229
00:11:45,776 --> 00:11:47,546
to your website's
push notifications.


230
00:11:47,936 --> 00:11:52,076
So, once you've adopted the
feature, websites that go


231
00:11:52,076 --> 00:11:56,176
to your website-- users that
go to your website on Safari 7,


232
00:11:56,766 --> 00:12:02,116
on Mavericks, will see an
invitation to subscribe


233
00:12:02,116 --> 00:12:04,856
to your website's
push notification.


234
00:12:05,106 --> 00:12:07,126
If they accept that invitation,


235
00:12:07,126 --> 00:12:09,606
Safari will then
contact your server


236
00:12:09,646 --> 00:12:11,016
for your service credentials.


237
00:12:11,136 --> 00:12:12,936
And you're going to return
those credentials in the form


238
00:12:13,196 --> 00:12:15,116
of that push package that
I talked about earlier.


239
00:12:16,386 --> 00:12:21,376
Safari will then validate
the data in your push package


240
00:12:21,376 --> 00:12:22,616
and verify your identity.


241
00:12:23,806 --> 00:12:27,386
And if that succeeds, then
it's going to prompt the user


242
00:12:27,386 --> 00:12:29,816
to confirm their subscription.


243
00:12:30,726 --> 00:12:33,466
When the user confirms that
they want to subscribe,


244
00:12:34,066 --> 00:12:36,736
then Safari will send
something called a device token


245
00:12:37,056 --> 00:12:39,896
to your server and
tells your server


246
00:12:39,896 --> 00:12:41,356
to register that device token.


247
00:12:41,736 --> 00:12:45,946
And this device token is just a
string that Apple uses in order


248
00:12:45,946 --> 00:12:49,546
to target that users Mac.


249
00:12:53,836 --> 00:12:57,346
By the way, if the user wants to
change their and then they want


250
00:12:57,346 --> 00:13:00,106
to unsubscribe from
your push notifications,


251
00:13:00,106 --> 00:13:01,496
they can go Safari preferences


252
00:13:01,696 --> 00:13:02,956
and they click a
little radio button


253
00:13:02,956 --> 00:13:05,096
that says they deny
permission, meaning they want


254
00:13:05,096 --> 00:13:09,726
to unsubscribe, and then Safari
will make that exact same call


255
00:13:09,726 --> 00:13:11,906
of the device token except
this time it'll tell you


256
00:13:11,906 --> 00:13:14,126
to un-register and we
expect you to delete


257
00:13:14,126 --> 00:13:16,236
that device token
from your server.


258
00:13:16,816 --> 00:13:19,926
OK. So that's the first.


259
00:13:19,926 --> 00:13:21,176
The second thing was-- is


260
00:13:21,176 --> 00:13:23,046
about delivering those
push notifications.


261
00:13:23,046 --> 00:13:25,246
So, now that your server
has the device token


262
00:13:25,596 --> 00:13:28,106
and the notification
itself called the


263
00:13:28,106 --> 00:13:29,886
"Message Payload"
we combine them


264
00:13:29,996 --> 00:13:32,406
and create what we call
notification packet


265
00:13:32,816 --> 00:13:35,416
and you're going to
deliver that to APNS


266
00:13:35,746 --> 00:13:39,516
over a secure protocol using
that website push certificate.


267
00:13:39,786 --> 00:13:43,346
APNS looks at the device token
and knows exactly how to connect


268
00:13:43,346 --> 00:13:47,266
to the users Mac and that
notification gets displayed


269
00:13:47,266 --> 00:13:49,046
in the user's Notification
Center.


270
00:13:50,016 --> 00:13:54,076
If the user decides to
click on that notification,


271
00:13:54,416 --> 00:13:57,386
it's just like clicking on
a link, so it takes them


272
00:13:57,386 --> 00:14:05,356
to a web page in Safari or the
user's default web browser.


273
00:14:05,526 --> 00:14:07,566
OK. So we talked about
these two things,


274
00:14:07,566 --> 00:14:08,896
let's see how they
work in action.


275
00:14:08,896 --> 00:14:10,596
So I'd like to bring
up Brian Weinstein,


276
00:14:10,596 --> 00:14:12,106
the engineer on the Safari team.


277
00:14:12,476 --> 00:14:13,106
>> Thanks Jon.


278
00:14:13,536 --> 00:14:17,056
Now, I am Brian Weinstein, an
engineer of the Safari team


279
00:14:17,406 --> 00:14:19,006
and I'm going to show you what--


280
00:14:19,766 --> 00:14:22,336
how interacting with push
notifications will work


281
00:14:22,336 --> 00:14:23,396
for your users.


282
00:14:23,696 --> 00:14:27,856
So, we've made up
a website to show


283
00:14:27,856 --> 00:14:30,606
of this feature,
bayairlines.com.


284
00:14:30,966 --> 00:14:35,466
And I have a flight to Boston
later tonight and I would


285
00:14:35,466 --> 00:14:38,246
like to be updated about
information about my flight.


286
00:14:38,686 --> 00:14:42,986
So, as you can see we have
a visual affordance to sign


287
00:14:42,986 --> 00:14:44,336
up for push notifications


288
00:14:44,716 --> 00:14:48,336
and when you click the
Subscribe button, we show--


289
00:14:48,526 --> 00:14:54,876
Safari shows an alert asking
me whether or not I would


290
00:14:54,876 --> 00:14:56,876
like to subscribe for
push notifications.


291
00:14:57,506 --> 00:15:00,876
And it is branded
with the websites icon


292
00:15:01,146 --> 00:15:02,326
and the website's name.


293
00:15:03,696 --> 00:15:06,396
When I choose Allow, you can see


294
00:15:06,396 --> 00:15:09,576
that the user interface
has automatically updated


295
00:15:09,766 --> 00:15:11,986
to give me some preferences
for what kind


296
00:15:11,986 --> 00:15:14,266
of notifications I
would like to listen to.


297
00:15:15,006 --> 00:15:18,686
So, let's say I'm at the
airport, I'm having some food


298
00:15:18,686 --> 00:15:21,306
and I would just like to
know when my gate changes


299
00:15:21,466 --> 00:15:25,206
so I can find out if I need
to head somewhere else.


300
00:15:25,716 --> 00:15:27,926
What I can do is I can
subscribe for notifications


301
00:15:27,926 --> 00:15:31,416
when my boarding gate is changed
and then I can just quit Safari.


302
00:15:31,986 --> 00:15:35,216
And what's so powerful about
these push notifications is


303
00:15:35,216 --> 00:15:38,496
that they can be delivered
even when Safari isn't running.


304
00:15:39,086 --> 00:15:41,366
And you can see that I
was given a gate change


305
00:15:42,286 --> 00:15:45,476
and it gives me the new gate.


306
00:15:45,476 --> 00:15:48,796
And if I want to find a little
more about that notification,


307
00:15:49,126 --> 00:15:52,856
I can open up Notification
Center, select the Notification


308
00:15:53,176 --> 00:15:54,456
and it will launch Safari


309
00:15:54,456 --> 00:15:56,286
and give me even
more information


310
00:15:56,556 --> 00:15:57,876
about my gate change.


311
00:15:58,146 --> 00:16:01,406
And some other things that are
great about push notifications


312
00:16:01,406 --> 00:16:04,346
for websites is that they
are first class citizens


313
00:16:04,856 --> 00:16:08,096
in the rest of Mavericks UI.


314
00:16:08,646 --> 00:16:11,336
So, if I open the
notifications preference pane,


315
00:16:11,656 --> 00:16:15,216
you can see that Bay Airlines
is listed right alongside all


316
00:16:15,216 --> 00:16:17,826
of the other apps with
your website icon.


317
00:16:18,556 --> 00:16:22,216
And this is where you can change
how you can configure how your


318
00:16:22,216 --> 00:16:25,176
alerts are delivered either
in better form or alert form,


319
00:16:25,476 --> 00:16:26,906
and you can also look at--


320
00:16:27,266 --> 00:16:31,296
you can also adjust how
many notifications you see


321
00:16:31,296 --> 00:16:32,456
in Notification Center.


322
00:16:33,226 --> 00:16:37,806
And if you want to change
your notification preferences


323
00:16:37,806 --> 00:16:40,726
altogether in terms of
unsubscribing or subscribing,


324
00:16:41,186 --> 00:16:43,416
you do that through
Safari's preferences


325
00:16:43,416 --> 00:16:45,986
where every website
you signed up for--


326
00:16:45,986 --> 00:16:48,756
I've signed up for
push notifications


327
00:16:48,756 --> 00:16:51,496
for are listed here
and I can either Allow


328
00:16:51,496 --> 00:16:53,926
or Deny push notifications
through there.


329
00:16:54,466 --> 00:16:56,146
And so, that is what
push notifications


330
00:16:56,146 --> 00:16:57,306
for websites looks like.


331
00:16:58,156 --> 00:17:00,326
And now we're going to
learn a little bit more


332
00:17:00,326 --> 00:17:01,446
about how to implement it.


333
00:17:01,446 --> 00:17:03,856
And now, I'd like to
hand it back to Jon.


334
00:17:04,171 --> 00:17:06,171
[applause]


335
00:17:06,486 --> 00:17:07,556
>> So we've learned a little bit


336
00:17:07,556 --> 00:17:09,136
about how it works behind
the scenes, let's figure


337
00:17:09,136 --> 00:17:10,586
out how to implement it.


338
00:17:12,715 --> 00:17:14,185
There are two things
that you need to do.


339
00:17:14,185 --> 00:17:16,486
The first is actually
to get a certificate


340
00:17:16,486 --> 00:17:17,776
from the developer portal.


341
00:17:17,776 --> 00:17:19,886
And don't worry, I will
take you through every step


342
00:17:20,356 --> 00:17:22,256
to get those-- that certificate.


343
00:17:22,256 --> 00:17:23,665
And the second thing is you need


344
00:17:23,665 --> 00:17:25,955
to add notification
support to your server.


345
00:17:26,266 --> 00:17:27,566
And what do I mean by that?


346
00:17:27,566 --> 00:17:31,906
Well, the server actually kind
of serves three different roles


347
00:17:31,906 --> 00:17:34,456
and you need to implement
support for each of those roles.


348
00:17:35,676 --> 00:17:38,716
The first is you need to ask
the user on your website,


349
00:17:38,716 --> 00:17:40,376
you need to invite
them to subscribe


350
00:17:40,376 --> 00:17:41,576
to your push notifications.


351
00:17:42,006 --> 00:17:44,286
You need to write a web
service back end and then


352
00:17:44,286 --> 00:17:46,376
when it's time you need to
send them push notifications.


353
00:17:46,636 --> 00:17:49,676
But a better way to kind of
think about these three tasks is


354
00:17:49,676 --> 00:17:54,516
that the first is how
your website communicates


355
00:17:54,516 --> 00:17:57,046
to your users that you've
got this great feature,


356
00:17:57,776 --> 00:17:59,816
the second is how
Safari communicates


357
00:17:59,816 --> 00:18:02,986
with your web server, and the
third is how your web server


358
00:18:02,986 --> 00:18:05,846
communicates with APNS to
deliver those notifications.


359
00:18:06,826 --> 00:18:10,126
So first, let's talk about
getting that Push certificate.


360
00:18:11,016 --> 00:18:12,386
Getting a push certificate,


361
00:18:12,386 --> 00:18:14,206
super simple, it's
just two steps.


362
00:18:14,206 --> 00:18:15,826
One, you have to
Register a put--


363
00:18:15,826 --> 00:18:17,396
website Push ID and
the second it


364
00:18:17,436 --> 00:18:20,556
to create a certificate
based on that push ID.


365
00:18:20,916 --> 00:18:22,236
So, in the developer portal,


366
00:18:22,236 --> 00:18:25,486
you go to the certificate's
identifiers and profiles page


367
00:18:25,656 --> 00:18:28,896
and on the left hand side
you will see a new item


368
00:18:28,896 --> 00:18:31,406
that allows you to
register a website push ID,


369
00:18:31,406 --> 00:18:33,976
just click on that Plus button
in the upper right hand corner


370
00:18:33,976 --> 00:18:37,186
and you'll be taken to a
form where you need to put


371
00:18:37,186 --> 00:18:38,396
in two pieces of information.


372
00:18:38,656 --> 00:18:42,936
Both of these pieces of
information are just names.


373
00:18:43,226 --> 00:18:44,856
It's just for different
audiences.


374
00:18:44,856 --> 00:18:47,666
So the first one is just
human readable description


375
00:18:47,666 --> 00:18:49,666
and this description
is just for you.


376
00:18:49,666 --> 00:18:51,906
It'll be used throughout
the developer portal


377
00:18:51,906 --> 00:18:54,186
but Safari won't see it,
your users won't see it,


378
00:18:54,186 --> 00:18:55,836
your server won't see it.


379
00:18:56,676 --> 00:19:00,866
The second is how your--
how the code actually knows


380
00:19:00,866 --> 00:19:03,466
about your website or can
identify your website.


381
00:19:03,976 --> 00:19:05,996
And we recommend the use
a reverse domain string.


382
00:19:06,286 --> 00:19:07,906
The developer portal will
make sure that it's got


383
00:19:07,936 --> 00:19:11,446
that web prefix, and that's it.


384
00:19:11,446 --> 00:19:13,506
We just registered the push ID.


385
00:19:13,636 --> 00:19:15,886
Now, let's create
the certificate.


386
00:19:15,886 --> 00:19:17,196
So, you're going
to go into settings


387
00:19:17,656 --> 00:19:19,746
and you see these
detailed instructions


388
00:19:19,746 --> 00:19:22,486
of creating a certificate
signing request.


389
00:19:23,146 --> 00:19:26,436
And the certificates I knew in
quest will create a private key


390
00:19:26,436 --> 00:19:31,236
that you will use to sign
your push package as well


391
00:19:31,606 --> 00:19:35,856
as the certificate itself you'll
be creating to connect to APNS.


392
00:19:36,566 --> 00:19:40,226
So, it's going to create a file,
you're to upload that file,


393
00:19:40,816 --> 00:19:42,156
and you've got your certificate.


394
00:19:42,866 --> 00:19:47,026
But the certificate is in
a format that actually--


395
00:19:47,766 --> 00:19:49,476
that's actually not
what we need in order


396
00:19:49,476 --> 00:19:51,246
to actually sign
our push package.


397
00:19:51,526 --> 00:19:53,326
So for that, install
the certificate


398
00:19:53,326 --> 00:19:55,956
in a keychain access.


399
00:19:56,056 --> 00:19:59,016
Right click on it and you want
to export that certificate


400
00:19:59,446 --> 00:20:02,906
to a P12 file, and that--


401
00:20:02,906 --> 00:20:06,286
it's that representation of your
certificate that you will use


402
00:20:06,286 --> 00:20:08,706
in order to sign
your push package.


403
00:20:09,356 --> 00:20:11,406
OK. So now we got
the certificate.


404
00:20:11,406 --> 00:20:13,916
Next, it's time to
do the fun stuff.


405
00:20:13,916 --> 00:20:15,456
It's time to do some coding.


406
00:20:15,456 --> 00:20:19,346
So, the first thing is to
invite your users to subscribe


407
00:20:19,346 --> 00:20:21,796
to push notifications
on your website.


408
00:20:23,146 --> 00:20:26,936
So we've created two
new JavaScript APIs


409
00:20:27,306 --> 00:20:29,056
that you use on your webpage.


410
00:20:29,486 --> 00:20:32,546
The first is to see if the user
has been asked before already


411
00:20:32,816 --> 00:20:35,576
and if not, you use the second
API which is to ask them.


412
00:20:36,156 --> 00:20:37,536
So, let's take a look
at the first one.


413
00:20:37,846 --> 00:20:40,246
You're going to call
window.safari.


414
00:20:40,246 --> 00:20:43,566
pushNotification.permission
and you're going to pass


415
00:20:43,566 --> 00:20:46,726
in the website push ID which
is that push ID that you used


416
00:20:46,726 --> 00:20:50,046
in order to create you website
push certificate, right?


417
00:20:50,576 --> 00:20:52,346
It's a synchronous
call and it's going


418
00:20:52,346 --> 00:20:56,526
to return a JavaScript object
that has a permission property


419
00:20:56,526 --> 00:20:58,386
and that property can have
three different values.


420
00:20:58,586 --> 00:21:00,606
The first is default which means


421
00:21:00,606 --> 00:21:03,076
that the user has never
been asked before.


422
00:21:03,916 --> 00:21:06,466
The second is denied, where
the user has been asked before


423
00:21:06,466 --> 00:21:09,166
but they said they did
not want to subscribe.


424
00:21:09,166 --> 00:21:12,486
It's when in that modal
dialog you said, "don't allow"


425
00:21:12,486 --> 00:21:15,136
so the user clicked on Don't
Allow, and the third is


426
00:21:15,136 --> 00:21:17,766
when they click Allow and they
confirmed their subscription


427
00:21:18,276 --> 00:21:21,016
and in that case you'll see that
the permission has been granted.


428
00:21:21,446 --> 00:21:22,946
And if the permission
is granted,


429
00:21:23,116 --> 00:21:24,266
they'll be a second property


430
00:21:25,226 --> 00:21:27,246
which contains the
user's device token.


431
00:21:27,246 --> 00:21:29,466
And you can use this
device token in order


432
00:21:29,466 --> 00:21:33,486
to change your website UI


433
00:21:33,486 --> 00:21:37,056
to give your users some more
granularity over the kinds


434
00:21:37,056 --> 00:21:38,706
of push notifications
that they receive.


435
00:21:39,166 --> 00:21:40,856
So, in the demo that
we just saw,


436
00:21:40,856 --> 00:21:42,696
it's like seeing the
different kinds of reminders


437
00:21:42,946 --> 00:21:45,676
that Brian wanted
to get notified of.


438
00:21:46,236 --> 00:21:48,366
Now let's say that the user
has never been asked before.


439
00:21:48,366 --> 00:21:50,386
So the permission will be
default, that first one, right?


440
00:21:50,476 --> 00:21:52,906
So, next we have to
actually request permission.


441
00:21:52,906 --> 00:21:55,896
And for that, you call
window.safari.push


442
00:21:55,896 --> 00:21:59,356
Notification.requestPermission,
it's an asynchronous call


443
00:21:59,356 --> 00:22:01,236
and you're going to call--


444
00:22:01,406 --> 00:22:03,226
you're going to pass
in four parameters.


445
00:22:03,536 --> 00:22:07,416
The first is the URL to your web
service, so it's that second--


446
00:22:07,796 --> 00:22:09,886
the second thing that
you have to implement.


447
00:22:10,326 --> 00:22:13,606
It must be-- it must
support HTTPS


448
00:22:13,606 --> 00:22:17,096
and this represents the base URL
to your web service and I'll get


449
00:22:17,096 --> 00:22:19,346
into how to implement
that web service later.


450
00:22:20,086 --> 00:22:22,806
The second is the push ID
which you've seen before.


451
00:22:23,336 --> 00:22:26,316
The third is something
that we added for you guys


452
00:22:26,316 --> 00:22:30,186
and we're calling it userInfo
which should sound familiar


453
00:22:30,186 --> 00:22:32,146
for those of you
who use Cocoa APIs.


454
00:22:32,536 --> 00:22:36,216
It's just simply a way
for your website to talk


455
00:22:36,466 --> 00:22:38,466
to your web service
because you recognize


456
00:22:38,466 --> 00:22:41,386
that you might have those
two roles implemented


457
00:22:41,386 --> 00:22:42,356
on separate hardware.


458
00:22:43,076 --> 00:22:46,376
It's basically just a
simple dictionary of strings


459
00:22:46,376 --> 00:22:48,346
and you can put anything
in there


460
00:22:48,646 --> 00:22:52,436
to help you identify the user
that's logged in to your website


461
00:22:52,616 --> 00:22:55,356
or maybe some preferences
that they want in terms


462
00:22:55,356 --> 00:22:58,496
of the notifications they
receive or even the language


463
00:22:58,496 --> 00:23:00,416
in which they want to
receive those notifications.


464
00:23:00,856 --> 00:23:04,156
Finally, you're going to
pass a callback function


465
00:23:04,826 --> 00:23:07,976
that will get invoked when
the user has finally made


466
00:23:07,976 --> 00:23:08,536
a decision.


467
00:23:08,536 --> 00:23:11,196
Like when the modal dropped
down, a dialogue appears


468
00:23:11,196 --> 00:23:12,746
and they decide one
way or the other.


469
00:23:13,026 --> 00:23:16,326
We will invoke this callback and
pass in that permissions object


470
00:23:16,326 --> 00:23:19,596
that you saw for the
first JavaScript API.


471
00:23:19,686 --> 00:23:22,326
In the case that the user
confirms, you're going


472
00:23:22,326 --> 00:23:24,586
to see the granted permission
and that device token.


473
00:23:25,396 --> 00:23:27,736
In the case that they said
"no" you're just going


474
00:23:27,736 --> 00:23:29,786
to see the denied permission
cause you don't need the device


475
00:23:29,786 --> 00:23:33,506
token in that case.


476
00:23:33,676 --> 00:23:38,566
All right, so we've asked users
on your website to subscribe.


477
00:23:39,936 --> 00:23:42,376
Now, it's time to write
that web service back end.


478
00:23:43,776 --> 00:23:46,726
So, let's review
how users subscribe


479
00:23:46,926 --> 00:23:49,436
to your push notifications,
so bring up that diagram.


480
00:23:49,716 --> 00:23:52,956
So any arrow that you
see going from Safari


481
00:23:53,146 --> 00:23:55,936
to the server represents an
endpoint that you're going


482
00:23:56,356 --> 00:23:59,166
to have to implement in order--


483
00:23:59,166 --> 00:24:01,746
that you're going to have to
implement in your web service.


484
00:24:02,426 --> 00:24:07,396
So the first is when Safari
contacts your web service


485
00:24:07,396 --> 00:24:08,656
in order to get that
push package,


486
00:24:09,276 --> 00:24:10,696
when that push package
has returned


487
00:24:10,866 --> 00:24:13,706
and Safari will do a validation


488
00:24:13,706 --> 00:24:15,686
and if anything went wrong
during that validation,


489
00:24:15,686 --> 00:24:17,056
it will then contact your--


490
00:24:17,266 --> 00:24:21,126
the second endpoint and
tell your what went wrong.


491
00:24:21,806 --> 00:24:22,966
But if everything succeeds


492
00:24:22,966 --> 00:24:25,266
and the user confirms their
subscription then it will


493
00:24:25,266 --> 00:24:27,626
contact the third endpoint


494
00:24:27,786 --> 00:24:31,426
where we register the device
token to your web service.


495
00:24:31,756 --> 00:24:34,416
There is a fourth endpoint
that's not in this diagram


496
00:24:34,416 --> 00:24:37,066
and that's when the
user changes her mind


497
00:24:37,066 --> 00:24:38,246
and decides to unsubscribe.


498
00:24:38,326 --> 00:24:40,836
We make a very similar call
except instead of saying


499
00:24:40,836 --> 00:24:43,526
where register device token
we say un-register this


500
00:24:43,526 --> 00:24:44,086
device token.


501
00:24:44,086 --> 00:24:47,646
So let's talk about
that first line


502
00:24:47,646 --> 00:24:48,816
about getting that push package.


503
00:24:49,246 --> 00:24:54,916
You can think of this as being
Safari just calling a function,


504
00:24:54,916 --> 00:24:58,106
except the function is in the
format of an HTTP request.


505
00:24:58,726 --> 00:25:01,016
And this function contains
two different parameters.


506
00:25:01,016 --> 00:25:04,966
The first is the websitePushID
and the second is that userInfo


507
00:25:04,966 --> 00:25:06,646
from the request permission call


508
00:25:06,926 --> 00:25:08,896
but serialized as
a query string.


509
00:25:09,256 --> 00:25:11,856
.So for many of you that
only have one website,


510
00:25:11,856 --> 00:25:13,466
you can basically ignore
the first one 'cause the


511
00:25:13,466 --> 00:25:15,026
websitePushID will
always be the same.


512
00:25:15,546 --> 00:25:17,296
But the second one, you
might want to pay attention


513
00:25:17,296 --> 00:25:20,586
to in order to be able to
tailor the push package


514
00:25:20,586 --> 00:25:21,346
that you return.


515
00:25:21,996 --> 00:25:24,876
So, just to review, here's
that requestPermission call,


516
00:25:24,876 --> 00:25:27,476
that third parameter, userInfo.


517
00:25:27,976 --> 00:25:29,556
Here's an example
of what I could--


518
00:25:29,596 --> 00:25:31,106
we could pass in for
the Bay Airlines site.


519
00:25:31,216 --> 00:25:34,056
We pass in the log in
of the user as well


520
00:25:34,056 --> 00:25:36,956
as their frequentFlyerID
and that will get converted


521
00:25:37,286 --> 00:25:40,376
by Safari to this string,
it looks like a query string


522
00:25:40,376 --> 00:25:42,226
and that will be
in the HTTP body


523
00:25:42,516 --> 00:25:45,156
in the requester
your web service.


524
00:25:46,706 --> 00:25:50,056
So, when this endpoint is
called, we expect your server


525
00:25:50,116 --> 00:25:52,546
to create that push package
and what does that look like?


526
00:25:53,076 --> 00:25:58,246
Well, if push package is nothing
more than a zipped archive


527
00:25:58,246 --> 00:26:00,376
of a whole bunch
of files formatted


528
00:26:00,376 --> 00:26:01,846
and structured in
a specific way.


529
00:26:02,076 --> 00:26:05,756
And for those of you who have
some familiarity with Passbook,


530
00:26:05,756 --> 00:26:09,146
you might recognize that
this actually follows the way


531
00:26:09,146 --> 00:26:11,136
that passes are constructed.


532
00:26:12,246 --> 00:26:15,406
So the first set of files are
just the icons representing


533
00:26:15,406 --> 00:26:16,026
your website.


534
00:26:16,026 --> 00:26:18,006
This will be used
throughout the UI


535
00:26:18,006 --> 00:26:20,646
and you'll see how
they map later.


536
00:26:21,676 --> 00:26:25,146
The second is a file
that we call website.json


537
00:26:25,146 --> 00:26:29,676
and it's a dictionary with
information about your website.


538
00:26:29,826 --> 00:26:32,116
Let's drill down a
little bit into it.


539
00:26:32,206 --> 00:26:33,616
The first two you've
seen already.


540
00:26:34,106 --> 00:26:38,336
It's the URL to your web service


541
00:26:39,066 --> 00:26:41,096
and the second is
your websitePushID.


542
00:26:41,816 --> 00:26:48,326
The third is your websiteName
and this will be used in the UI


543
00:26:48,326 --> 00:26:52,116
when we ask the user to
confirm their subscription


544
00:26:52,116 --> 00:26:54,016
or in Notification Center.


545
00:26:55,276 --> 00:26:57,956
The fourth is what we
called allowedDomains


546
00:26:57,956 --> 00:27:01,126
and it's just a list of
domains that are allowed


547
00:27:01,566 --> 00:27:06,006
to request permission from
your users to subscribe


548
00:27:06,126 --> 00:27:08,036
to your website's
push notifications.


549
00:27:08,276 --> 00:27:09,906
So why would we add
something like this here?


550
00:27:09,906 --> 00:27:13,066
Well, it's to prevent somebody
trying to spoof your website


551
00:27:13,066 --> 00:27:15,276
from being able to get
those device tokens


552
00:27:15,516 --> 00:27:17,686
and sent push notifications
on your behalf.


553
00:27:18,386 --> 00:27:22,256
So, one way that a spoofer could
try to pretend to be you is


554
00:27:22,256 --> 00:27:24,696
to take this push package
that you would normally serve


555
00:27:24,886 --> 00:27:26,716
and serve that to users instead.


556
00:27:27,646 --> 00:27:30,756
But what will happen is during
the verification algorithm,


557
00:27:30,756 --> 00:27:33,056
Safari will take a
look at the domain


558
00:27:33,056 --> 00:27:35,316
that was making the request
for the permission and compare


559
00:27:35,316 --> 00:27:36,896
that against this list.


560
00:27:37,226 --> 00:27:38,746
And so, in the case of
the spoofing website,


561
00:27:38,746 --> 00:27:41,806
that website won't be here
so therefore Safari won't--


562
00:27:41,836 --> 00:27:43,756
Safari will fail and
you'll be notified of that.


563
00:27:44,466 --> 00:27:47,036
So really, this-- having this
list here is a way for you


564
00:27:47,036 --> 00:27:50,306
to protect yourself against
people who are going to try to--


565
00:27:50,306 --> 00:27:52,446
or going to try to forge
your notifications.


566
00:27:52,916 --> 00:27:57,576
Next is what we call
an authenticationToken


567
00:27:58,136 --> 00:28:02,286
and it's similar in its
purpose to userInfo.


568
00:28:02,846 --> 00:28:06,046
Remember that with userInfo,
we were saying it's just a way


569
00:28:06,046 --> 00:28:08,596
for your website to talk
to your web service.


570
00:28:09,086 --> 00:28:11,876
This is a way for your web
service to talk back to itself


571
00:28:11,996 --> 00:28:14,006
because the web service,
we don't expect


572
00:28:14,116 --> 00:28:15,586
to maintain any sort of state.


573
00:28:15,896 --> 00:28:19,426
So, when the user changes their
mind about their subscription


574
00:28:19,426 --> 00:28:22,896
to push notifications, you need
a way to identify that user


575
00:28:23,086 --> 00:28:27,306
and so you can use this
authenticationToken to do that.


576
00:28:27,516 --> 00:28:30,626
Finally, we include
urlFormatString


577
00:28:30,626 --> 00:28:33,136
and the reason why we
included this here is because,


578
00:28:33,266 --> 00:28:35,576
like I said, like when you
click on that notification it's


579
00:28:35,576 --> 00:28:36,426
like clicking on a link.


580
00:28:36,686 --> 00:28:39,146
Well, so the notification
is going to have that URL.


581
00:28:39,706 --> 00:28:42,126
But for many websites,
that URL is really long


582
00:28:42,126 --> 00:28:47,366
and because notifications
payloads can only have a limited


583
00:28:47,366 --> 00:28:51,876
size, those URLs might actually
take up all the space available,


584
00:28:51,876 --> 00:28:53,686
and so you won't have any
room for your notifications.


585
00:28:53,686 --> 00:28:57,246
So, we have this here as
a way for you to be able


586
00:28:57,246 --> 00:29:00,716
to reduce the amount of
space that your URL needs


587
00:29:00,716 --> 00:29:02,296
in the notification
and you'll see


588
00:29:02,296 --> 00:29:07,586
that it's formatted very
similar to strings in Cocoa.


589
00:29:08,066 --> 00:29:11,676
OK. So we just talked
about the things that kind


590
00:29:11,676 --> 00:29:12,836
of describe your website.


591
00:29:12,836 --> 00:29:18,126
The next two pieces are
how Safari can validate


592
00:29:18,126 --> 00:29:18,766
your identify.


593
00:29:18,946 --> 00:29:22,306
So the first thing is a
manifest.json, it's a dictionary


594
00:29:22,706 --> 00:29:24,066
of all of the files
we just talked


595
00:29:24,066 --> 00:29:27,576
about that contains
references to all the files


596
00:29:27,576 --> 00:29:30,126
that we just talked about
and the SHA1 checksums.


597
00:29:30,666 --> 00:29:33,306
And this is kind of
what that looks like.


598
00:29:33,706 --> 00:29:38,066
As you see it, the keys are all
relative passed to those files


599
00:29:38,396 --> 00:29:40,436
and then the values
are the checksums


600
00:29:40,436 --> 00:29:42,526
and I've truncated them
here for readability.


601
00:29:42,696 --> 00:29:44,176
So why would we do
something like this?


602
00:29:44,476 --> 00:29:49,756
Well, if a spoofer try to change
your icon or change the name


603
00:29:49,756 --> 00:29:53,996
of your website, when Safari
does its validation algorithm,


604
00:29:53,996 --> 00:29:55,916
it's going to find
that the checksums


605
00:29:55,916 --> 00:29:59,136
for those files are not going to
match what you have here, right?


606
00:29:59,136 --> 00:30:01,646
So that's how we-- that's the
reason why we have this file.


607
00:30:02,166 --> 00:30:04,976
And then finally,
you're going to sign


608
00:30:05,046 --> 00:30:07,276
that manifest using
the private key


609
00:30:07,276 --> 00:30:08,686
of your website push
certificate.


610
00:30:09,696 --> 00:30:12,876
And we do this because when
the push package gets sent


611
00:30:12,876 --> 00:30:16,956
to Safari, it will check the
signature against the manifest


612
00:30:17,096 --> 00:30:19,046
and if they don't match,


613
00:30:19,386 --> 00:30:26,156
that means that some other
developers try to sign it


614
00:30:26,156 --> 00:30:28,286
with an invalid certificate.


615
00:30:29,786 --> 00:30:32,936
OK. So now, that's the push
package, you zip that up


616
00:30:32,936 --> 00:30:34,516
and you send that
back to Safari.


617
00:30:34,876 --> 00:30:37,076
Safari will then validate kind


618
00:30:37,076 --> 00:30:38,926
of checking all the
things that I talked about.


619
00:30:39,526 --> 00:30:43,896
And if anything went wrong
like a file is malformed


620
00:30:43,896 --> 00:30:47,326
or there is a typo
in the website.json,


621
00:30:47,866 --> 00:30:50,916
we will then contact
a logging endpoint


622
00:30:50,916 --> 00:30:53,826
and that's the second endpoint
to report what went wrong.


623
00:30:55,166 --> 00:30:58,226
And super simple, it's what--
this is what it looks like,


624
00:30:58,606 --> 00:31:02,946
and you'll notice that
the body is just formatted


625
00:31:02,996 --> 00:31:04,976
like a JSON object
that contains list


626
00:31:04,976 --> 00:31:09,286
of the human readable
strengths explaining


627
00:31:09,286 --> 00:31:10,416
like what exactly went wrong.


628
00:31:10,946 --> 00:31:13,996
But hopefully, you have a
major push package correctly


629
00:31:13,996 --> 00:31:17,486
and so we prompt and confirm.


630
00:31:18,436 --> 00:31:21,596
And at this point, that we
can actually see how elements


631
00:31:21,596 --> 00:31:23,386
in the push package
map to the UI.


632
00:31:23,706 --> 00:31:27,396
So just briefly, here's
that dialogue that Brian saw


633
00:31:27,396 --> 00:31:29,706
when he clicked on that
Subscribed Button and you'll see


634
00:31:29,706 --> 00:31:32,806
that the icon comes from the
icons in the push package


635
00:31:33,296 --> 00:31:36,406
and the websiteName and
the website.json map


636
00:31:36,516 --> 00:31:39,576
into the text asking
the user to subscribe.


637
00:31:40,196 --> 00:31:45,926
OK. So now, the user
says I want your--


638
00:31:46,036 --> 00:31:49,046
I want Bay Airlines push
notifications so now it's time


639
00:31:49,046 --> 00:31:53,466
for Safari to send that device
token over to your web service.


640
00:31:53,906 --> 00:31:57,066
And this is what
that call looks like.


641
00:31:57,066 --> 00:31:59,356
There are three pieces
of information.


642
00:31:59,776 --> 00:32:01,956
The first is the
deviceToken itself


643
00:32:01,956 --> 00:32:04,276
and that's what you're going to
want to store in your databases.


644
00:32:04,556 --> 00:32:07,256
The second is the websitePushID
which again for those of you


645
00:32:07,256 --> 00:32:08,916
with just one website,
you can just ignore that.


646
00:32:08,916 --> 00:32:12,526
And the third is the
authenticationToken that you put


647
00:32:12,526 --> 00:32:16,506
in that push package and
that's how your web server,


648
00:32:16,946 --> 00:32:20,446
your web service knows who to
associate the device token with.


649
00:32:20,656 --> 00:32:26,246
If the user changes their
mind because they don't want


650
00:32:26,246 --> 00:32:28,186
to subscribe to your push
notifications anymore,


651
00:32:28,186 --> 00:32:29,986
we actually make a request


652
00:32:29,986 --> 00:32:35,296
to the exact same endpoint
except instead we use the HTTP


653
00:32:35,296 --> 00:32:37,176
Delete Method so just
look for the method


654
00:32:37,176 --> 00:32:39,996
and you'll know whether
to add that device token


655
00:32:39,996 --> 00:32:41,186
to your databases or remove it.


656
00:32:45,756 --> 00:32:46,646
And that's it.


657
00:32:46,646 --> 00:32:47,926
That's all you need
to do in order


658
00:32:47,926 --> 00:32:49,696
to implement your web service.


659
00:32:50,886 --> 00:32:54,416
Now, it's time to send
those push notifications.


660
00:32:55,556 --> 00:32:59,436
So those of you who had
experienced implementing push


661
00:32:59,436 --> 00:33:02,416
notifications for Native
Apps, we'll be happy to learn


662
00:33:02,416 --> 00:33:04,626
that it works exactly the
same way for websites.


663
00:33:04,856 --> 00:33:07,956
For those of you who are not
familiar, this is the format


664
00:33:08,016 --> 00:33:10,236
that you send to APNS.


665
00:33:10,236 --> 00:33:12,466
It looks like it's
JSON formatted,


666
00:33:12,746 --> 00:33:16,516
and in that notification
you include the elements


667
00:33:16,516 --> 00:33:17,846
that will be in the notification


668
00:33:17,846 --> 00:33:19,576
so that includes the
title and the body.


669
00:33:20,366 --> 00:33:25,366
And for those users who decide
to see your notifications


670
00:33:25,366 --> 00:33:26,866
as alerts instead of banners,


671
00:33:27,136 --> 00:33:31,886
then this action value
will override the title


672
00:33:31,886 --> 00:33:33,526
in the Action button
in the notification.


673
00:33:35,286 --> 00:33:39,936
And instead of having
custom data which you can do


674
00:33:39,936 --> 00:33:42,646
with Native App Push
Notifications, we--


675
00:33:42,776 --> 00:33:45,786
or you have the URL and that
URL can provide all the context


676
00:33:45,786 --> 00:33:47,236
that you need in order to get--


677
00:33:47,236 --> 00:33:49,676
in order to take your
users to the right detail.


678
00:33:49,676 --> 00:33:54,296
So, here we've decided to
express it in terms of URL args


679
00:33:54,646 --> 00:33:58,516
and the reason for that is
because we don't want you


680
00:33:58,516 --> 00:34:00,596
to necessarily include the
entire URL 'cause it might be


681
00:34:00,596 --> 00:34:03,836
too long and you
have a limited size


682
00:34:03,836 --> 00:34:04,966
in your notification payload.


683
00:34:05,576 --> 00:34:08,516
In fact, that payload
is limited to 256 bytes.


684
00:34:09,376 --> 00:34:10,585
So be sure to take advantage


685
00:34:10,585 --> 00:34:13,656
of that URL format string
in the push package.


686
00:34:14,926 --> 00:34:17,065
And when you send
that notification,


687
00:34:17,065 --> 00:34:18,235
make sure that you
always send it


688
00:34:18,315 --> 00:34:21,596
to the APNS's Production
Environment.


689
00:34:21,596 --> 00:34:26,406
There is no support for
pushing your notifications


690
00:34:26,406 --> 00:34:27,216
to the Sandbox.


691
00:34:27,826 --> 00:34:32,866
So now that we got the payload
and we have the push package


692
00:34:32,866 --> 00:34:35,476
from earlier, we know now
how to construct everything.


693
00:34:35,476 --> 00:34:38,116
So, in the notification
itself, the icons come


694
00:34:38,186 --> 00:34:41,835
from your push package
and the title


695
00:34:41,835 --> 00:34:43,196
and body come from the payload.


696
00:34:43,196 --> 00:34:45,946
And for users who are
seeing your notification


697
00:34:46,216 --> 00:34:50,976
as an alert will see your
Action button title override


698
00:34:50,976 --> 00:34:52,166
that button.


699
00:34:53,295 --> 00:34:58,436
The notification in Notification
Center will appear as such.


700
00:34:58,526 --> 00:35:01,306
The header gets its
icon and website name


701
00:35:01,306 --> 00:35:05,306
from your push package and the
actual notification itself comes


702
00:35:05,306 --> 00:35:06,396
from the payload.


703
00:35:07,006 --> 00:35:10,176
And when the user clicks
on that notification,


704
00:35:10,586 --> 00:35:13,516
we combine the URL format
string from your push package


705
00:35:13,826 --> 00:35:18,816
and the URL args from your
payload, combine them together


706
00:35:19,376 --> 00:35:23,336
to make the final URL that takes
the user to see more details.


707
00:35:23,946 --> 00:35:27,486
So, I'd like to bring Brian back


708
00:35:27,486 --> 00:35:30,566
up to show you how these
all works behind the scenes.


709
00:35:30,846 --> 00:35:31,706
>> Thanks, Jon.


710
00:35:32,626 --> 00:35:38,096
So now we are going to look
at what happens when I use--


711
00:35:38,216 --> 00:35:40,056
when I sign up for
push notifications


712
00:35:40,056 --> 00:35:41,546
from the website's
point of view--


713
00:35:42,376 --> 00:35:43,736
from the web server's
point of view.


714
00:35:43,946 --> 00:35:47,286
So as you can see, we have a
terminal window open with some--


715
00:35:47,866 --> 00:35:51,526
with the web service log
output from bayairlines.com


716
00:35:52,076 --> 00:35:54,626
and we also-- as a little bonus,
we'll get to see what happens


717
00:35:54,626 --> 00:35:56,096
if you happened to
make a mistake


718
00:35:56,096 --> 00:35:59,436
in generating your push package.


719
00:35:59,436 --> 00:36:02,646
So when I want to sign up
for push notifications,


720
00:36:03,006 --> 00:36:08,476
I will click the
Subscribe button and some--


721
00:36:08,476 --> 00:36:11,486
and there is an issue with
the web server's push package.


722
00:36:11,736 --> 00:36:18,286
As you can see, Safari sends
a request to V1 push packages


723
00:36:18,286 --> 00:36:20,966
and then the website
identifier and we--


724
00:36:20,966 --> 00:36:23,876
and then the web server
will log some user info


725
00:36:24,446 --> 00:36:26,336
and send back a push package.


726
00:36:26,736 --> 00:36:30,656
But as we can see, the push
package Safari did not validate


727
00:36:30,656 --> 00:36:34,046
the push package
correctly and there was a--


728
00:36:34,696 --> 00:36:38,976
and we send an issue
back to V1 log saying,


729
00:36:39,286 --> 00:36:42,476
"Refer URL bayairlines.com
is not


730
00:36:42,476 --> 00:36:43,956
in the list of allowed domains".


731
00:36:44,556 --> 00:36:48,856
So, as Jon described
from earlier in the talk,


732
00:36:49,356 --> 00:36:54,246
allowed domains are-- is in the
website.json file so let's open


733
00:36:54,246 --> 00:36:56,426
that up and see what's in there.


734
00:36:57,876 --> 00:37:02,486
And as you can see, we have
allowed domains it's just listed


735
00:37:02,486 --> 00:37:04,146
as bayairline.com.


736
00:37:04,676 --> 00:37:08,746
So, we very-- we just have
a simple typo, we just need


737
00:37:08,746 --> 00:37:12,726
to add an S to make it
bayairlines.com, save it,


738
00:37:13,596 --> 00:37:20,186
and what the Bay Airlines web
server will do is when you--


739
00:37:20,186 --> 00:37:22,546
when we try and sign up
for push notifications,


740
00:37:23,036 --> 00:37:26,196
the server will automatically
generate a push package based


741
00:37:26,196 --> 00:37:31,216
on the files that are-- based
on the files on the file system.


742
00:37:31,216 --> 00:37:33,196
So, we don't need to
generate a new push package,


743
00:37:33,196 --> 00:37:34,546
it will be done automatically.


744
00:37:35,316 --> 00:37:38,416
We can just reload the
web page and try again.


745
00:37:39,596 --> 00:37:43,146
And that time it works
correctly and we were given--


746
00:37:43,276 --> 00:37:45,656
we were told that we
were asked for permission


747
00:37:45,656 --> 00:37:48,446
to sign up for notifications.


748
00:37:49,696 --> 00:37:52,846
We click Allow and you
can-- and then when we--


749
00:37:52,906 --> 00:37:56,756
when the user finished signing
up for push notifications,


750
00:37:57,176 --> 00:38:02,506
we sent the device token to
the Bay Airlines web server


751
00:38:03,096 --> 00:38:09,256
and in the HTTP Authorize Header
we have the userInfo specified


752
00:38:09,256 --> 00:38:10,356
in the push package.


753
00:38:11,196 --> 00:38:15,136
Now, let's open up System
Preferences again because I want


754
00:38:15,136 --> 00:38:18,946
to change my type
of alert and I want


755
00:38:18,946 --> 00:38:20,546
to make it an alert
instead of a banner.


756
00:38:21,616 --> 00:38:27,266
So now, let's say there's
Wi-Fi on the plane and I want


757
00:38:27,266 --> 00:38:30,836
to be updated with the
weather for when I land.


758
00:38:31,686 --> 00:38:34,816
So when I get notified of
weather, I want to be notified


759
00:38:34,816 --> 00:38:39,056
of weather conditions
on the day of flight.


760
00:38:39,056 --> 00:38:41,956
And as you can see, our
web server connected


761
00:38:41,956 --> 00:38:45,836
to APNS using the
Production Environment


762
00:38:46,346 --> 00:38:50,236
and deliver this message payload
giving me some more information


763
00:38:50,236 --> 00:38:57,226
about the weather and it shows
up in Notification Center right


764
00:38:57,406 --> 00:39:00,916
over here with-- and then
we can either just close the


765
00:39:00,916 --> 00:39:02,436
notification or see more.


766
00:39:03,326 --> 00:39:06,286
Now, if the user
decides to unsubscribe


767
00:39:06,286 --> 00:39:11,326
from push notifications like
Bay Airlines lost their baggage


768
00:39:11,326 --> 00:39:17,456
and they're never going to
fly them again, they can open


769
00:39:17,456 --> 00:39:22,276
up Safari's Preferences and
switch over from Allow to Deny.


770
00:39:23,066 --> 00:39:26,156
And as you can see, we
sent a delete request--


771
00:39:26,326 --> 00:39:30,546
Safari sent a delete request
to the web server saying to--


772
00:39:30,546 --> 00:39:34,876
telling the web server to
unsubscribe this device token


773
00:39:34,876 --> 00:39:37,846
and not to send any
more push notifications


774
00:39:37,846 --> 00:39:38,886
to this device token.


775
00:39:39,786 --> 00:39:43,506
And if they happen to have
a great deal and you decide


776
00:39:43,506 --> 00:39:46,666
to fly them again, you
can just click Allow


777
00:39:46,666 --> 00:39:48,836
and we will send
back that same--


778
00:39:48,836 --> 00:39:53,816
we will send back your
device token via that same--


779
00:39:53,816 --> 00:39:57,076
we will send it to the web
server via that same endpoint.


780
00:39:57,706 --> 00:40:03,026
So that is what your web
server will see when users sign


781
00:40:03,026 --> 00:40:06,246
up for Push Notifications
or unsubscribe from them.


782
00:40:07,176 --> 00:40:09,116
Now, let's hand it back to Jon.


783
00:40:09,596 --> 00:40:11,596
[applause]


784
00:40:12,076 --> 00:40:13,246
>> So, you now know
how to implement


785
00:40:13,246 --> 00:40:17,936
and let's talk a little
bit about best practices.


786
00:40:17,936 --> 00:40:19,856
So when it comes to
your notifications,


787
00:40:19,986 --> 00:40:22,996
think about what
notifications can be most useful


788
00:40:23,386 --> 00:40:24,266
to your users.


789
00:40:24,466 --> 00:40:26,796
So all of you that like raise
your hands, you know what it's


790
00:40:26,796 --> 00:40:29,036
like to get annoying
notifications.


791
00:40:29,696 --> 00:40:32,096
Make sure that everything
that you're doing


792
00:40:32,356 --> 00:40:36,006
to send notifications
to users informs them.


793
00:40:37,876 --> 00:40:40,726
Remember that the push
notification service is the best


794
00:40:40,726 --> 00:40:42,816
effort which means we're going
to do our best to deliver them


795
00:40:42,816 --> 00:40:44,466
but there's not necessary
guaranteed


796
00:40:44,466 --> 00:40:45,386
that they'll be delivered.


797
00:40:45,856 --> 00:40:47,366
So think of these
push notifications


798
00:40:47,366 --> 00:40:50,436
as an additional rather than a
primary means of communicating.


799
00:40:51,156 --> 00:40:54,816
Next, remember to take advantage
of that URL format string.


800
00:40:54,816 --> 00:40:57,136
Here is an example of
what we could have done


801
00:40:57,386 --> 00:40:58,686
where the URL format string


802
00:40:58,686 --> 00:41:01,496
in the push package was
something very generic


803
00:41:01,496 --> 00:41:04,826
and we put the entire URL
inside the notification payload.


804
00:41:05,346 --> 00:41:08,686
Well, all that-- you know,
there's a pretty long URL


805
00:41:08,686 --> 00:41:10,766
and so it's taking up space
that we could be using


806
00:41:10,766 --> 00:41:12,816
to actually have in
the notification.


807
00:41:13,156 --> 00:41:15,996
So, taking out what's common
among all of your URLs


808
00:41:15,996 --> 00:41:18,666
and putting that inside
the URL format string means


809
00:41:18,666 --> 00:41:19,816
that you save some space.


810
00:41:20,476 --> 00:41:24,216
In this case, well, remember


811
00:41:24,216 --> 00:41:27,016
to strip the white space
base from JSON payload.


812
00:41:27,016 --> 00:41:31,006
So like in that slide before
with the notification payload


813
00:41:31,006 --> 00:41:35,086
that I showed you, just taking
out that white space saved


814
00:41:35,086 --> 00:41:36,886
like 40 bytes or
something like that which is


815
00:41:36,886 --> 00:41:38,026
like half a sentence, right?


816
00:41:38,186 --> 00:41:39,496
So, remember to do that.


817
00:41:40,006 --> 00:41:44,526
Next to our best practices
for your web server,


818
00:41:44,976 --> 00:41:48,076
remember that when users decide
to unsubscribe and we give--


819
00:41:48,076 --> 00:41:49,876
and we touched that
unsubscribe endpoint,


820
00:41:50,166 --> 00:41:52,596
just remove those tokens
from your web service.


821
00:41:52,986 --> 00:41:57,016
We don't want you to be
wasting your precious resources


822
00:41:57,396 --> 00:42:00,966
delivering push notifications
that will never get displayed.


823
00:42:01,376 --> 00:42:07,576
Remember to take advantage of
the userInfo in the JavaScript


824
00:42:07,856 --> 00:42:09,176
as well as the
authenticationToken


825
00:42:09,176 --> 00:42:13,236
in push package in order for you
to be able to identify the user


826
00:42:13,236 --> 00:42:16,846
that wants to register for
your push notifications.


827
00:42:17,726 --> 00:42:20,576
And finally, the best
practices for your website.


828
00:42:20,636 --> 00:42:23,036
So, think about the kind
of service that you want


829
00:42:23,036 --> 00:42:24,616
to provide your users.


830
00:42:24,936 --> 00:42:26,406
If your website is the kind


831
00:42:26,566 --> 00:42:32,096
that just broadcast a common
notification to all the users,


832
00:42:32,326 --> 00:42:34,696
then all you need
really is a like a file


833
00:42:34,696 --> 00:42:37,656
or just a single database table
nothing but device tokens.


834
00:42:38,106 --> 00:42:40,166
But if you want to
provide an experience


835
00:42:40,216 --> 00:42:43,056
where users can really
tailor the way


836
00:42:43,056 --> 00:42:47,106
that they use push notifications
on your website, you're going


837
00:42:47,106 --> 00:42:51,826
to want to communicate the
User Log in on your website


838
00:42:51,826 --> 00:42:56,196
and associate that
with the device token.


839
00:42:56,346 --> 00:42:59,726
Remember that this is a
feature on Safari 7 on Mavericks


840
00:42:59,726 --> 00:43:02,246
so you want to check for
API ability as an example


841
00:43:02,246 --> 00:43:03,036
of what that looks like.


842
00:43:04,456 --> 00:43:08,996
And remember to ask users to
subscribe at the right time.


843
00:43:09,276 --> 00:43:12,796
You don't know necessarily
how users have landed


844
00:43:12,796 --> 00:43:16,496
on your website and
it's probably your--


845
00:43:16,576 --> 00:43:19,186
and probably they're not going
to want to be asked immediately.


846
00:43:19,766 --> 00:43:22,876
We recommend providing some
kind of switch that allows user


847
00:43:22,876 --> 00:43:26,596
to like physically turn the--


848
00:43:26,596 --> 00:43:29,656
physically turn on push
notifications on your website.


849
00:43:29,656 --> 00:43:31,146
And in the Bay Airlines demo,


850
00:43:31,386 --> 00:43:33,086
we did that through
a Subscribe button.


851
00:43:33,686 --> 00:43:37,686
And finally, think about giving
your users some granularity.


852
00:43:37,936 --> 00:43:40,106
It gives them the opportunity


853
00:43:40,106 --> 00:43:42,796
to really tailor their
experience with your website.


854
00:43:43,056 --> 00:43:46,186
In the Bay Airlines site,
there's multiple types


855
00:43:46,186 --> 00:43:48,716
of notifications that Brian
could have subscribed to.


856
00:43:50,136 --> 00:43:53,336
So for more information,
you can contact Jon Geleynse


857
00:43:53,336 --> 00:43:57,136
and Paul Marcos, our
evangelists online.


858
00:43:57,266 --> 00:43:59,836
There is the Local
and Push Notifications


859
00:43:59,836 --> 00:44:03,316
for Developers page which
contains links to lot


860
00:44:03,316 --> 00:44:05,876
of different references
that give you more details


861
00:44:05,876 --> 00:44:07,316
about notifications in general.


862
00:44:07,316 --> 00:44:09,466
And for those of you
which should be all of you


863
00:44:09,556 --> 00:44:15,546
that have access to the preview
of the developer publications,


864
00:44:15,756 --> 00:44:17,756
there is a guide called
Notifications Programming Guide


865
00:44:17,756 --> 00:44:19,896
for Websites that gives
much more detail about how


866
00:44:19,896 --> 00:44:22,126
to implement push
notifications for your website.


867
00:44:22,126 --> 00:44:25,276
And of course, there's
always the Safari Developer


868
00:44:25,276 --> 00:44:26,726
for all of us.


869
00:44:27,046 --> 00:44:29,376
So, push notifications
for websites is just one


870
00:44:29,376 --> 00:44:31,466
of many awesome new
features in Safari.


871
00:44:31,716 --> 00:44:34,586
I recommend listening to
Tuesday's video on What's New


872
00:44:34,586 --> 00:44:36,656
in Safari WebKit
for Web Developers.


873
00:44:37,616 --> 00:44:40,456
And as I mentioned before that,
push package is very similar


874
00:44:40,676 --> 00:44:42,356
to the way that passes are made


875
00:44:42,706 --> 00:44:45,346
and I would recommend you
listening to Wednesday's talk


876
00:44:45,346 --> 00:44:47,446
on Integrating Passbook
into Your Ecosystem.


877
00:44:47,646 --> 00:44:48,866
It's a really interesting
to talk


878
00:44:48,866 --> 00:44:51,756
about how Apple Online
Store adopted passbook


879
00:44:51,756 --> 00:44:53,096
and they have some
interesting uses


880
00:44:53,276 --> 00:44:55,156
for that authenticationToken.


881
00:44:56,096 --> 00:45:00,516
So just in summary, I'm really
please to announce that Safari 7


882
00:45:00,516 --> 00:45:02,716
on Mavericks now
allows your website


883
00:45:02,896 --> 00:45:06,396
to send push notifications
to your users.


884
00:45:07,556 --> 00:45:10,606
And we've done everything we
can to make push notifications


885
00:45:10,606 --> 00:45:14,196
for your website and those for
your apps the exact same thing.


886
00:45:14,196 --> 00:45:19,346
Safari knows that it is
you that is that wants


887
00:45:19,346 --> 00:45:22,206
to send push notifications
to your users


888
00:45:22,346 --> 00:45:23,766
because we asked your server


889
00:45:23,766 --> 00:45:25,316
to create something we
called a push package


890
00:45:25,356 --> 00:45:28,116
that signed using a
website push certificate.


891
00:45:28,116 --> 00:45:29,926
I love push notifications


892
00:45:29,926 --> 00:45:32,546
because they tell me the
information that I want to know


893
00:45:32,546 --> 00:45:35,316
at the best time it is for me to
know them and I'm really excited


894
00:45:35,316 --> 00:45:39,146
to see how you integrate push
notifications into your website.


895
00:45:40,026 --> 00:45:41,036
Not only this is
going to be great


896
00:45:41,036 --> 00:45:43,366
because your Mac users will
be able to take advantage


897
00:45:43,366 --> 00:45:45,596
of this great feature when
they visit your website,


898
00:45:45,926 --> 00:45:48,946
but I really believe you're
going to see increased traffic


899
00:45:48,946 --> 00:45:51,846
when people return to
your website as a result


900
00:45:51,846 --> 00:45:53,236
of using these push
notifications.


901
00:45:53,816 --> 00:45:55,846
All right, thanks for listening.


902
00:45:55,846 --> 00:45:58,116
Enjoy the rest of the WWDC
and I'll see you at the lab.


903
00:45:58,716 --> 00:46:03,560ddle
[ Applause ]


904
00:45:58,716 --> 00:46:03,560
[ Applause ]

