Notification Programming Guide for Websites Contents

About Notifications for Websites 4 At a Glance 5 Users Control Their Notifications 5 Push Notifications Are Deployed from Your Server 5 Local Notifications Are Invoked with JavaScript 5 See Also 5

Understanding the User Experience 7 Local Versus Website Push Notifications 7 Opting In to Notifications 9 Users Can Change Their Notification Preferences 10

Configuring Safari Push Notifications 12 Registering with Apple 12 Certificate Revocation 13 Building the Push Package 14 The Website JSON 15 The Iconset 16 The Manifest 16 The Signature 16 Requesting Permission 17 Configuring Your Web Service Endpoints 20 Downloading Your Website Package 20 Registering or Updating Device Permission Policy 20 Forgetting Device Permission Policy 21 Logging Errors 21 Pushing Notifications 22 Troubleshooting 24

Configuring Local Notifications 26 Requesting Permission 26 Creating and Interacting with Local Notifications 27

Document Revision History 31

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 2 Figures, Tables, and Listings

About Notifications for Websites 4 Figure I-1 Notifications in Notification Center 4

Understanding the User Experience 7 Figure 1-1 A banner showing a local notification 7 Figure 1-2 A local notification in Notification Center 7 Figure 1-3 A banner showing a push notification sent from a web server 8 Figure 1-4 A push notification in Notification Center 8 Figure 1-5 Requesting to display local notifications 9 Figure 1-6 Requesting to display push notifications 9 Figure 1-7 Controlling which websites have authorization to send notifications 10 Figure 1-8 Adjusting the appearance of notifications 11

Configuring Safari Push Notifications 12 Figure 2-1 Register as a push provider with Apple 13 Figure 2-2 The user controls their notification permissions 17 Figure 2-3 The resulting push notification 23 Table 2-1 Allowed keys in the website.json file 15 Table 2-2 The permission object structure 18 Table 2-3 A web service’s endpoint URL fragments 20 Table 2-4 Alert dictionary structure 23 Table 2-5 Logging endpoint error 24 Listing 2-1 File structure of a push package 14 Listing 2-2 A sample valid website.json file 15 Listing 2-3 Handling permissions for website push notifications 19 Listing 2-4 A JSON dictionary showing a sample notification payload 22

Configuring Local Notifications 26 Figure 3-1 A dialog box prompting for permission 27 Figure 3-2 A notification banner 27 Figure 3-3 A notification in Notification Center 28 Table 3-1 Available notification events 28 Listing 3-1 Implementing local notification support 29

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 3 About Notifications for Websites

Important: This is a preliminary document for an API or technology in development. Although this document has been reviewed for technical accuracy, it is not final. This Apple confidential information is for use only by registered members of the applicable Apple Developer program. Apple is supplying this confidential information to help you plan for the adoption of the technologies and programming interfaces described herein. This information is subject to change, and software implemented according to this document should be tested with final software and final documentation. Newer versions of this document may be provided with future seeds of the API or technology.

Notifications are concise, unobtrusive messages that appear in the top-right corner of the screen, alerting Mac users about a new message or a completed task. As a web developer, you can configure your website to send notifications to Mac users, even if you don’t have a native Cocoa app.

Figure I-1 Notifications in Notification Center

There are two kinds of notifications for websites:

● Safari Push Notifications, which is an Apple-exclusive technology and triggered remotely using Apple Push Notification service (APNs).

● Local Notifications, which are specified by a W3C standard and triggered locally using JavaScript.

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 4 About Notifications for Websites At a Glance

Note: This document pertains to OS X only. Notifications for websites do not appear on iOS.

At a Glance This document explains the key concepts of notifications for websites and how to implement them in your ecosystem.

Users Control Their Notifications Review the preferences available to users to better understand how to implement your notification service.

Relevant Chapter: “Understanding the User Experience” (page 7)

Safari Push Notifications Are Deployed from Your Server In OS X v10.9 and later, you can send push notifications to your website users. Safari doesn’t need to be open for the notification to appear, and your visitors have control over their notification settings on a per-website basis.

Relevant Chapter: “Configuring Safari Push Notifications” (page 12)

Local Notifications Are Invoked with JavaScript In OS X v10.8 and later, you can tap into Notification Center through a JavaScript API. After visitors grant permission to receive local notifications, you can trigger notifications to appear as long as the webpage remains in an open tab.

Relevant Chapter: “Configuring Local Notifications” (page 26)

See Also ● WWDC 2013: Implementing OS X Push Notifications for Websites shows best practices for implementing push notifications for websites.

● Local and Push Notification Programming Guide describes how to send push notifications to iOS and OS X apps.

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 5 About Notifications for Websites See Also

● WebKit DOM Programming Topics describes other JavaScript APIs available to WebKit browsers.

● Safari Web Content Guide describes how to create websites for Safari.

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 6 Understanding the User Experience

To best serve notifications to your users, you must first understand how OS X displays notifications. In this chapter, you learn the difference between local notifications and push notifications for websites, how users grant permission for websites to display notifications, and how users manage their notification preferences.

Local Versus Website Push Notifications Starting in OS X v10.8, Safari users can allow websites to display banners and alerts in Notification Center. Through a JavaScript API, you can create notifications that appear and behave like notifications from native Cocoa apps, as shown in Figure 1-1 and Figure 1-2.

Figure 1-1 A banner showing a local notification

Figure 1-2 A local notification in Notification Center

Because local notifications are controlled entirely by JavaScript, the user must have your website open in a Safari window (or tab) for your notification to appear. Safari can be minimized or hidden, or your website could be loaded in an inactive tab, but it must be open to run the JavaScript that creates the notification.

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 7 Understanding the User Experience Local Versus Website Push Notifications

Local notifications display the Safari icon, and appear under the Safari section in Notification Center. The Safari section in Notification Center is where local notifications from all websites appear. The notification title, domain, and body are shown. Because local notifications appear as coming from Safari, rather than from your website directly, the user’s notification preferences for Safari are applied.

Push notifications are similar to local notifications. They exhibit the same appearance, except that they have their own icon and section in Notification Center, as shown in Figure 1-3 and Figure 1-4.

Figure 1-3 A banner showing a push notification sent from a web server

Figure 1-4 A push notification in Notification Center

Unlike local notifications, push notifications don’t display the website domain, because the icon makes it clear which website it represents. More importantly, push notifications can be received even when Safari is closed.

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 8 Understanding the User Experience Opting In to Notifications

Note: If you already have an OS X app, you should push notifications through your app. To avoid sending duplicate notifications to users who accept notifications from both your app and website, you need to add extra logic in your server-side scripts. See “Configuring Your Web Service Endpoints” (page 20).

Opting In to Notifications Users must opt in to receive notifications. The opt-in process only occurs once per domain. The presentation of asking for permission is identical for all website notifications. In fact, the permission policy that a user chooses for push notifications applies to local notifications. Compare the appearance of requesting both kinds of notifications in Figure 1-5 and Figure 1-6.

Figure 1-5 Requesting to display local notifications

Figure 1-6 Requesting to display push notifications

As you can see, the permission sheets for local and push notifications look very similar. The request appears only once; after a user sets the permission level, the preference is saved.

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 9 Understanding the User Experience Users Can Change Their Notification Preferences

Remember: Allowing or denying a request for push notifications sets the same permission level for local notifications as well.

Users Can Change Their Notification Preferences Users can adjust their notification preferences in Safari preferences and .

In Safari preferences, users can choose to allow or deny notifications from websites on a per-domain basis by selecting Notifications, as shown in Figure 1-7. In the Notifications pane, users can grant permission for some websites to send notifications while denying permission to others.

Figure 1-7 Controlling which websites have authorization to send notifications

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 10 Understanding the User Experience Users Can Change Their Notification Preferences

Users choose how they want notifications to appear in the Notifications pane of System Preferences, as shown in Figure 1-8. Local notifications respect the preferences set for Safari, and push notifications respect the preferences for each website that issues push notifications. Some users may prefer that notifications display as alerts, which stay on the screen until dismissed. Other users may choose not to display notifications at all.

Figure 1-8 Adjusting the appearance of notifications

Because some users may have configured their system or browser to block your notifications, be sure you present only information that is informative. Never use a notification to provide crucial information.

Your website becomes notified if a user changes their preferences for a website employing push notifications. You can use this information to change the notification settings for your user’s account in your web interface. For more information, skip down to “Configuring Your Web Service Endpoints” (page 20).

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 11 Configuring Safari Push Notifications

In OS X v10.9 and later, you can dispatch Safari Push Notifications from your web server directly to OS X users by using the Apple Push Notification service (APNs). Not to be confused with local notifications, push notifications can reach your users regardless of whether your website or Safari is open.

To integrate push notifications in your website, you first present an interface that allows the user to opt in to receive notifications. If the user consents, Safari your website requesting its credentials in the form of a file called a push package. The push package also contains notification assets used throughout OS X and data used to communicate to a web service you configure. If the push package is valid, you receive a unique identifier for the user on the device known as a device token. The user receives the notification when you send the combination of this device token and your message, or payload, to APNs.

Upon receiving the notification, the user can click on it to open a webpage of your choosing in Safari.

Note: If you need a refresher on APNs, read the “Apple Push Notification Service” chapter in Local and Push Notification Programming Guide. Although the document is specific to iOS and OS X push notifications, paradigms of the push notification service still apply.

Registering with Apple You are required to register in the Certificates, Identifiers & Profiles section of the Member Center to send push notifications. Registration requires an iOS developer license or Mac developer license.

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 12 Configuring Safari Push Notifications Registering with Apple

When registering, include the following information:

● Identifier. This is your unique reverse-domain string, such as web.com.example.domain (the string must start with web.). This is also known as the Website Push ID.

● Website Push ID Description. This is the name used throughout the Provisioning Portal to refer to your website. Use it for your own benefit to label your Website Push IDs into a more human-readable format.

The registration process looks like the form in Figure 2-1.

Figure 2-1 Register as a push provider with Apple

After you have successfully entered this information, the certificate you use to sign your credentials and to push notifications becomes available to download.

Certificate Revocation To protect OS X users, Apple reserves the right to revoke your certificate if you abuse the push notification service or fail to adhere to Apple’s guidelines. Certificate revocation results in the inability to issue new push notifications.

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 13 Configuring Safari Push Notifications Building the Push Package

If your push certificate has been compromised, you can manually revoke it from Apple’s servers in the Certificates, Identifiers & Profiles section of the Member Center.

Building the Push Package When a user is asked for permission to receive push notifications, Safari asks your web server for a package. The package contains data that is used by the notification UI, such as your website name and icon, as well as a cryptographic signature. The signature verifies that your notification hasn’t been intercepted by a man-in-the-middle attack and that it is indeed coming from a trusted source: you.

You create the push package by first populating a folder with a specific set of . The push package contains a website JSON dictionary, a set of icons (referred to as an iconset), a manifest, and a signature. Listing 2-1 exemplifies the complete push package file structure.

Listing 2-1 File structure of a push package

BayAirlines.pushpackage/ icon.iconset/ icon_16x16.png [email protected] icon_32x32.png [email protected] icon_128x128.png [email protected] manifest.json signature website.json

Note: Be sure to remove any metadata files, such as the .DS_Store file, from your package.

After the required files are in place, compress the folder into a ZIP archive to create the finalized push package. The push package can either be served as a static file or generated dynamically per user (as long as the Content-type header matches application/zip). Return the push package from your web server in the location you specify in “Downloading Your Website Package” (page 20).

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 14 Configuring Safari Push Notifications Building the Push Package

The Website JSON Dictionary The website JSON dictionary named website.json contains metadata used by Safari and Notification Center to present UI to the user and to communicate with your web service.

The keys of the website JSON dictionary shown in Listing 2-2 are described in Table 2-1 (page 15).

Listing 2-2 A sample valid website.json file

{ "websiteName": "Bay Airlines", "websitePushID": "web.com.example.domain", "allowedDomains": ["http://domain.example.com"], "urlFormatString": "http://domain.example.com/%@/?flight=%@", "authenticationToken": "19f8d7a6e9fb8a7f6d9330dabe", "webServiceURL": "https://example.com/push" }

Table 2-1 Allowed keys in the website.json file

Key Description

websiteName The website name. This is the heading used in Notification Center.

websitePushID The Website Push ID, as specified in your registration with the Member Center.

allowedDomains An array of websites that are allowed to request permission from the user.

urlFormatString The URL to go to when the notification is clicked. Use %@ as a placeholder for arguments you fill in when delivering your notification. This URL must use the http or https scheme; otherwise, it is invalid.

authenticationToken A string that helps you identify the user. It is included in later requests to your web service. This string must 16 characters or greater.

webServiceURL The location used to make requests to your web service. The trailing slash should be omitted.

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 15 Configuring Safari Push Notifications Building the Push Package

The Iconset The iconset is a directory called icon.iconset that contains PNG images in varying sizes. The images in your iconset populate the icons displayed to the user in the permission prompt, Notification Center, and the notification itself. Because your icon is static, it is unnecessary to include it in every push notification. Instead, your icons are downloaded once from your server and stored on the user’s computer. Icons in the icon set are named with the convention shown in Listing 2-1 (page 14) with the dimensions each name implies.

Note: All six images must be in the iconset for it to be considered valid.

The Manifest The manifest is a JSON dictionary named manifest.json that contains an entry for each file, where the local file path is the entry’s key, and the file’s SHA1 checksum is the entry’s value; for example:

{ "website.json": "96838c40594f632cc25d7760fa404c728886b3a8", "icon.iconset/icon_16x16.png": "865f103703cbb85e1867793e1c798d96a63417e1", ... }

Every file in the package must appear in the manifest, except for the manifest itself and the signature. Each key and value must be a string.

To manually generate a SHA1 checksum, type openssl sha1 in a Terminal prompt. The create_manifest function in the attached createPushPackage.php companion file (the link is near the top of the page) iterates through each file and generates a checksum for you.

Note: The manifest must strictly conform to RFC 4627.

The Signature The signature is a PKCS #7 detached signature of the manifest file. Sign the manifest file with the private key associated with your web push certificate that you obtained while registering with Apple. In PHP, you can do this with the openssl_pkcs7_sign function. The create_signature function in the attached createPushPackage.php companion file (the link is near the top of the page) shows how you can do this.

If the contents of your push package ever change, you’ll need to recompute your signature.

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 16 Configuring Safari Push Notifications Requesting Permission

Requesting Permission There are two important JavaScript functions to keep in mind when dealing with push notifications. The first is a lightweight function that checks the user’s permission level without talking to the server. The second contacts with the server and displays the permission dialog to the user, as shown in Figure 2-2.

Figure 2-2 The user controls their notification permissions

To check the permission level a user has set for your website, call window.safari.pushNotification.permission() with your Website Push ID as an argument. This synchronous call returns a permission object for the given identifier by looking in the user’s preferences. This function does not contact your server.

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 17 Configuring Safari Push Notifications Requesting Permission

Important: Make sure that your web server is using a real certificate issued from a Certificate Authority, not a self-signed certificate. If your certificate is self-signed, push notifications won’t reach your users.

The permission object contains the keys as described in Table 2-2.

Table 2-2 The permission object structure

Key Description

permission The permission level set by the user; possible values are:

● default — The user hasn’t yet been asked his or her permission. This also is the value if the user removes the permission for this site in Safari preferences.

● granted — The user has allowed permission for the website to send push notifications.

● denied — The user denied permission for the website to send push notifications.

deviceToken The unique identifier for the user on the device. Only present if permission is granted.

To request permission to send the user push notifications, call window.safari.pushNotification.requestPermission(). Requesting permission is an asynchronous call.

window.safari.pushNotification.requestPermission(url, websitePushID, userInfo, callback);

A description of each argument is as follows:

● url—The URL of the web service, which must start with https. The web server does not need to be the same domain as the website requesting permission.

● websitePushID—The Website Push ID, which must start with web..

● userInfo—An object to pass to the server. Include any data in this object that helps you identify the user requesting permission.

● callback—A callback function, which is invoked upon completion. The callback must accept a permission object with the same structure as described in Table 2-2 (page 18).

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 18 Configuring Safari Push Notifications Requesting Permission

Listing 2-3 Handling permissions for website push notifications

document.body.onload = function() { // Ensure that the user can receive Safari Push Notifications. if ('safari' in window && 'pushNotification' in window.safari) { var permissionData = window.safari.pushNotification.permission('web.com.example.domain'); checkRemotePermission(permissionData); } };

var checkRemotePermission = function (permissionData) { if (permissionData.permission === 'default') { // This is a new web service URL and its validity is unknown. window.safari.pushNotification.requestPermission( 'https://domain.example.com', // The web service URL. 'web.com.example.domain', // The Website Push ID. {}, // Data that you choose to send to your server to help you identify the user. checkRemotePermission // The callback function. ); } else if (permissionData.permission === 'denied') { // The user said no. } else if (permissionData.permission === 'granted') { // The web service URL is a valid push provider, and the user said yes. // permissionData.deviceToken is now available to use. } };

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 19 Configuring Safari Push Notifications Configuring Your Web Service Endpoints

Configuring Your Web Service Endpoints When a webpage requests permission to display push notifications, an HTTP request for your credentials is sent to your web server. Similarly, when a user changes their website push notification settings in Safari or System Preferences, an HTTP request is sent to your web server. You need to configure a RESTful web service on your server to respond to these requests accordingly. The web service does not need to be hosted on the same server(s) or domain(s) that serve your webpages.

To properly implement the web service, craft your endpoints as specified in the following sections using the URL fragments listed in Table 2-3.

Table 2-3 A web service’s endpoint URL fragments

Fragment Description

webServiceURL The URL to your web service; this is the same as the url parameter in window.safari.pushNotification.requestPermission(). Must start with https.

version The version of the API. Currently, “v1”.

deviceToken The unique identifier for the user on the device.

websitePushID The Website Push ID.

Downloading Your Website Package When a user allows permission to receive push notifications, a POST request is sent to the following URL:

webServiceURL/version/pushPackages/websitePushID

This POST request contains the following information:

● In the HTTP body. The same user info JSON object that is passed as the third argument of the requestPermission() call. Use the user info dictionary to identify the user.

When serving the push package, return application/zip for the Content-type header.

Registering or Updating Device Permission Policy When users first grant permission, or later change their permission levels for your website, a POST request is sent to the following URL:

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 20 Configuring Safari Push Notifications Configuring Your Web Service Endpoints

webServiceURL/version/devices/deviceToken/registrations/websitePushID

This POST request contains the following information:

● In the HTTP header. An Authorization header. Its value is the word ApplePushNotifications and the authentication token, separated by a single space. The authentication token is the same token that’s specified in your package’s website.json file. Your web service can use this token to determine which user is registering or updating their permission policy.

Respond to this request by saving the device token in a database that you can later reference when you send push notifications. Also, change the user’s settings in your database to the values indicated by the parameterized dictionary for the device.

If you have an iOS app that sends push notifications, and users log in to your app with the same credentials they use to log in to your website, set their website push notification settings to match their existing iOS push notification settings.

Forgetting Device Permission Policy If a user removes permission of a website in Safari preferences, a DELETE request is sent to the following URL:

webServiceURL/version/devices/deviceToken/registrations/websitePushID

This DELETE request contains the following information:

● In the HTTP header. An Authorization header. Its value is the word ApplePushNotifications and the authentication token, separated by a single space. The authentication token is the same token that’s specified in your package’s website.json file. Your web service can use this authentication token to determine which user is removing their permission policy.

Use this authentication token to remove the device token from your database, as if the device had never registered to your service.

Logging Errors If an error occurs, a POST request is sent to the following URL:

webServiceURL/version/log

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 21 Configuring Safari Push Notifications Pushing Notifications

This POST request contains the following information:

● In the HTTP body. A JSON dictionary containing a single key, named logs, which holds an array of strings describing the errors that occurred.

Use this endpoint to help you debug your web service implementation. The logs contain a description of the error in a human-readable format. See “Troubleshooting” (page 24) for a list of possible errors.

Pushing Notifications You send push notifications to clients in the same way that iOS and OS X apps push notifications to APNs. As a push notification provider, you communicate with APNs over a binary interface. This a high-speed, high-capacity interface uses a streaming TCP socket design with binary content. The binary interface is asynchronous.

The binary interface of the production environment is available through gateway.push.apple.com, port 2195. Do not connect to the development environment to send Safari Push Notifications. You may establish multiple parallel connections to the same gateway or to multiple gateway instances.

For each interface, use TLS (or SSL) to establish a secured communications channel. The SSL certificate required for these connections is the same one that’s provisioned when you registered your Website Push ID in the Member Center. To establish a trusted provider identity, present this certificate to APNs at connection time.

A JSON dictionary like the one in Listing 2-4 produces a notification that looks like the one in Figure 2-3. The JSON object must strictly conform to RFC 4627.

Listing 2-4 A JSON dictionary showing a sample notification payload

{ "aps": { "alert": { "title": "Flight A998 Now Boarding", "body": "Boarding has begun for Flight A998.", "action": "View"

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 22 Configuring Safari Push Notifications Pushing Notifications

}, "url-args": ["boarding", "A998"] } }

Figure 2-3 The resulting push notification

The outermost dictionary, which is identified by the aps key, should contain another dictionary named alert. The alert dictionary may contain only the keys listed in Table 2-4. Custom keys are not supported.

Table 2-4 Alert dictionary structure

Key Description

title Required. The title of the notification. (“Flight A998 Now Boarding” in Figure 2-3.)

body Required. The body of the notification. (“Boarding has begun for Flight A998.” in Figure 2-3.)

action Optional. The label of the action button, if the user sets the notifications to appear as alerts. This label should be succinct, such as “Details” or “Read more”. If omitted, the default value is “Show”.

Note: You are responsible for handling the internationalization of the notification. the text of your notification to your users’ language before sending to APNs.

The optional url-args key specifies an array of values that are paired with the placeholders inside the urlFormatString value of your website.json file. The order of the placeholders in the URL format string determines the order of the values supplied by the url-args array.

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 23 Configuring Safari Push Notifications Troubleshooting

Important: The maximum size of the notification payload is 256 bytes.

For a low-level breakdown of notification packets, as well as a code listing of how to send a notification over a binary interface, read “Provider Communication with Apple Push Notification Service” in Local and Push Notification Programming Guide.

Troubleshooting If something goes wrong in downloading your push package or delivery of your push notifications, the logging endpoint on your web service as described in “Logging Errors” (page 21) will be contacted with an error message describing the error. Table 2-5 lists the possible errors and steps you can take to fix them.

Table 2-5 Logging endpoint error messages

Error message Resolution

authenticationToken must be at The authenticationToken key in your website.json file least 16 characters. must be 16 characters or greater. See “The Website JSON Dictionary” (page 15).

Downloading push notification The push package could not be retrieved from the location package failed. specified in “Downloading Your Website Package” (page 20).

Extracting push notification package Make sure that your push package is zipped correctly. See failed. “Building the Push Package” (page 14).

Missing file in push notification Make sure that your push package contains all of the files package. specified in “Building the Push Package” (page 14).

Missing image in push notification Make sure that your push package contains all of the files package. specified in “The Iconset” (page 16).

Missing key in website.json. Make sure that your website.json file has all of the keys listed in “The Website JSON Dictionary” (page 15).

Serialization of JSON in The website.json file in your push package is not valid website.json failed. JSON. See “The Website JSON Dictionary” (page 15).

Signature verification of push package The manifest was not signed correctly or was signed using an failed. invalid certificate. See “The Signature” (page 16).

Unable to create notification The extracted push package could not be saved to the user’s for push notification package. disk.

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 24 Configuring Safari Push Notifications Troubleshooting

Error message Resolution

Unable to generate ICNS file for push Your iconset may have malformed PNGs. See “The notification package. Iconset” (page 16).

Unable to parse webServiceURL. Make sure that the value for webServiceURL in your website.json file is a valid URL. See “The Website JSON Dictionary” (page 15).

Unable to save push notification The push package could not be saved to the user’s disk. package.

urlFormatString must have http Make sure that the value for urlFormatString in your or https scheme. website.json file starts with http or https. See “The Website JSON Dictionary” (page 15).

Verifying hashes in manifest.json The SHA1 checksums specified in your manifest.json file failed. do not compute to their actual values. See “The Manifest” (page 16).

Web Service API URL must be https. Make sure that the URL at your push package endpoint starts with https. See “Downloading Your Website Package” (page 20).

webServiceURL must be equal to Cross-check that the web service URL in your JavaScript call URL in call to requestPermission. matches the web service URL in your website.json file. See “Requesting Permission” (page 17).

websitePushID must be equal to Cross-check that the identifier in your JavaScript call matches identifier in call to the identifier in your website.json file. See “Requesting requestPermission. Permission” (page 17).

x cannot be used as a format string The URL created by inserting the notification payload’s for URLs. url-args values into the placeholders specified in the push package’s urlFormatString is not valid, or there are a different number of values than placeholders. See “Pushing Notifications” (page 22).

Also check Web Inspector for errors that might occur in your JavaScript. To learn how to use Web Inspector, read Safari Web Inspector Guide.

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 25 Configuring Local Notifications

As of OS X v10.8, webpages in Safari can post notifications to the systemwide notification system known as Notification Center. Local notifications are dispatched by the WebKit Notification object and follow the implementation outlined by the W3C specification.

Requesting Permission Because your website’s visitors could be running an older version of OS X, first determine whether notifications are supported by their browser. Do this by making sure that the window.Notification object is defined.

Extensions Note: When implementing notifications in extensions, you do not need to check for the permission level. Since users proactively install extensions, permission is granted automatically.

If the window.Notification object does indeed exist, you can continue to check for permissions by accessing the permission property. The permission property can return three possible states:

● default—The user has not yet specified whether he or she approves of notifications being sent from this domain.

● granted—The user has given permission for notifications to be sent from this domain.

● denied—The user has denied permission for notifications to be sent from this domain.

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 26 Configuring Local Notifications Creating and Interacting with Local Notifications

If the permission level is default, it’s likely that the user hasn’t yet been prompted to grant access to notifications from your domain. Prompt your users with a Safari dialog box, as shown in Figure 3-1, by calling the requestPermission() function on the Notification object. This function accepts one parameter, a callback function, which executes when the user grants or denies permission.

Figure 3-1 A dialog box prompting for permission

Creating and Interacting with Local Notifications Creating a local notification is as simple as creating a new object.

var n = new Notification(title [, options]);

The only required parameter is the title, which is a string. Available keys that can be included in the options object are as follows:

● body—The notification’s subtitle.

● tag—The notification’s unique identifier. This tag prevents duplicate entries from appearing in Notification Center if the user has multiple instances of your website open.

The notification is placed in a queue and is shown when it isn’t preceded by another notification. The subtitle is always the domain or extension name from which the notification originated, and the icon is always the Safari icon, as shown in Figure 3-2.

Figure 3-2 A notification banner

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 27 Configuring Local Notifications Creating and Interacting with Local Notifications

Note: Even though you can show an unlimited amount of notifications, show notifications only when necessary. In this way you avoid annoying your users.

A notification stays in Notification Center (see Figure 3-3) until the user explicitly clears all notifications from Safari, or until you close the notification programmatically. To close notifications programmatically, call the close() function on the notification object.

Figure 3-3 A notification in Notification Center

To remove a local notification from Notification Center immediately after it is clicked, call close() in the notification’s onclick event handler. The onclick event handler, and other JavaScript event handlers, are listed in Table 3-1.

Table 3-1 Available notification events

Event handler Description

onshow An event that triggers when the notification is first presented onscreen.

onclick An event that triggers if the user clicks on the notification as an alert, a banner, or in Notification Center. By default, clicking a notification brings the receiving window into focus, even if another app is in the foreground.

onclose An event that triggers when the notification is dismissed, or closed in Notification Center. Calling close() on the notification object triggers the onclose event handler.

onerror An event that triggers when the notification cannot be presented to the user. This event is fired if the permission level is set to denied or default.

Listing 3-1 shows how to send a local notification while adhering to the permission level a user has set.

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 28 Configuring Local Notifications Creating and Interacting with Local Notifications

Listing 3-1 Implementing local notification support

var notify = function () { // Check for notification compatibility. if (!'Notification' in window) { // If the browser version is unsupported, remain silent. return; } // Log current permission level console.log(Notification.permission); // If the user has not been asked to grant or deny notifications // from this domain... if (Notification.permission === 'default') { Notification.requestPermission(function () { // ...callback this function once a permission level has been set. notify(); }); } // If the user has granted permission for this domain to send notifications... else if (Notification.permission === 'granted') { var n = new Notification( 'New message from Liz', { 'body': 'Liz: "Hi there!"', // ...prevent duplicate notifications 'tag' : 'unique string' } ); // Remove the notification from Notification Center when clicked. n.onclick = function () { this.close(); }; // Callback function when the notification is closed. n.onclose = function () { console.log('Notification closed'); };

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 29 Configuring Local Notifications Creating and Interacting with Local Notifications

} // If the user does not want notifications to come from this domain... else if (Notification.permission === 'denied') { // ...remain silent. return; } };

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 30 Document Revision History

This table describes the changes to Notification Programming Guide for Websites.

Date

2013-08-20 New document that describes how to configure websites to send local and push notifications.

2013-08-20 | Copyright © 2013 Apple Inc. All Rights Reserved. Apple Confidential Information. 31 Apple Inc. Copyright © 2013 Apple Inc. All rights reserved.

No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, mechanical, electronic, photocopying, recording, or otherwise, without prior written permission of Apple Inc., with the following exceptions: Any person is hereby authorized to store documentation on a single computer for personal use only and to print copies of documentation for personal use provided that the documentation contains Apple’s copyright notice. No licenses, express or implied, are granted with respect to any of the technology described in this document. Apple retains all intellectual property rights associated with the technology described in this document. This document is intended to assist application developers to develop applications only for Apple-labeled computers. Apple Inc. 1 Infinite Loop Cupertino, CA 95014 408-996-1010

Apple, the Apple logo, Cocoa, Mac, OS X, and Safari are trademarks of Apple Inc., registered in the U.S. and other countries. Java is a registered trademark of Oracle and/or its affiliates. iOS is a trademark or registered trademark of Cisco in the U.S. and other countries and is used under license. Even though Apple has reviewed this document, APPLE MAKES NO WARRANTY OR REPRESENTATION, EITHER EXPRESS OR IMPLIED, WITH RESPECT TO THIS DOCUMENT, ITS QUALITY, ACCURACY, MERCHANTABILITY, OR FOR A PARTICULAR PURPOSE. AS A RESULT, THIS DOCUMENT IS PROVIDED “AS IS,” AND YOU, THE READER, ARE ASSUMING THE ENTIRE RISK AS TO ITS QUALITY AND ACCURACY. IN NO EVENT WILL APPLE BE LIABLE FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES RESULTING FROM ANY DEFECT OR INACCURACY IN THIS DOCUMENT, even if advised of the possibility of such damages. THE WARRANTY AND REMEDIES SET FORTH ABOVE ARE EXCLUSIVE AND IN LIEU OF ALL OTHERS, ORAL OR WRITTEN, EXPRESS OR IMPLIED. No Apple dealer, agent, or employee is authorized to make any modification, extension, or addition to this warranty. Some states do not allow the exclusion or limitation of implied warranties or liability for incidental or consequential damages, so the above limitation or exclusion may not apply to you. This warranty gives you specific legal rights, and you may also have other rights which vary from state to state.