Vous êtes sur la page 1sur 48

Passbook Programming Guide

Contents

About Passbook 5
At a Glance 5 Passes Exist in a Larger Ecosystem 5 Passes Are Created as a Package 6 Passes Are Updated Using Push Notifications and Your Web Server 6 Your App Can Interact with Passes 6 See Also 6

Building Your First Pass 8


Case Study: A Very Simple Coupon 8 Downloading the Sample Pass 8 Creating and Populating the Pass Package 8 Describing the Offer 9 Requesting a Pass Type Identifier 10 Changing the Pass Type ID and Team ID 10 Signing and Compressing the Pass 11 Viewing the Pass 12

Passbook Ecosystem Design 13


You Create and Distribute Passes 13 Passes Are Presented and Managed by the Passbook App 13 Your App Can Interact with Passes Using Pass Kit 13 Your Server Can Update Passes 14 You Are Responsible for Pass Redemption 14 Pass for a One-Time-Use Coupon 14 Pass for a Store Card with a Balance 15 Pass for a Season Membership 15

Pass Design and Creation 17


Passes Are Identified by Pass Type Identifier and Serial Number 17 Required Information Is Provided by Top-Level Keys 18 Pass Style Sets the Overall Visual Appearance 19 Fields Contain Text Displayed on the Pass 23 Fields Support Formatting 25

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

Contents

The Back of the Pass Provides Additional Space for Text 26 Barcodes Link Passes to Your Records 28 Pass Colors Can Be Customized 29 Images Fill Their Allotted Space 30 Relevance Information Displays Passes on the Lock Screen 30 Passes Support Localization 33 Passes Are Cryptographically Signed and Compressed 35 Passes Are Distributed via Email, the Web, or Your App 36 Debugging Passes 36

Updating a Pass 37
Overview of the Communication 37 Devices Register for Updates 40 Your Server Sends a Push Notification When Something Changes 41 Devices Ask for Changed Serial Numbers 41 Devices Ask for Latest Version of Passes 43 Devices Display Change Messages 43 Best Practices 43

Interacting with Passes in Your App 44


Checking Whether the Pass Library Is Available 44 Checking Whether a Pass Is in the Library 45 Getting Passes 45 Reading a Pass 45 Adding a New Pass 46 Changing a Pass 46 Removing a Pass 46

Document Revision History 47

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

Figures, Tables, and Listings

Building Your First Pass 8


Figure 1-1 Listing 1-1 Listing 1-2 Listing 1-3 Viewing the finished pass 12 Setting the description and organization name 9 Describing the offer 9 Setting the pass type ID and team ID 11

Pass Design and Creation 17


Figure 3-1 Figure 3-2 Figure 3-3 Figure 3-4 Figure 3-5 Figure 3-6 Table 3-1 Table 3-2 Listing 3-1 Listing 3-2 Listing 3-3 Listing 3-4 Listing 3-5 Listing 3-6 Directory structure of a sample pass 17 Layout of a boarding pass 21 Layout of a coupon 21 Layout of an event ticket 22 Layout of a generic pass 22 Layout of a store card 23 Pass styles, images, and layout 20 Pass style and relevance information 32 Partial pass showing top-level keys 19 Pass with simple fields 24 Partial pass with date and number formatting 25 Partial pass with back fields 27 Partial pass with a barcode 28 Partial pass with relevance information 31

Updating a Pass 37
Figure 4-1 Interaction between the client and your server 38

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

About Passbook

Passes are a digital representation of information that might otherwise be printed on small pieces of paper or plastic. They let users take an action in the physical world. Passes can contain images and a barcode, and you can update passes using push notifications. The pass library contains the users passes, and users view and manage their passes using the Passbook app.
Server Client

This technology is made of three main parts:

A package format for creating passes. A web service API for updating passes, implemented on your server. An Objective-C API used by your apps to interact with the users pass library.

At a Glance
This document covers the key concepts of the Passbook technology and explains the ways you can use it.

Passes Exist in a Larger Ecosystem


Passes exist within the context of a larger ecosystem including the Passbook app, your servers, the Apple Push Notification service, and your infrastructure for redeeming passes. Each of these components of the ecosystem is responsible for certain parts of the pass lifecycle.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

About Passbook See Also

Relevant Chapter: Passbook Ecosystem Design (page 13)

Passes Are Created as a Package


You create passes by providing data, including a JSON file and image assets, in a package that contains the pass. The JSON file describes the contents of the pass and allows some control over the passs visual appearance. You sign this data using the private key for a certificate that you obtain from Apple. To keep your private key private, you sign passes on your server, not on the users device. Relevant Chapters: Building Your First Pass (page 8), Pass Design and Creation (page 17)

Passes Are Updated Using Push Notifications and Your Web Server
Passes can be updated after you distribute them. Updates use the Apple Push Notification service to inform the device that a new version of the pass is available, and a web service that your server implements to provide the latest version of the pass. Relevant Chapter: Updating a Pass (page 37)

Your App Can Interact with Passes


Your apps can use the Pass Kit framework to interact with passes and the pass library. This allows you to install new passes and integrate passes into your app. Relevant Chapter: Interacting With Passes in Your App (page 44)

See Also
Local and Push Notification Programming Guide describes how to send push notifications. Passbook Package Format Reference describes the package format for defining passes. Passbook Web Service Reference describes the web service protocol for updating passes. Pass Kit Framework Reference describes the Objective-C API for interacting with the users pass library.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

About Passbook See Also

The Passbook support materials are available in the developer downloads area They contain fully-worked example passes, a command-line tool to help you sign passes during development, and a sample implementation of the web service.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

Building Your First Pass

In this tutorial, you will download and edit a sample pass, build it, and view it in the iOS Simulator app.

Case Study: A Very Simple Coupon


Suppose you own a candy shop and you want to email your customers a coupon for a free lollipop. You trust most of your customers and youre only running the promotion until the giant bucket of lollipops runs out, so you dont take any special effort to prevent customers from using their coupon more than once. You create a pass with the same information that you would include on a printed coupon: a description of the offer and some information about your store.

Downloading the Sample Pass


The Passbook Support Materials in the developer downloads area contain several sample passes and a command-line tool called signpass that you will use later, as well as other resources that are not needed for this tutorial.

Creating and Populating the Pass Package


Passes are created as a package containing a pass.json file that defines the pass, and image assets such as the logo and the icon. To create the pass package for your pass, make a new directory in the Documents folder called Lollipop.pass. The .pass extension is a best practice to indicate that the directory is a pass package. Find the sample coupon in the Passbook Support Materials. Open the raw pass package and copy the files it contains to your Lollipop.pass directory.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

Building Your First Pass Describing the Offer

Describing the Offer


The sample pass is already a coupon, but it doesnt have the right details. First, change the description and organization name. Find the following keys in the pass.json file and change their values:
Listing 1-1
{ ... "description" : "Coupon for a free lollipop at Example Candy Store", "logoText" : "Example Candy Store", ... }

Setting the description and organization name

Next, the pass needs to describe the actual offer. This requires three levels of keys, as shown in Listing 1-2. At the top level, find the coupon key which indicates that this pass is a coupon. Its value is a dictionary that describes the coupon. At the second level, find the primaryFields key which shows text on the front of the pass for the offer. Its value is a dictionary that describes the contents of the field. At the third level, the key is a string that uniquely identifies the field within the pass, and the value and label contain text that appears on the pass. Change their values to describe the candy stores offer.
Listing 1-2
{ ... "description" : "Coupon for a free lollipop at Example Candy Store", "logoText" : "Example Candy Store",

Describing the offer

"coupon" : { "primaryFields" : [ { "key": "offer", "value": "Free lollipop" "label": "On July 29" } ] }, ...

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

Building Your First Pass Requesting a Pass Type Identifier

Requesting a Pass Type Identifier


Every pass has a pass type identifier which identifies the class or type of pass. Pass type identifiers are managed in the iOS Provisioning Portal by a team admin. To build this pass, you need to register a pass type identifier. You will use this pass type identifier with your team identifier in the next step. To register a pass type identifier, do the following:
1. 2. 3.

In the iOS Provisioning Portal, go to the Pass Type IDs section. Click the New Pass Type ID button. Enter the description and pass type identifier, and click Submit.

To configure a pass type identifier, do the following:


1.

In the Pass Type IDs section of the iOS Provisioning Portal, click the Configure link next to the pass type identifier. Click the Configure button next to Pass Certificate . Follow the directions that are shown to generate a certificate signing request in Keychain Access, upload it to the iOS Provisioning Portal, and then download the certificate. After you download the certificate, you can delete the certificate signing request.

2. 3.

4.

Open the certificate with Keychain Access to add it to your keychain.

To find your team ID, do the following:


1. 2.

Open Keychain Access and select your certificate. Select File > Get Info and find the Organizational Unit section under Details. This is your team ID. The pass type identifier appears in the certificate under the User ID section.

You can also find your team ID by visiting the Member Center and looking at your organization profile.

Changing the Pass Type ID and Team ID


Edit the pass.json file and find the pass type identifier and team identifier. Change them to match the values from the previous step.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

10

Building Your First Pass Signing and Compressing the Pass

Listing 1-3
{

Setting the pass type ID and team ID

"description" : "Coupon for a free lollipop at Example Candy Store", "logoText" : "Example Candy Store", "coupon" : { "primaryFields" : [ { "key": "offer", "value": "Free lollipop" "label": "On July 29" } ] },

"passTypeIdentifier" : "<<your pass type ID>>", "teamIdentifier" : "<<your team ID>>", }

Signing and Compressing the Pass


In a production environment, the signing and compressing would be part of the system that generates passes. During development, you can use the signpass tool to sign and compress passes that you build by hand. To get the signpass tool, do the following:
1. 2. 3.

Open the Xcode project in the Passbook Support Materials for the signpass tool and build the project. Right-click on the signpass executable (in the Products folder) and select Show in Finder. Move the signpass executable to the Documents folder.

To sign and compress the pass, use the signpass tool to sign the pass package. In Terminal, run the following commands:
cd ~/Documents ./signpass -p ~/Lollipop.pass

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

11

Building Your First Pass Viewing the Pass

This creates a signed and compressed pass named Lollipop.pkpass in the Documents folder. If the pass fails to build, check the pass.json file to make sure the JSON file is well formed. A common error is to misplace commas or braces.

Viewing the Pass


The simplest way to see what a pass looks like during development is in the iOS Simulator app. To view the pass, launch Simulator and drag the Lollipop.pkpass file into the Simulator window. It displays the pass and offers to add it to Passbook, as shown in Figure 1-1.
Figure 1-1 Viewing the finished pass

When testing in the iOS Simulator app, errors are logged to the system log, which you can view with the Console app. If the pass doesnt display and add to Passbook, check the log for a description of what went wrong.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

12

Passbook Ecosystem Design

There are three major parts to the pass life cycle: creation, management, and redemption. Passbook handles the middle; it lets users view and manage their passes and provides lock screen integration. You are responsible for the two ends: creating passes and redeeming passes.

You Create and Distribute Passes


You are responsible for distributing passes to your users. Mail and Safari understand how to work with passeson iOS they install passes directly, and on OS X they install passes via iCloudso you can use them to add passes. Your app can also install passes using the Pass Kit framework.

Passes Are Presented and Managed by the Passbook App


You control the visual appearance by specifying a pass style, providing images, and setting colors and text formatting. Passes contain text, images, and a barcode. The Passbook app handles the details of layout and presenting a pass on the screen for you, and it provides the interface for the user to manage and delete passes.

Your App Can Interact with Passes Using Pass Kit


The Pass Kit framework provides an Objective-C interface for apps to interact with passes in the Passbook library. Companion apps should not duplicate the functionality of the Passbook app, rather they should enrich the user experience by doing things that Passbook cant do such as letting the user ask for a different seat on a flight and then updating the pass. Passes need to be useful use even if the user doesnt have your app installed. Your app can only interact with passes whose pass type identifier matches the apps entitlementseither passes you created or some subset of those passes.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

13

Passbook Ecosystem Design Your Server Can Update Passes

Your Server Can Update Passes


Updating passes is a cooperative effort between your server and Passbook. When information on a pass changes, your server sends a push notification to the users device. The device communicates with your server to find out what has changed and to get the latest version of your passes. Passes are updated by providing the latest version of the pass, not by providing a list of what changed. Anything in the pass can be updated except for the pass type ID and serial number. However, only certain kinds of changes actually make sense to the user. Updating a train ticket to reflect a delayed departure or a store card to show the current balance keeps the pass current and wouldnt cause confusion. Replacing a coupon for a free order of breadsticks with a coupon for a free drink is likely to confuse the userfrom the users perspective, one coupon disappeared and another coupon was unexpectedly added. In that case, you should create a new pass for the drink coupon.

You Are Responsible for Pass Redemption


Policies regarding when passes are valid or how many times they can be redeemed are your responsibility. Likewise, the effects of redeeming a pass such as updating a balance in your records are up to you. The following sections describe several use cases for passes and explain how you might implement them.

Pass for a One-Time-Use Coupon


Suppose you want to give out a coupon for 10 percent off that can only be used once. You include a unique number on each coupon from 1 to 500, and you write the numbers 1 through 500 on a piece of paper next to the cash register. When the cashiers ring up a coupon, they consult the paper and cross off that coupons number. This works on a very small scale, and illustrates the principle of a central trusted authority. You dont control what your customers do with their passes or devices (or even with their paper coupons) so you cant use that as a starting point for trusting information. Instead, you trust your database, and use the pass as a quick way to look up a particular record. The data in the pass itself is just a snapshot of some particular database state. Doing it with passes is similar: the pass includes a unique ID in its barcode, and your server keeps track of which passes are still valid. At the point of redemption, you scan the barcode and consult your server to determine whether the pass is valid. Dont try to make a one-time-use pass by only giving the pass to a single device. Users with multiple iOS devices want your pass on all of their devices and iCloud syncs their passes across devices for them. If you email your pass to your users, they can forward the email and its pass. Your scanning and redemption system is responsible for implementing policies like this pass is only valid once .

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

14

Passbook Ecosystem Design You Are Responsible for Pass Redemption

Dont try to expire or void a pass by pushing an update. Updates are not guaranteed to be delivered: the user may not have a network connection or may have disabled updates for the pass. Instead, update your database to indicate that the pass is invalid, and consult your database when the pass is redeemed. Additionally, your app should not remove expired passes without the users consent.

Pass for a Store Card with a Balance


Suppose you own a coffee shop and your customers typically pay with a card carries a balance, such as a gift card or store card. Similar to the one-time-use pass, you need a piece of information and it must come from a trustworthy source. In that case you needed to know whether the pass was still valid; in this case you want to know the passs current balance. The implementation is similar. Each pass has a unique ID in the barcode which is scanned at the point of sale. Before completing the sale, you consult your server to record the transaction and update the balance. Once this is done, the cashier completes the sale. You could take several approaches to verify that the person presenting the pass is actually the account holder. A store card can include a thumbnail image, so you could put the account holders picture on the pass. For greater security, you could store the account holders picture in your database and display it on the cashiers screen rather than trusting the pass. Other approaches are also possible, such as asking for a photo ID. At some point after the sale, your server pushes an update to the pass with the new balance. This lets your users easily check their balance as its displayed right on the pass. This update can be handled by a different server that implements the web service API.

Pass for a Season Membership


Suppose you work for a museum that supports Passbook for its annual memberships. Most of your exhibits are permanent, but you have one or two special traveling exhibits which change every few months. You want to update the artwork on membership passes to include an image of the current traveling exhibit and include its name on the pass. Ideally, the pass needs a unique ID in the barcode that you can scan at the museum entrance, to verify with your server that the membership is still valid. However, this is an situation where its possible to establish trust without consulting your server. (For example, if your scanners dont have a network connection.) In addition to the unique ID in the barcode, you now include the year that the pass is valid, followed by a cryptographic signature of the ID and year. The signature lets you check that the contents of the barcode came from your server, and is therefore trustworthy. This approach would not let you implement a one-time-use coupon without network access at the scanner; thats essentially an unsolvable problem. It works here because the barcode contains an unchanging facta year that the membership is validand that is the only piece of information needed to determine whether

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

15

Passbook Ecosystem Design You Are Responsible for Pass Redemption

the pass is still valid. Scanning the museum pass doesnt change any state. In contrast, scanning a one-time-use coupon does change state: it voids the coupon. Without network access at the scanner, there is no way to get the latest state of the world before scanning or inform others of a state change after scanning.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

16

Pass Design and Creation

The files that make up a pass are arranged in a package called the pass package. At the center of the pass is a JSON file named pass.json which defines the pass. The file contains information that identifies the pass, the text that appears on it, and other information about the pass. In addition to this file, you provide images and localization data. Figure 3-1 shows the directory structure for a sample pass that provides a background image an icon and a logo, and is localized in Spanish and Chinese. It has both at Retina and non-Retina sizes of the image assets, and a different version of background for the Chinese localization.
Figure 3-1 Directory structure of a sample pass

Most of your work in creating a pass is done by providing keys and values in the pass.json file.

Passes Are Identified by Pass Type Identifier and Serial Number


The pass type identifier is conceptually similar to a bundle identifier or a class name. The value for the passTypeIdentifier key in the pass specifies the pass type identifier. It is a string, chosen by you, that defines a class or category of passes. It always begins with pass. and uses reverse DNS stylefor example, pass.com.example.membership-card. Use the iOS Developer Portal to register for a pass type identifier. The pass type identifier must match the certificate used to sign the pass.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

17

Pass Design and Creation Required Information Is Provided by Top-Level Keys

The exact meaning of each pass type identifier is determined by you. You specify what types of pass an app can interact with as part of the apps entitlements. This allows you to have app-specific passes if you are developing multiple apps. A different certificate is used for signing passes with different pass type identifiers. This means that groups in your company that work with different types of passes dont need to share signing infrastructure, certificates, or private keys. The serial number is a string that uniquely identifies the pass within the scope of its pass type. The value for the serialNumber key in the pass specifies the serial number. The serial number is opaque to Passbook; you are free to assign it in whatever way makes sense. A monotonically increasing integer or a UUID are convenient ways to assign the serial number. The combination of pass type identifier and serial number is used throughout Passbook to uniquely identify a pass. Two passes of the same type with the same serial number are understood to be the same pass, even if other information on them differs. For example, when a pass is updated, the new version has the same pass type identifier and serial number as the old version, so the new version replaces the old version. The difference between pass type identifiers and serial numbers is similar to the difference between classes and instances of a class: pass type identifiers designate an abstract kind of thing, and serial numbers identify a specific concrete thing. For example, suppose an airline is creating passes for boarding passes and for its loyalty card program. All of the boarding passes you create have the same pass type identifier because theyre all the same type of pass, but each one has its own serial number. Loyalty cards have a different pass type identifier than boarding passes, because theyre a different type of pass.

Required Information Is Provided by Top-Level Keys


In addition to the pass type identifier and serial number, there are several other keys that every pass contains. The version of the file format is specified by the formatVersion key; its value is the number 1. The team identifier is a series of letters and numbers issued to you by Apple. You can find it on the iOS Developer Portal or in Keychain Access by looking at the Organizational Unit field of your certificate. The value for the teamIdentifier key in the pass specifies the team ID. The team ID in a pass must match the certificate used to sign the pass. The organization name is displayed on the lock screen when your pass is relevant and by apps such as Mail which act as a conduit for passes. The value for the organizationName key in the pass specifies the organization name. Choose a name that users will recognize and associate with your organization or company.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

18

Pass Design and Creation Pass Style Sets the Overall Visual Appearance

The description lets VoiceOver make your pass accessible to blind and low vision users. The value for the description key in the pass specifies the description. The description should start with a high-level term such as Membership card , Weekly coupon , or Bus ticket followed by one or two small pieces of information such as the coupons offer and the store where its valid. Dont try to summarize the entire contents of the pass, but include enough detail to let users distinguish between passes of the same type.

Pass Style Sets the Overall Visual Appearance


The passs style determines the overall visual appearance of the pass and the template for placement of information on the pass. The most distinctive visual indication of the style is at the top edge of the pass: event tickets have a small cutout, coupons have a perforated edge, and so on. Unlike pass type identifiers, which you define, the pass styles are part of the API, as is their meaning. There is no facility for you to change them or add new ones. Pass type identifiers categorize passes in a very specific way; pass styles categorize passes in a much more general high-level way. You specify the pass style by providing the corresponding key at the top level of the pass.json file:

Boarding passes use the key boardingPass. This pass style is appropriate for passes used with transit systems such as train tickets, airline boarding passes, and other types of transit. Typically each pass corresponds to a single trip with a specific starting and ending point. Coupons use the key coupon. This pass style is appropriate for coupons, special offers, and other discounts. Event tickets use the key eventTicket. This pass style is appropriate for passes used to gain entry to an event like a concert, a movie, a play, or a sporting event. Typically each pass corresponds to a specific event, but you can also use a single pass for several events as in a season ticket. Store cards use the key storeCard. This pass style is appropriate for store loyalty cards, discount cards, points cards, and gift cards. Typically a store identifies an account the user has with your company that can be used to make payments or receive discounts. When the account carries a balance, the current balance should appear on the pass. Generic passes use the key generic. This pass style is appropriate for any pass that doesnt fit into one of the other more specific stylesfor example, gym membership cards, coat check claim tickets, and metro passes that carry a balance.

The value of this key is a dictionary containing the fields that hold the pass content. Listing 3-1 shows a pass that uses the boarding pass style, with a placeholder for the field dictionaries.
Listing 3-1
{

Partial pass showing top-level keys

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

19

Pass Design and Creation Pass Style Sets the Overall Visual Appearance

"description" : "Boarding pass for October 4, San Francisco to London", "formatVersion" : 1, "passTypeIdentifier" : "pass.com.example.boarding-pass", "serialNumber" : "123456", "boardingPass" : { <<field dictionaries>> } }

The pass style controls how fields are laid out and which images can be used. Table 3-1 shows the images supported by each pass style and the number and placement of fields for each pass style. Pass style also affects relevance informationfor details, see Relevance Information Displays Passes On the Lock Screen (page 30).
Table 3-1 Pass style Pass styles, images, and layout Supported images Layout

Boarding pass Coupon Event ticket

logo, icon, footer logo, icon, strip logo, icon, strip, background, thumbnail If you specify a strip image, do not specify a background image or a thumbnail.

See Figure 3-2 (page 21) See Figure 3-3 (page 21) See Figure 3-4 (page 22)

Generic

logo, icon, thumbnail

See Figure 3-5 (page 22)

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

20

Pass Design and Creation Pass Style Sets the Overall Visual Appearance

Pass style

Supported images

Layout

Store card

logo, icon, strip

See Figure 3-6 (page 23)

Figure 3-2

Layout of a boarding pass

Figure 3-3

Layout of a coupon

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

21

Pass Design and Creation Pass Style Sets the Overall Visual Appearance

Figure 3-4

Layout of an event ticket

Figure 3-5
logo

Layout of a generic pass


logo text header fields primary field thumbnail logo logo text header fields primary field thumbnail

secondary fields auxiliary fields

secondary fields

rectangular barcode

square barcode

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

22

Pass Design and Creation Fields Contain Text Displayed on the Pass

Figure 3-6

Layout of a store card

The pass style determines the maximum number of fields that can appear on the front of a pass:

In general, a pass can have up to three header fields, a single primary field, up to four secondary fields, and up to four auxiliary fields. Boarding passes can have up to two primary fields and up to five auxiliary fields. Coupons and store cards can have a total of up to four secondary and auxiliary fields, combined. Event tickets with a background image and generic passes with a square barcode dont support auxiliary fields.

The number of fields displayed on the pass also depends on the length of the text in each field. If there is too much text, some fields may not be displayed.

Fields Contain Text Displayed on the Pass


The information shown on the pass is broken up into fields. Each field is defined by a dictionary which gives it a value and label (which are displayed to the user), a unique key, and optional information about how its value should be formatted. Listing 3-2 shows a pass with a few simple fields. The primary fields contain the most important information and are shown prominently on the pass. Secondary fields are less important and less prominent, and auxiliary fields even less. Header fields contain highly salient information, and they are the only field that is visible when the passes are stacked up in Passbook; use them sparingly.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

23

Pass Design and Creation Fields Contain Text Displayed on the Pass

Listing 3-2
{

Pass with simple fields

"description" : "Boarding pass for October 4, San Francisco to London", "formatVersion" : 1, "passTypeIdentifier" : "pass.com.example.boarding-pass", "serialNumber" : "123456", "boardingPass" : { "primaryFields" : [ { "key" : "origin", "label" : "San Francisco", "value" : "SFO" }, { "key" : "destination", "label" : "London", "value" : "LHR" } ], "secondaryFields" : [ { "key" : "boarding-gate", "label" : "Gate", "value" : "F12" } ], "auxiliaryFields" : [ { "key" : "seat", "label" : "Seat", "value" : "7A" }, { "key" : "passenger-name", "label" : "Passenger",

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

24

Pass Design and Creation Fields Support Formatting

"value" : "John Appleseed" } ], "transitType" : "PKTransitTypeAir" } }

The ordering between the lists of fields is not significant, but the ordering of fields within the list is significant. For example, putting the primary fields before or after the secondary fields doesnt change where the primary and secondary fields appear, but putting the seat assignment before or after the passenger name changes the ordering of those two fields on the pass. This is because the key/value pairs in a dictionary arent ordered, but lists are. For a complete list of the keys used in a field dictionary and their possible values, see Field Dictionary Keys in Passbook Package Format Reference .

Fields Support Formatting


There are three kinds of formatting you can apply to a field: alignment, date formatters, and number formatters:

To set the alignment for a field, specify a value for the alignment key in the field dictionary. To format a date, specify a value for the dateStyle and timeStyle keys in the field dictionary. To format a currency amount or other number, specify a value for the currencyCode or numberStyle key in the field dictionary.

Letting Passbook handle dates, times, and currency amounts ensures the right display formatting based on the users locale. Listing 3-3 shows an example of date and number formatting.
Listing 3-3
{ ...

Partial pass with date and number formatting

"description" : "Concert ticket to see The Hectic Glow", "eventTicket" : { "primaryFields" : [ {

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

25

Pass Design and Creation The Back of the Pass Provides Additional Space for Text

"key" : "event-name", "label" : "Event", "value" : "The Hectic Glow in concert" } ], "secondaryFields" : [ { "dateStyle" : "PKDateStyleMedium", "isRelative" : true, "key" : "doors-open", "label" : "Doors open", "timeStyle" : "PKDateStyleShort", "value" : "2013-08-10T19:30-06:00" }, { "key" : "seating-section", "label" : "Seating section", "numberStyle" : "PKNumberStyleSpellOut", "textAlignment" : "PKTextAlignmentRight", "value" : 5 } ] } }

The Back of the Pass Provides Additional Space for Text


Space on the front of the pass is at a premium: the number of fields is limited, and the contents of fields must be brief. In contrast, the back of the pass can have as many fields as needed and the contents of fields can be much longer. If there is too much content fit on the screen at once, the back lets the user scroll through it. As the contents of each field on the back gets longer, the fields font size is reduced.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

26

Pass Design and Creation The Back of the Pass Provides Additional Space for Text

The back of the pass gives you a place to put information that is too long to fit on the front of the pass, extra information that isnt as important, and general information that may be helpful for your users. Examples of back fields include terms and conditions, the full address of a venue, your customer service phone number, and the URL for your website. Listing 3-4 shows examples of back fields. These go in the same place in the pass file as the rest of the fieldsthis key is a sibling to primaryFields and auxiliaryFields.
Listing 3-4
{ ...

Partial pass with back fields

"backFields" : [ { "key" : "frequent-flier-number", "label" : "Frequent flier number", "value" : "1234-5678" }, { "key" : "website", "label" : "Track my checked bags", "value" : "http://www.example.com/track-bags/XYZ123" }, { "key" : "customer-service", "label" : "Customer service", "value" : "(800) 555-0199" }, { "key" : "terms", "label" : "Terms and Conditions", "value" : "O Fortuna velut luna statu variabilis, semper crescis aut decrescis; vita detestabilis nunc obdurat et tunc curat ludo mentis aciem, egestatem, potestatem dissolvit ut glaciem.\n\n Sors immanis et inanis, rota tu volubilis, status malus, vana salus semper dissolubilis, obumbrata et velata michi quoque niteris; nunc per ludum dorsum nudum fero tui sceleris.\n\n Sors salutis et virtutis michi nunc contraria, est affectus et defectus semper in angaria. Hac in hora

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

27

Pass Design and Creation Barcodes Link Passes to Your Records

sine mora corde pulsum tangite; quod per sortem sternit fortem, mecum omnes plangite!" } ] }

The text of the back fields is run through data detectors for URLs and phone numbers, which appear as live links. Users can tap on the URL to launch it in Safari and on phone numbers to dial them. Text on the back of the card can include line breaks, escaped in the JSON file as \n. To provide a link to an app, provide a list of iTunes Store item identifiers (also known as Adam IDs) as the value of the associatedStoreIdentifiers key at the top level of the pass.json file.

Barcodes Link Passes to Your Records


Your server has the up-to-date records about your business, and the pass is just a copy of those records from some time in the past. The most common use for a barcode is a unique ID that points to corresponding records on your server. This let you consult your server to update a balance, void a coupon, or confirm that a ticket is valid. To add a barcode to a pass, provide a value for the barcode key at the top level of the pass.json file. The value is a dictionary that describes the barcode you want to display. Specify the barcode format and provide the message to be displayed and the encoding used by the message. The optional alternate text is rendered near the barcode and contains a code to be entered manually if the barcode cant be scanned. Listing 3-5 shows part of an example pass that contains a barcode.
Listing 3-5
{ ...

Partial pass with a barcode

"barcode" : { "message" : "ABCD 123 EFGH 456 IJKL 789 MNOP", "format" : "PKBarcodeFormatPDF417", "messageEncoding" : "iso-8859-1" } }

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

28

Pass Design and Creation Pass Colors Can Be Customized

Barcode scanners and software typically use the ISO 8859-1 encoding, also known as Latin-1. Unicode in particular is poorly supported by most systems. Passbook itself supports all encodings supported by Foundation. Note: Most laser scanners cant reliably read barcodes displayed on LCD screens. To scan pass barcodes, use an optical barcode scanner. All of the supported barcode formats are two dimensional and are typically read with optical barcode scanners.

The barcode message is just data, theres nothing that limits you from using it to carry additional information. For example, suppose you need to scan passes in a setting without network access, which makes it impossible to communicate with your database. You can sign the data you need with a private key, and use the result as the barcode. When the pass is scanned, validating the signature lets you trust the data in the barcode. Although this approach doesnt let you enforce a one-time-use pass, it could be useful for applications where passes are valid for a predictable period of time. The amount of data that you can include in a barcode depends on the barcode format and the conditions under which the barcode is scanned. The barcode format defines a hard maximum that it supports, but scanning conditions often lower this limit. For example, consider a barcode displayed on a non-Retina device under poor lighting, and scanned by an inexpensive barcode scanner. Test your passes in real-world conditions on a variety of devices to ensure that the barcode can be scanned reliably.

Pass Colors Can Be Customized


By default, Passbook chooses the colors for your pass background and text. To override a color, provide a value for the appropriate key at the top level of the pass.json file. Colors are specified as RGB valuesfor example, rgb(0, 255, 0) is bright green. You can customize three colors:

The background color is used for the background of the front and back of the pass. If you provide a background image, any background color is ignored. The key for the background color is backgroundColor. The foreground color is used for the values of fields shown on the front of the pass. The key for the foreground color is foregroundColor. The label color is used for the labels of fields shown on the front of the pass. The key for the label color is labelColor.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

29

Pass Design and Creation Images Fill Their Allotted Space

Images Fill Their Allotted Space


The pass layout allots a certain area on the front of the pass for each image. Images are scaled (preserving aspect ratio) to fill this allotted space. Images with a different aspect ratio than their allotted space are cropped after being scaled. The space allotted is as follows:

The background image (background.png) is displayed behind the entire front of the pass. The expected dimensions are 180x220 points. The image is cropped slightly on all sides and blurred. Depending on the image, you can often provide an image at a smaller size and let it be scaled up, because the blur effect hides details. This lets you to reduce the file size without a noticeable difference in the pass. The footer image (footer.png) is displayed near the barcode. The allotted space is 286x15 points. The icon (icon.png) is displayed when a pass is shown on the lock screen and by apps such as Mail when showing a pass attached to an email. The expected dimensions are the same as a small icon, as described in Custom Icon and Image Creation Guidelines in iOS Human Interface Guidelines . A shine effect is automatically applied to the icon for you. The logo image (logo.png) is displayed in the top left corner of the pass, next to the logo text. The allotted space is 160x50 points; in most cases it should be narrower. To engrave the logo so that it matches the logo text, add a black drop shadow with a 1 pixel y offset, a 1 pixel blur, and a 35% opacity. The strip image (strip.png) is displayed behind the primary fields. The allotted space is 312x84 points for event tickets, 312x110 points for other pass styles with a square barcode, and 312x123 in all other cases. A shine effect is automatically applied to the strip image; to suppress it use the suppressStripShine key. The thumbnail image (thumbnail.png) displayed next to the fields on the front of the pass. The allotted space is 90x90 points. The aspect ratio should be in the range of 2:3 to 3:2, otherwise the image is cropped.

Note: The dimensions given here are all in points. On Retina displays, there are 2 pixels per point; on non-Retina displays, there is 1 pixel per point. Provide both Retina and non-Retina assets in your passes.

Relevance Information Displays Passes on the Lock Screen


Passes let your users take some action in the real world, so accessing them needs to be easy and fast. Passbook integrates with the lock screen to make relevant passes immediately accessible from the lock screen. To take advantage of lock screen integration, add information about where and when your pass is relevant. A pass is relevant at the time and place that the user can redeem it. For example, a gym membership card is relevant at the gym, and a boarding pass is relevant at the time the flight begins boarding.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

30

Pass Design and Creation Relevance Information Displays Passes on the Lock Screen

You provide a point in time and points in space in the pass. Passbook determines the appropriate duration of time and radius in space around these points that the pass appears on the lock screen. Dont try to manipulate the time and place that pass appears on the lock screen by providing inaccurate relevance information. Relevance information is passive: it helps users find passes when they need them by putting relevant passes right on the lock screen. It doesnt present alerts or post notifications. This is in contrast to the notification posted when a pass updates, as described in Updating a Pass (page 37). To provide a relevant date, add the relevantDate key at the top level of the pass. Its value is a W3C timestamp, either a complete date plus hours and minutes or a complete date plus hours minutes and seconds. For more information about the timestamp format, see Time and Date Formats on the W3C website. To provide relevant locations, add the locations key at the top level of the pass. Its value is an array of dictionaries with longitude, latitude, and optional altitude information. Listing 3-6 shows part of an example pass which provides both a relative date and three relevant locations. A pass can have up to ten relevant locations. In many cases, you have more than ten relevant locations so you have to pick the best ten. There are a variety of ways to do this. For example, you could have settings in your account management system to let customers add their favorite stores or the stores that they frequently visit. Like other data in the pass, relevance data can be changed when the pass is updated. A pass could initially have very generic relevance information which is replaced over time with relevant locations tailored by the user.
Listing 3-6
{ ...

Partial pass with relevance information

"description" : "Example pass showing relevance information", "locations" : [ {"latitude" : 37.3229, "longitude" : -122.0323}, {"latitude" : 37.3286, "longitude" : -122.0143}, { "altitude" : 10.0, "latitude" : 37.331, "longitude" : -122.029, "relevantText" : "Store nearby on 3rd and Main." } ], "relevantDate" : "2012-12-05T09:00-08"

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

31

Pass Design and Creation Relevance Information Displays Passes on the Lock Screen

Depending on the pass style, the relevance information is interpreted in slightly different ways, as listed in Table 3-2. When the location is interpreted with a small radius, the current location must be on the order of a hundred meters or closer; with a large radius, on the order of a thousand meters or closer. In both cases, the exact relevance radius is an implementation detail and may change.
Table 3-2 Pass style Pass style and relevance information Relevant Date Relevant Locations Relevance

Boarding pass

Optional

Interpreted with a large radius.

Relevant if the time or any location matches. Without a relevant time, relevant if any location matches.

Coupon

Not supported

Interpreted with a small radius. Interpreted with a large radius.

Relevant if any location matches.

Event ticket

Required if any relevant locations are specified. Optional

Relevant if the time and any location matches. Without a relevant time, relevant if any location matches.

Generic

Interpreted with a small radius. Required if a relevant date is specified.

Relevant if the time and any location matches. Without a relevant time, relevant if any location matches. Relevant if any location matches.

Store card

Not supported

Interpreted with a small radius.

The system provides the relevant text for passes that have time-based relevance. For passes with relevant locations, you provide a description of why the pass is relevant at a given location. This can be as simple as Store nearby or include a brief description of how to find the relevant location, such as cross streets or landmarks. Dont include your organization name in the relevant text, and dont include instructions to the user such as Redeem this pass at XYZ .

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

32

Pass Design and Creation Passes Support Localization

Note: Test relevance information on a device; the iOS Simulator app doesnt support relevance information.

Passes Support Localization


Localizing a pass has three parts: displaying numbers and dates in the correct format, providing localized strings, and providing localized images. Before you include localizations in a pass, consider whether you need it. You generate a pass for each user, and you have information about your users. If you let users tell you their preferred localizations through account settings, or if you can infer the localization from the geographic region, you can often include a small number of localizations or even produce a pass only in the preferred localization. Limiting the number of localizations helps keep pass size small by not providing localized images. Use field formatters to display numbers and dates in the users preferred format and language. For more information about formatters, see Fields Support Formatting (page 25). Use a strings file to provide localized strings. A strings file lists strings that appear in the pass.json file and the string to display for a particular language. For example, given the following pass fragment from an airline ticket:
{ ...

"primaryFields" : [ { "key" : "origin", "label" : "Seville", "value" : "SVQ" }, { "key" : "destination", "label" : "London", "value" : "LHR" } ] }

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

33

Pass Design and Creation Passes Support Localization

To localize this pass into Spanish and English, do the following:


1.

Change pass file to factor out the text being localized:


{ ...

"primaryFields" : [ { "key" : "origin", "label" : "origin_SVQ", "value" : "SVQ" }, { "key" : "destination", "label" : "destination_LHR", "value" : "LHR" } ] }

The field values are no longer the text to be displaynow they indicate which entry in the strings file should be used.
2.

Create an es.lproj directory in the pass package. Create a strings file named pass.strings containing the Spanish strings:
"origin_SVQ" = "Sevilla"; "destination_LHR" = "Londres";

3.

Create an en.lproj directory in the pass package. Create a strings file named pass.strings containing the English strings:
"origin_SVQ" = "Seville"; "destination_LHR" = "London";

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

34

Pass Design and Creation Passes Are Cryptographically Signed and Compressed

Note: In this example, the strings files contains only ASCII characters. Save strings files that contain non-ASCII characters using the UTF-16 encoding.

If there is more than one localization, each localization needs its own .lproj directory, as shown earlier in Figure 3-1 (page 17). If the text in the pass were left in English and Spanish text were provided in a strings file, the pass would display in Spanish only. For more information about strings files, see Localizing String Resources in Internationalization Programming Topics . Images that need to be localized appear in the .lproj directories for their respective languages. Images that dont need localization appear at the top level of the pass. Dont include an image at the top level and inside a .lproj directory. For more information about localizing images, see Localized Resources in Bundles in Bundle Programming Guide .

Passes Are Cryptographically Signed and Compressed


Passes are cryptographically signed and compressed before being distributed. This establishes the identity of the signer and lets your customers be sure the pass hasnt been modified since being signed. Note: Omit metadata files, such as the .DS_Store file, when distributing the pass.

To create the manifest file, recursively list the files in the package (except the manifest file and signature), calculate the SHA-1 hash of the contents of those files, and store the data in a dictionary. The keys are relative paths to the file from the pass package. The values are the SHA-1 hash (hex encoded) of the data at that path. Write this to the file manifest.json at the top level of the pass package. To create the signature file, make a PKCS #7 detached signature of the manifest file, using the private key associated with your signing certificate. Include the WWDR intermediate certificate as part of the signature; you can download this certificate from Apples website. Write the signature to the file signature at the top level of the pass package. To compress the pass, create a ZIP archive of the contents of the pass package. This ZIP archive is what you distribute to users.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

35

Pass Design and Creation Passes Are Distributed via Email, the Web, or Your App

Passes Are Distributed via Email, the Web, or Your App


Mail and Safari have support for passes on iOS 6 and later and on OS X v10.8.2 and later, so you can use them to distribute passes by email or on a website. On iOS, they add passes to the pass library directly. On OS X, they use iCloud to add passes to the users iOS devices. The advantage of sending passes as an email attachment is simplicity. When the user views the email, the pass appears and can be added to their pass library. During development, this is an easy way to get a pass onto your device. The disadvantage is that you cant interact with the pass-installation process. For example, an email cant present an alternate representation for older devices that dont support passes. Hosting passes on your web server gives you more control over the user experience, but is less simple. You can give your users a link to a landing page that lets them add the pass to their pass library. This page can also offer a representation of the pass in older formats such as PDF. This landing page also gives you a place to ask the user to log in if needed. Note: Mail and Safari expect passes to use the application/vnd.apple.pkpass MIME type. Configure your email creation system or web server to use this MIME type for pass data.

Using your own app to install passes is appropriate when your app provides a richer experience by integrating with your systems and business. For information about how your app can interact with passes, see Interacting With Passes in Your App (page 44).

Debugging Passes
If the pass doesnt display and add to Passbook, check the log for a description of what went wrong. When testing in the iOS Simulator app, errors are logged to the system log, which you can view with the Console app. When testing on a device, errors are logged to the devices console which you can view from the Xcode organizer window. Common errors include malformed JSON files, misspelled keys or values, pass type identifiers that dont match your certificate, and signatures that omit the WWDR intermediate certificate.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

36

Updating a Pass

Passes allow the user to take real-world actions, and they reflect real-world state. When something in the real world changes, such as a delay to a departure, you can update the pass. Another reason to update a pass is when the pass represents multiple real world actions. For example, a season ticket gains access to every game of the season, and is updated before each game.

Overview of the Communication


Updating a pass is a cooperative effort between the users device, Apples servers, and your servers. At a high level, it consists of the following steps, shown in Figure 4-1:
1. 2. 3.

A pass that supports updates is installed and the users device registers with your server to get updates. Some change triggers an update and your server sends a push notification. The users device receives the notification and it queries your server to get a list of changes.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

37

Updating a Pass Overview of the Communication

4.

The users device asks your server for the latest version of each pass that has changed.

Figure 4-1

Interaction between the client and your server


Client Server

APNs

The update process uses the following pieces of information:


Information Source Purpose

Web service URL

You define in the pass

Tells Passbook how to contact your web server Together, uniquely identify the pass

Pass type identifier Serial number Device library identifier

You define both in the pass

Device defines

Identifies the device and authorizes requests

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

38

Updating a Pass Overview of the Communication

Information

Source

Purpose

Authentication token Push token

You define in the pass Device defines

Authorizes requests Allows the server to send push notifications to the device Describes state

Update tag

Your server defines

Your server implements a specific web service API which allows this communication to happen. This is different from most uses of push notifications where you provide an app that is free to communicate with your server however you prefer. In this case, you only provide a pass, so Passbook needs a standardized way to communicate with your server. The web service URL tells Passbook how to contact your server during the update process. It must include the protocol, and it can include an optional port number. Passbook requires an HTTPS connection to your server for all communication. During development, you can use the developer settings to allow plain HTTP connections. Before responding to a request, you server always checks that the request is authorized. There are two shared secrets that are used to authorize requests. For more information about shared secrets, see Security Overview . The device library identifier is a Passbook-specific shared secret between the users device and your web server. It is not related to the device identifier (UDID). The device identifies itself with a different ID to different servers and it may change its ID at any time. Its purpose is to allow efficient communication between the device and your server, not to let your server keep a list of of what passes are currently installed on a device. The device library identifier uniquely identifies a device and indicates that the entity making the request is authorized to make such a request. The authentication token is a shared secret between the users device and your server. It shows that the request for an update to a pass is actually coming from the user who has the pass, and not from a third party. Your server needs to remember contain information between requests. There are two entitiesdevices and passesand one relationship, registrations. Assuming your server stores data in a traditional relational database, it needs to maintain the following tables: Devices table A device is identified by its device library identifier; it also has a push token. Passes table A pass is identified by pass type ID and serial number. This table includes a last-update tag (such as a time stamp) for when the pass was last updated, and typically includes whatever data you need to generate the actual pass.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

39

Updating a Pass Devices Register for Updates

Registrations table A registration is a relationship between a device and a pass. You need to be able to look up information in both directions: to find the passes that a given device has registered for, and to find the devices that have registered for a given pass. Registration is a many-to-many relationship: a single device can register for updates to multiple passes, and a single pass can be registered by multiple devices. Note: Test updates on a device; the iOS Simulator app doesnt register for push notifications.

Devices Register for Updates


After installing a pass, the iOS device registers with your server, asking to receive updates. Your server saves the devices library ID and its push token. The device sends the following pieces of information:

Device library identifier (in the URL) Push token (in JSON payload) Pass type ID (in the URL) Serial number (in the URL) Authentication token (in the header)

To handle the device registration, do the following:


1.

Verify that the authentication token is correct. If it doesnt match, immediately return the HTTP status 401 Unauthorized and disregard the request. Store the mapping between the device library identifier and the push token in the devices table. Store the mapping between the pass (by pass type identifier and serial number) and the device library identifier in the registrations table.

2. 3.

When a device removes a registration, it uses the same endpoint and sends the same data. The difference is that the device sends a DELETE request instead of a POST request, and your server removes (or invalidates) data from its tables instead of adding it. When a device removes a registration, you can immediately remove the entry from the registrations table. When there are no entries for a device in the registrations table, you can remove the entry for the device from the devices table.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

40

Updating a Pass Your Server Sends a Push Notification When Something Changes

Your Server Sends a Push Notification When Something Changes


When a pass needs to be updated, your server sends a push notification to inform devices of the change. Send pushes only to the devices that have registered for updates for that pass, and only when the pass has changed. Dont send unnecessary pushes. Your server sends the following pieces of information:

The pass type identifier (in the certificate) The push token (in the communication to the Apple Push Notification service)

To send the push notification, do the following:


1.

Update the passes table with the new pass information and get the pass type identifier and serial number for the pass that changed. Consult the registrations table and get the list of devices that registered for updates for that pass. Consult the devices table and get the push token for each device. Send a push notification with an empty JSON dictionary as its payload to each push token.

2. 3. 4.

You may wonder why your server doesnt include more information in the push notification. The reason is twofold: push notifications are not guaranteed to be delivered, and multiple push notifications from the same source are coalesced into a single notification. If more information were included it could be lost. The push notification just indicates that some passes with a given pass type identifier changed, so no information is lost if they are coalesced. Note: The Apple Push Notification service (APNs) provides feedback to your server which may require specific actions. For example, if APNs tells you that a push token is invalid, remove that device and its registrations from your server.

You use the same certificate and private key for sending push notifications as for signing passes. For more information about push notifications, see Local and Push Notification Programming Guide .

Devices Ask for Changed Serial Numbers


When a device gets a push notification, it asks your server for the serial numbers of passes that have changed since a specific point in time. The device sends the following pieces of information:

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

41

Updating a Pass Devices Ask for Changed Serial Numbers

The device ID (in the URL) The pass type ID from the push notification (in the URL) The latest update tag that its seen from this pass type ID (as an optional query)

Authorization tokens are specified by each pass, so there is no appropriate token in this case. The device identifier is sufficient to prove that the request is valid. Your server determines which passes have changed since that update tag. It returns the serial numbers of those passes, and a new update tag to store. To send the list of serial numbers, do the following:
1. 2.

Look at the registrations table and determine which passes the device is registered for. Look at the passes table and determine which passes have changed since the given tag. Dont include serial numbers of passes that the device didnt register for. If no update tag is provided, return all the passes that the device is registered for. For example, this happens the very first time a device communicates with your server. Compare the update tags for each pass that has changed and determine which one is the latest. This is the update tag that will be returned to the device. Respond with this list of serial numbers and the latest update tag in a JSON payloadfor example:
{ "serialNumbers" : [001, 020, 3019], "lastUpdated" : "1351981923" }

3.

4.

Update tags are just an opaque piece of data, as far as Passbook is concerned. Your server must be able to compare any two tags to determine which one comes before the other, and the later tag must also be later than every earlier tag. The tag system is similar to the standard HTTP If-Modified-Since mechanism, but different in an important way. The standard HTTP mechanism is for a single monolithic resource; if the resource has changed, the entire resource is returned. The tag system used here is for a collection of passes; only the passes that have changed are returned, not the entire collection.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

42

Updating a Pass Devices Ask for Latest Version of Passes

Devices Ask for Latest Version of Passes


The device asks your server for the latest version of each updated pass. To prove that the request is valid, the device includes the passs authorization token. The device sends the following pieces of information:

Pass type identifier (in the URL) Serial number (in the URL) Authentication token (in the header)

Your server returns the pass data or the HTTP status 304 Not Modified if the pass hasnt changed. Support the If-Modified-Since or ETag caching mechanism on this endpoint.

Devices Display Change Messages


The device compares the latest version of the pass against the version it had before to determine which fields have changed. If the value of a field has changed and the field specifies a change message, the device shows the message to inform the user about the change. Change messages interrupt the user and must be read immediately. They are typically appropriate only for information that is time sensitive. For example, if the concert tonight has been delayed by an hour and has moved across town, thats important to know about that right away. However, updating a season ticket for the next game or changing your customer service phone number would not merit a change message.

Best Practices
As you implement your web service, keep the following best practices in mind:

Always make a backup of your private key and certificate and keep them in a secure place. Avoid storing your private keys on your web server, because web servers typically have a larger attack surface. A more secure approach is to have a different server handle creating and signing passes, and push the finished passes to your web server. The serial number, pass type identifier, and last-update tag all get included in a URL when talking to your web service. Making them excessively long could cause problems with systems that impose a restriction on the length of a URL. Dont change the authentication token in an update. Passes are not guaranteed to be updated, so there could still be devices with the old pass and the old authentication token. Your server would have to check the authentication token against the list of every token that has ever been valid.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

43

Interacting with Passes in Your App

There are two main reasons apps interact with passes: to provide an integrated user experience or to serve as a conduit for passes. An event venues app is an example of an integrated user experience. This app could show the performance schedule, play short video clips, and let users buy tickets. After buying a ticket, it could add a pass for that ticket to Passbook and create an event in the users calendar. It could also include UI for managing the tickets that users have purchased. An email or instant messaging client is an example of an app serving as a conduit. Just as it supports attachments such as images, it could also support passes attached to a message like Mail does. The app could display UI that indicated that the message has a pass attached and allow users to add the pass to their library. Supporting passes in your app should add value for the user; avoid trying to duplicate functionality of the Passbook app. Your app needs the appropriate entitlement to read, update, or delete passes. Adding a pass requires explicit user interaction, so it doesnt require an entitlement. The Pass Kit framework provides model-level access to pass data. The PKPassLibrary class represents the pass library, and the PKPass class represents individual passes. The framework also provides a view controller, the PKAddPassesViewController class, which displays a pass and lets users add it to their pass library. Your app is responsible for the views it needs to display passes. If you need to present a pass, use the passURL property of a pass and open that to show it in Passbook as follows:
[[UIApplication sharedApplication] openURL:[pass passURL]]

Note: A pass should not depend on your app to be useful. Passes need to be self contained and useful by themselves, even if your app is not installed.

Checking Whether the Pass Library Is Available


The presence of the Pass Kit framework and its classes doesnt mean that the pass library is available. To check for its availability, call the isPassLibraryAvailable method of the PKPassLibrary class.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

44

Interacting with Passes in Your App Checking Whether a Pass Is in the Library

Checking Whether a Pass Is in the Library


You can determine whether a pass is in the library even if you dont have the entitlement to actually read the pass. This allows apps that act as conduits for passes to display the appropriate UI: for passes that are already in Passbook, an indication that they have been added, and for other passes an affordance to add them to Passbook. To check whether a pass is in the library:
1. 2. 3.

Create an instance of the PKPass class for the pass. Create an instance of the PKPassLibrary class. Call the containsPass: method of the PKPassLibrary class with the pass you just created.

Getting Passes
Use the passes method of the PKPassLibrary class to get all passes that your app is entitled to access. Passes are returned in an arbitrary order. If your app displays a list of passes, it should sort them in some meaningful way such as by date. To receive notifications when the pass library changes, register for the PKPassLibraryDidChangeNotification notification. Pass the instance of PKPassLibrary as the object. The pass library isnt a singleton; each instance sends its own notifications, and you want the notifications from this particular instance. Use the addObserverForName:object:queue:usingBlock: method to specify that you want to respond on the main queue and provide a block to handle the notification. The user info dictionary of the notification describes what changed. Alternately, use the dispatch_async and dispatch_get_main_queue functions to respond on the main thread.

Reading a Pass
Use the passWithPassTypeIdentifier:serialNumber: method of the PKPassLibrary class to read a particular pass from the pass library. You can access certain common bits of data, such as the organization name and description, using the properties of the PKPass class. You can access the description using the localizedDescription method. These are useful if your app is acting as a conduit passes that you didnt create, so you dont know their fields keys. You can access specific fields of a pass using the their key with the localizedValueForFieldKey: method. This is useful if you created the pass, because then you know the keys for specific fields.PKPass properties.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

45

Interacting with Passes in Your App Adding a New Pass

Adding a New Pass


To add a pass to the library:
1. 2.

Create an instance of the PKPass class for the pass, initializing it with the passs data. Use the containsPass: method of the PKPassLibrary class to check whether the pass is in the library. Your app can use this method to detect the presence of a pass, even if it doesnt have the entitlements to read passes in the library. If the pass isnt in the library, use an instance of the PKAddPassesViewController class to let the user add it. Present the add passes view controller modally, with animation.

3.

Changing a Pass
Passes cannot be changed directly on the device. Changing the contents of a pass would invalidate its signature. An updated pass needs to be signed using your private key, and distributing your private key as part of your app would be a particularly poor security practice. To change a pass, coordinate with your server:
1.

Your app connects to your server. It identifies the pass by serial number and pass type identifier and describes the change to your server. Your server updates your business records as needed, creates a new version of the pass, and signs it. Your app downloads the new pass from your server and uses the replacePassWithPass: method of the PKPassLibrary class to install it.

2. 3.

After creating a new version of the pass, your server should also send a push notification so that other devices with this pass installed will get the latest copy.

Removing a Pass
Use the removePass: method of the PKPassLibrary class to remove a pass. Remember that passes belong to the user, not to your app. Pass removal should be done only in response to a direct user action. Never remove a pass without the users consent, even if the pass is expired or outdated.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

46

Document Revision History

This table describes the changes to Passbook Programming Guide .

Date iOS 6.0

Notes New document that explains how to create passes, update them, and interact with them from your app.

iOS 6.0 | 2012 Apple Inc. All Rights Reserved.

47

Apple Inc. 2012 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 Apples 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, Finder, iTunes, Keychain, Numbers, Objective-C, OS X, Passbook, Safari, and Xcode are trademarks of Apple Inc., registered in the U.S. and other countries. Retina is a trademark of Apple Inc. iCloud and iTunes Store are service marks of Apple Inc., registered in the U.S. and other countries. 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 FITNESS 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.

Vous aimerez peut-être aussi