Passbook, Apple’s digital wallet - Barcodes with iOS: Bringing together the digital and physical worlds (2015)

Barcodes with iOS: Bringing together the digital and physical worlds (2015)

Chapter 4. Passbook, Apple’s digital wallet

This chapter covers

· Barcodes: the technology that makes Apple’s Passbook system possible

· Micro-documents as a convenient digital alternative to paper tickets and plastic cards

· Creating Passbook tickets with Ruby

· A method for validating Passbook tickets without a server

We have all come into contact with small documents that provide some benefit if we present them to the right person at the right time in the right location. Such documents include movie tickets that allow you to enter the movie theater, coupons that entitle you to receive a promotional discount for certain products, membership cards that let you enter the gym, loyalty cards for collecting loyalty points at the supermarket chain where you faithfully shop, or tickets for planes, trains, ships, or other vehicles providing transportation. Long before the digital revolution, those micro-documents were usually printed on paper with varying measures to prevent somebody from creating illicit copies.

Consider, for example, tickets for a sold-out concert. The concert organizer might go as far as embedding holograms in the paper the tickets are printed on to make sure that there’s no way for counterfeiters to produce their own tickets.

Apple, being constantly on the lookout for ways to enrich the lives of their customers, saw this plethora of micro-documents and developed Passbook as a digital alternative. The mobile phone has already replaced the wristwatch as a timekeeper. Passbook aims to make your wallet obsolete as well, or at least its function as a repository of paper tickets, membership cards, and other things you carry around besides cash.

Nomenclature

The name Passbook is used by Apple as the umbrella term for all the pieces of this system. Passbook micro-documents are embodied by files with the extension .pkpass. Those files can represent different kinds of tickets, coupons, cards, and so on. For the sake of simplicity, these are all commonly referred to as passes. The iOS APIs for interacting with passes from within your apps are grouped in the PassKit.framework. The Passbook.app comes preinstalled on all iPhones since iOS 6 and provides access to all the passes users have on their device.

In the past, Apple had a reputation for developing technologies without considering the requirements of existing corporate systems. Passbook, first introduced in 2012 as part of iOS 6, was the first drastic departure from this methodology. Apple published everything companies needed to produce digital passes on their own systems—no Macs required. Because of this openness, most major companies have begun to offer Passbook passes as an option when delivering digital passes by email.

The goal of this chapter is to give you a basic understanding of how passes are created, and then to demonstrate in a sample app how you can validate passes you create without requiring an impressive server setup.

4.1. Barcodes in Passbook

Physical micro-documents—we’ll call them “passes” for short—can contain human-readable information that a person can look at to determine the validity of the pass. But this activity becomes impractical at larger scales for several reasons:

· A ticket might look alright but could be counterfeit.

· It takes too long to manually type in a membership number printed on a member card.

· Such manual data transfer is prone to copying mistakes.

· Customers might prefer to not use their loyalty card if it means they’re holding up the queue.

The creators of paper passes and plastic cards now often add a barcode to allow for automated scanning. These pieces of paper or plastic essentially now serve as a medium to transport the barcode.

When Apple designed Passbook, they evaluated which kinds of barcodes would be feasible. The core requirement was that scanners needed to be able to scan the barcode from the device’s display. This is something that laser-based scanners can’t do well because of reflection on iPhone glass displays. As a result, Apple decided to support only 2D symbologies for Passbook, as those are generally scanned with CCD-based scanners.

4.2. Producing digital passes for your users

After reading this chapter, you might get hired by a chain of movie theaters that needs your help in implementing a Passbook-based ticket flow. But for this example we’ll scale down the scenario a bit. You are, more than likely, the owner of a state-of-the-art home movie theater (a.k.a. your TV). The size of your sofa puts a natural limit on the number of friends who can come over and attend a VIP movie night, so you do what every venue owner does: you create tickets with assigned seat numbers and the date and time of the movie night.

The point of this exercise is to demonstrate the workflow required to create valid tickets and distribute them. In all of its communication, Apple is promoting Passbook as something for large corporations with extensive server infrastructure to implement. Because of this, you might be harboring some fear that you need to have server-side skills. But this isn’t the case. Once you’ve wrapped your head around the simple beauty of the pkpass format, you’ll lose this worry and instead begin to see many other usage scenarios you’ll want to explore.

The first two steps of the process are rather tedious, but you only need to do them once for the type of pass you want to create. You need to sign into your Apple developer account and create a digital certificate to sign your passes with. Once you have this setup step out of the way, you can begin to create valid passes. We’ll explore pass validation afterward.

4.2.1. Requesting a certificate for signing passes

In the Passbook system, the role of the non-fakable hologram on paper tickets is taken on by a digital signature. A few initial setup steps are required to produce signatures that iOS and the Passbook app will accept as valid. These steps might seem like a lot of work, but you only need to execute them once per type of pass you want to sign.

Sign into the iOS Dev Center (https://developer.apple.com/devcenter/ios/) and go to the Certificates, Identifiers & Profiles section.

The identifier represents a certain type of pass that you’re going to create. Use a different identifier for coupons than for movie tickets.

In the Identifiers section, shown in figure 4.1, you can create a new identifier for your passes. The description is only visible to you, and you should identify it so that you can tell it apart from the other pass types you might create in the future. For this example, use “VIP Movie Night” for the description. The identifier needs to start with pass. followed by reverse domain notation, as you would use for an app identifier. Enter the ID pass.com.yourcompany.vipmovie, substituting your domain or company name for yourcompany.

Figure 4.1. Creating a pass type identifier

On the confirmation screen that’s displayed next, verify that both values are correct. I once made the mistake of entering a duplicate pass prefix, with the effect that the signing failed with weird error messages.

Different passes, different type identifiers

You can have as many pass types as you need. For example, you could issue loyalty cards to your clients and also one-off coupons with a promotional discount. Those would be two different types.

For every different type of pass, you should configure a pass type identifier first and then request a signing certificate for it. When interacting with passes via the PassKit APIs, you can determine which type of pkpass you’re looking at by checking its pass-TypeIdentifier property.

Next, you’ll create a signing certificate that exactly matches the identifier. Still on the Certificates, Identifiers & Profiles page, enter the Certificates section. Under Production, click on the plus button (+) at the top right to get the certificate Select Type screen (see figure 4.2). There select the Pass Type ID Certificate option, which allows you to “Sign and send updates to passes in Passbook.” While you’re here, there’s also a convenient link for downloading the Worldwide Developer Relations Certificate Authority. Download this before clicking Continue.

Figure 4.2. Creating a signing certificate

On the following screen (see figure 4.3), pick the pass type identifier that you want to configure the certificate for. Here you can see that Apple prefixes all your pass type IDs with your team ID to make them even more unique.

Figure 4.3. Creating a certificate for a pass type identifier

This screen is followed by an explanation of how to create a certificate request via the Keychain Access app. The subsequent screen contains an upload form for the certificate request file you’ll create next.

SSL certificates

SSL certificates employ an asymmetric scheme for encryption and digital signing. They consist of a pair of public and private keys. Data encrypted/signed with the private key can only be decrypted/verified with the public key.

You need to keep your private key secret but supply the public key with signed documents to allow verification of your signature.

The easiest method for creating SSL certificates on a Mac is via the Keychain Access app. In that app, select Keychain Access > Certificate Assistant > Request a Certificate From a Certificate Authority (see figure 4.4).

Figure 4.4. Use Certificate Assistant to create a private/public key pair

Fill in your Apple ID email address and your name as the common name. Even though the placeholder text states it’s required, you should leave the CA Email Address field empty. Choose the Saved to Disk option to write the CA signing request to a file. When you click Continue, a private key is stored in your keychain and the public part is prepared to be sent to the Apple certificate authority for signing. The filename for this file doesn’t matter.

Upload the signing request file via the upload form, and after a few seconds the signed request is ready (see figure 4.5).

Figure 4.5. Your certificate is ready.

Apple signed the public key part of your certificate, and back on your Mac the public key rejoins the private key in your keychain to form a complete key pair. Look in the My Certificates section in Keychain Assistant to see the private key listed below its certificate and the info showing that the certificate is valid and trusted (see figure 4.6).

Figure 4.6. Finished certificate in keychain

The finished certificate is signed with Apple’s Worldwide Developer Relations Intermediate Certificate, which depends on the Apple Inc. Root Certificate. Both can be downloaded from the Apple CA page (http://www.apple.com/certificateauthority/), although the latter is usually preinstalled on Macs.

4.2.2. Preparing signing certificates

You’ll sign your passes with the openssl command-line tool. This tool doesn’t have the ability to get the certificate from the OS X keychain where you stored it in the previous section, so you first need to export the certificate into a file and convert it into a format that the utility can work with.

OpenSSL

OpenSSL is a collaborative project developing a robust, commercial-grade, full-featured and open source toolkit. It provides a plethora of functions for working with SSL certificates, decoding and encoding data, creating and validating cryptographic hashes, and much more.

You can access the openssl utility from the Terminal command line, and it’s also available from many modern programming languages, such as Ruby and Python.

Apple doesn’t provide OpenSSL to developers. Instead, a comprehensive set of cryptography functions is packaged in the CommonCrypto.framework available on both Apple platforms.

OpenSSL needs three pieces for the signing process, which you’ll save in a working folder with specific names for simplicity:

· The WWDR (Worldwide Developer Relations) intermediate certificate, downloaded from Apple and saved as AppleWWDRCA.cer

· The pass type certificate, saved as passtypecert.pem

· The signing key matching the pass type certificate, saved as passtypecertkey.pem

Keychain Access doesn’t allow you to directly export separate private and public keys for the pass type certificate, so you must first export the pair into a p12 file and then use OpenSSL to create the distinct files.

In Keychain Access, select the certificate, right-click on it, and select the export option. Choose the p12 format, and leave the password for the exported file blank (see figure 4.7).

Figure 4.7. Export pass type certificate as p12 file

In Terminal, change into the directory where you placed the p12 file and run the following commands:

For a public key, security is irrelevant, but for the private key file you might want to specify a strong password, especially if you’re going to be creating passes on a web server. The WWDR intermediate certificate in CER format is already in a format that you can use.

4.2.3. Constructing passes

Passes are usually created on a web server. In the case of a movie theater chain, it would be the ticketing system that creates paper tickets or allows customers to print their own paper tickets at home.

Figure 4.8 shows the steps involved in creating a Passbook pass.

Figure 4.8. Pass creation flow

For our example VIP Movie Night scenario, you’ll create the tickets with a Ruby script. Ruby on Rails is one of the predominant modern frameworks for developing web applications, and Ruby is also the scripting language of choice for most iOS developers. Passbook is not in any way dependent on Apple hardware or software.

Ruby comes preinstalled on your Mac with OS X, so no setup is required. Ruby provides OpenSSL out of the box and also has great support for JSON, which is the format used for making passes.

Configuring the pass build script

The following Ruby code snippets are all part of the makepass.rb script, which you’ll find in the source code for this book.1 Put the script file in the directory where you prepared the certificates. This script is intentionally simplistic to demonstrate the bare essentials for building a pass. It has no command-line parameters—you’ll have to edit the script to change the contents of any pass fields.

You can configure all details for the pass by modifying the variable assignments at the top of the Ruby script:

The most important things to check and possibly adjust are the team identifier and the pass type identifier. Those need to match your signing certificate or you can’t produce a valid signature. You can look up your team identifier in the Apple developer member center (https://developer.apple.com/membercenter). You might also remember from figure 4.3 that Apple combines both of these identifiers for an even more unique pass type identity; this is the signing identity that the certificates need to match.

The eventDateString—the event time from the general pass info formatted as a W3C string—doubles as the relevantDate, which is logical for an event ticket that’s relevant at the time of the beginning of the event. This date needs to be complete with hours and minutes—seconds are optional. The locations array contains the geocoordinates of the event location—you should replace them with the location where the pass will be relevant. For testing, the GPS coordinates of your sofa would work well.

Beginning with iOS 7, you can also add an array of beacons to specify iBeacon identifiers. iBeacons are small, battery-powered devices that emit an identifier via Bluetooth. For example, a bus could have an iBeacon next to the driver, and this would cause bus tickets to be shown on the device’s lockscreen.

Let’s take the Ruby script for a spin now that all certificates and keys are present and you’ve adapted the pass details to your liking. In Terminal, change into the working directory where you put the certificate files and the edited Ruby script:

Running the script will dynamically create the pass.json file containing the pass details, the manifest.json file that contains the checksums of the pass files, and a signature file with the cryptographic signature of the manifest. The pieces will be zipped up into a .pkpass file in the same directory.

If you double-click on the .pkpass file, OS X will show a preview. You can also inspect the pass.json file to see the beautiful JSON reflecting the details you set up in the Ruby script. Figure 4.9 shows the pass.json file compared to the front and back of the pass as displayed by QuickLook preview on OS X.

Figure 4.9. Pass preview compared to pass.json

This pass has several generally applicable elements at the top, and the eventTicket key groups fields that are specific to this pass being an event ticket. The relevancy information in relevantDate and locations specifies conditions that make this pass relevant for display on the iPhone lock screen. Apple doesn’t publish the exact algorithm for determining when a pass should be shown on the lock screen, so you’ll have to trust them to do so in a manner useful to the user.

The following sections walk you through the Ruby script so that you can understand the process of assembling passes.

Checking and loading signing certificates

Once the pass details have been set up, the Ruby script loads and checks the three certificates needed to perform the signing of the manifest. They’re in begin/rescue/end blocks so they’ll gracefully fail should one of the certificates be missing or faulty. To keep things simple, the names of the three files are hardcoded:

Adding a barcode

The barcode is generated for you based on the contents of the barcodeMessage key. We want to be able to validate tickets without having to ping a server, so we’ll add some extra secret “salt” to the message and create an SHA1 hash as a signature. Because we’re the only ones who know the value of the salt, nobody else can create tickets with a correct barcode message signature. The following code snippet is a continuation of makepass.rb:

Passbook supports the three most-used 2D barcode symbologies: QR, Aztec, and PDF417 (see section 1.2.2 for details about their differences). Generally speaking, all three types can encode arbitrary strings. If you can spare the space and are free to choose, I recommend QR or Aztec Codes, as these have built-in error correction and are recognized faster and more reliably. PDF417 is more compact and thus better suited for passes with lots of info on the front.

Barcode character encoding

The ISO-8859-1 message-encoding format (also known as Latin 1) is the de facto standard for most barcode readers. This is why Apple suggests you use this as the character encoding for the contents of the pass barcode.

You can specify any character encoding scheme supported by NSString in the messageEncoding value of the barcode dictionary in pass.json.

The data content of the barcode is completely independent of the other content of the pass. It’s up to you whether you want to encode all the pass details in the barcode or whether you only encode a serial number there and then look up the information needed for validation from your server.

As you can see in the previous code snippet, you specify the contents, barcode type to use, and character encoding when creating the JSON file for the pass. When iOS or OS X displays the pass, it renders a barcode symbol according to this information.

Assembling the pass details

You configured the pass details at the top of the Ruby script (near the beginning of section 4.2.3).

The contents of the pass are assembled in a Ruby hash, the equivalent of a dictionary in Objective-C. This can easily be transformed into a JSON file. The first few entries are taken from variables you set up earlier; a few of the fields change less frequently and have hardcoded values. You may also customize these to your needs with your text editor:

Adding artwork to the pass

At this point, the JSON string for the pass is complete, but it yields rather boring visuals, as you can see on the left side of figure 4.10. To spice it up and brand it, you can add a number of images to the pass. Their exact use on the pass depends on its type, and some experimentation might be required. For each image, you’ll also need to include the Retina version, denoted by the @2x filename:

Figure 4.10. What a difference a few PNGs make ...

· icon.png and icon@2x.png are the icons to display in the Mail app. Without this, iOS rejects the pass.

· thumbnail.png and thumbnail@2x.png are small images to add beside the pass details.

· strip.png and strip@2x.png are background images to place behind the thumbnail. These can’t be combined with the background.

· background.png and background@2x.png are background images that get blurred and placed over the entire area of the pass. These can’t be combined with the strip image.

Figure 4.10 shows the dramatic difference you get from adding artwork files. Because the background image is blurred anyway, you can get away with a smaller-resolution image.

Looking for design love

The artwork to produce these results is included in the Passbook folder in the book’s example code. Please forgive my unprofessional choice of art—I’m a developer and not a designer. Passes you plan to distribute to actual users should receive the loving care of a design professional.

To prevent somebody from tampering with a pass by replacing artwork files, they’re also featured in the pass manifest. This is likely a gesture by Apple to give pass issuers a greater feeling of security and thus inspire trust in the platform. At validation time, if the signature is valid, then neither the JSON nor the resources could have been altered.

The following Ruby code from makepass.rb scans the current directory for suitable resources and determines the SHA1 checksum for each:

After this, both the manifest and pass JSON files have been written to disk. The manifest.json file has the SHA1 checksums for all files to prevent tampering.

Signed, sealed, delivered

In the last step in makepass.rb, the manifest JSON gets digitally signed and the result is output to a standalone signature file. Then all the files belonging to the pass get zipped up into a .pkpass file:

The signature is output in binary DER format into a detached file. Note that the rootCert is also included. iPhones usually don’t have the WWDR intermediate certificate installed, so it needs to be present inside the signature file so that the chain of trust (see figure 4.11) can be validated on the user’s device.

Figure 4.11. Passbook chain of trust

Instead of using the convenient Ruby script provided, you can also perform all the steps manually. For sake of completeness, here are the Terminal command equivalents for signing and zipping the pkpass file:

This manual approach requires you to create the pass and manifest JSON files by hand, which is as tedious as it is error prone. I think you’ll agree that editing a few values in the makepass.rb script is much more convenient.

Debugging passes

The OS X preview app will happily show you passes even if they have errors. Besides the signature being valid, there are a number of other conditions that need to be met for iOS to accept a pass. For example, passes require an icon image when sending them via email or else iOS will reject them.

To ensure that your pass creation is OK, mail yourself a pass file. Connect your iP-hone to your Mac via USB and open the Xcode Organizer’s console view. When you open the email with the pass, you’ll see in the log if there are any problems with the pass. If iOS lets you add the pass to Passbook, you know it’s OK.

4.2.4. Pass creation takeaways

At this point, you’re able to produce a batch of passes with different seat numbers for your VIP Movie Night event. By modifying the Ruby script, you can set the event date, specify the correct latitude and longitude of your sofa, and adjust the seat assignments. Adding images makes your passes much prettier. You should also make sure your iPhone will accept one such pass as valid to check that the creation was successful.

Some key takeaways:

· Passbook aims to make carrying tickets, passes, coupons, and vouchers on your iPhone quite convenient.

· Apple made the technology totally independent of any Apple hardware or software to facilitate it becoming the de facto standard.

· The certificate used for signing passes needs to be created in your Apple iOS developer account.

· For devices to be able to verify the signature, the WWDR intermediate certificate needs to be included.

· A manifest contains the SHA1 hashes of all artwork images and the pass.json file.

· This manifest is cryptographically signed to prevent tampering with the pass details or any artwork.

The procedure for creating a pass might seem a bit daunting at first. But once you work through this complexity, you’ll start seeing possible usage scenarios everywhere you look.

4.3. Validating passes

You counted the seats on your sofa as seating for your VIP Movie Night. You set a location, date, and time for the event. You produced valid digital Passbook tickets for the event. You emailed these tickets to your guinea pigs ... um, friends. Now you need to be able to verify tickets at the door to the venue (a.k.a. your living room). This section will teach you how to use the barcode scanning code you built in chapters 2 and 3 and build an app for doing that.

Several validation checks occur when a user adds the pass to their pass library. iOS will silently refuse to add any invalid passes, so if the pass is inside the Passbook library, it hasn’t been modified or otherwise tampered with. Additional validation levels (see figure 4.12) depend on your usage scenario. A big chain of movie theaters might want to check the ticket info against their ticket server.

Figure 4.12. Validating passes on multiple levels

If you had a big chain of movie theaters, you’d have your development department build an app that you could install on a number of iOS devices. Those ticket-checking devices would be used by the employees checking tickets at the door. They’d check paper tickets visually as they have always done, and they’d scan Passbook tickets with the app. This app would check the ticket and indicate whether they should let the ticket holder enter.

You probably don’t have a department doing the developing for you, so you’ll do this yourself. You also won’t have an army of ushers, but you might be able to delegate that job to your children. Another key difference between this scenario and real life is that you don’t have a ticketing server with a web API that you could check scanned tickets against.

For this reason, a cryptographic signature was included in the barcode message in the previous section. This signature ensures that only you can create valid passes for your event—no server required! Another benefit of this serverless approach is that it’s extremely fast. Imagine the long queue of people holding popcorn and cola, all of them wanting to get to their seats. The faster you can determine the eligibility of each visitor, the better. In an ideal implementation, the checking of a ticket would be as fast as glancing at a paper ticket.

The last of the validation steps depends on your usage scenario. For a small venue—like your living room—you can easily see if somebody has a duplicate seat assignment. Other scenarios might keep track of which seats have already been scanned and flag duplicates this way. Movie theaters in the United States usually won’t have assigned seating because of the hassle and cost of enforcing it.

In the following section you’ll create a serverless app for checking tickets and have it output the event details and assigned seats for valid tickets.

4.3.1. Building a ticket-verifier app

You’re now back on iOS terra firma and have finished your excursion into the world of cross-platform scripting with Ruby. This section demonstrates the serverless validation approach on iOS. You’ll see that the Ruby cryptographic functions—which use OpenSSL—have equivalents in iOS in the CommonCrypto.framework.

Your ticket-verifier app will have these features:

· It will have a single-screen UI for hassle-free scanning at the venue entrance.

· It will scan QR, Aztec, and PDF417 codes.

· It will only accept tickets with a properly formatted barcode message.

· It will verify cryptographic signatures in barcode messages.

· It will reject tickets if their encoded event time differs by more than one hour from the current time.

· It will show the event details and seat number in case of success, or an alert detailing the reason for failure.

The finished ticket-verifier app scanning a valid ticket is shown in figure 4.13.

Figure 4.13. Passbook ticket-verifier app

4.3.2. Reusing barcode scanner code

The QR Code scanning app you developed in chapter 3 has all the pieces you need for the ticket-verifier app. It’s already set up for scanning the three 2D barcode symbologies supported by iOS and Passbook. It was developed in a reusable manner (nice interfaces, delegation, proper prefixes), so it provides a great starting point. Let’s get started.

Create a new Xcode project, and from the QR Scanner project copy these files to the new project:

· DTAVFoundationFunctions.h and .m

· DTCameraPreviewController.h and .m

· DTVideoPreviewInterestBox.h and .m

· DTVideoPreviewView.h and .m

You’ll also reuse the Main.storyboard file, which has a full-screen video preview with a focus box. Make the focus box a bit wider in Interface Builder (see figure 4.14), so that it’s more convenient for targeting those rather wide PDF417 barcodes.

Figure 4.14. Making the scan box wider

As is usual when using the iPhone camera, you’ll need to add AVFoundation.framework in the Link Binary with Libraries build phase.

For the sake of simplicity, the UI will be generated from the storyboard. The scanning logic for this app will be in the app delegate. The following addition to AppDelegate.m grabs a reference to the scan preview view controller and sets itself as a delegate. This causes the delegate callback for when a new barcode has been detected to call into the app delegate for processing:

4.3.3. Serverless pass validation

To validate the barcode message signature, you need a way to get a hex representation of a string’s SHA1 hash. Here’s such a helper method, which uses CommonCrypto.framework. This framework is automatically linked with all apps via the System dynamic library, so you don’t need to add it to the linking build phase but only import the header for using it:

The following code snippet shows two helper methods for reporting to the user either a valid pass or what went wrong validating one. The latter’s basic functionality is achieved with a UIAlertView:

Now for the scan delegate method. This method checks the validity of the pass on several levels, and if it reaches the bottom, it reports a valid pass. You want to ignore new barcodes while an alert is still showing to prevent multiple alerts from stacking on top of each other:

These checks—if statements with a return—weed out tickets that aren’t valid for the current event. These checks are performed on top of the checks that iOS already made when the user added this pass to the device. You could say that Apple’s checks pertain to the pass’s syntax, whereas you’re responsible for verifying the pass’s semantics. This is natural, because only you know under which circumstances you would want to consider a pass to be valid.

And you’re done!

Now, with the Ruby script, generate a pass with an event time that’s no more than 60 minutes away. Send this to your iPhone by email and add it to Passbook. Open up the pass so that the barcode is visible. Then scan this pass with the verifier app, and it should be reported as valid. Change the event’s time to be further away, and the pass should be reported as being too far in the future.

Here are some suggestions as to how you could further improve this ticket-verification solution:

· Detect duplicate seat assignments by tracking which seat numbers have been filled.

· Configure specific events and validate tickets against these instead of using the current time.

· Improve the user interface by replacing the alert views with something nicer.

· Communicate scanned tickets to a server-based API.

4.3.4. Pass validation takeaways

The sample app you built in this chapter demonstrates a simple way of validating Passbook passes without a server. You’ll usually want to be able to verify passes as quickly as possible while the user is holding out the iPhone for you to scan. There is little room for delay or for not being able to scan a pass because you lack an internet connection.

Even nowadays with ubiquitous 3G/LTE internet, there are places where connectivity is limited or utterly demolished by the sheer number of iPhones around. At large conferences promising free WiFi, people often bring their own wireless hotspots (a.k.a. MiFis) and multiple iOS devices, and these often overwhelm the limited WiFi frequencies and destroy the organizer’s WiFi network. Time slots on 3G antennas are even more likely to get overloaded by too many devices being in close proximity to each other, such as in a sports stadium.

You should evaluate your real-world scenario and determine whether you absolutely need server connectivity or if you can validate tickets first and then upload the scan info to your server later on. The serverless verification technique discussed in this chapter might save your life (as an iOS developer).

These are the key verification takeaways:

· Being able to quickly verify tickets as they are being presented is important for avoiding “traffic jams” at the venue entrance.

· If your usage scenario involves many iOS developers in close proximity, then plan for times without connectivity.

· Using a secret “salt” phrase together with a cryptographic hash at both creation and verification time is a powerful technique for validating passes without a server.

· Providing an enterprise-level pass-verification app can be fun as well as lucrative.

Creating passes for other companies

Many people have ideas for Passbook-based solutions that involve creating passes for clients or users. I asked Apple about an app where one user would create an IOU for a friend. This would be a coupon stating that user A owes a sum of money to user B. User B could redeem this coupon at a later stage in exchange for user A returning the money. Apple stated categorically that they would not approve such an app.

Apple’s review guidelines state thus:

23.3 Passes must be signed by the entity that will be distributing the pass under its own name, trademark, or brand or the App will be rejected and Passbook credentials may be revoked

Apple’s rule would require user A to have a developer account and signing certificate so that he can distribute the IOU pass in his own name.

As this chapter has demonstrated, it would be easy to create valid passes for—say—Coca Cola. Logos and suitable artwork can be come by with ease. If Apple allowed everybody to create passes for anyone, this would quickly erode trust in Passbook. The suggested workaround is that if a company wants to implement Passbook, they should register a developer account. If you’re contracting for them, they can add you as a team member. This way you could take care of their Passbook type identifier and certificate on their behalf.

4.4. Summary

In this chapter we focused on two major aspects of Passbook, both of which related to barcodes. You’ve learned how to create signed Passbook passes on any platform that has Ruby, and you built a verification app that checks those passes at the entrance to your venue.

iOS also includes view controllers and methods you can use to access the passes in the user’s pass library that match your developer prefix. These APIs are grouped within the PassKit.framework. With this framework’s methods, users can add passes to their pass library without leaving your app. Imagine a boarding pass app that lets the user add passes for flights. Or that allows the user to pick a seat during online check-in. This app could communicate with the airline’s server and update the pass with the new seat number. Apple refers to this kind of app as a companion app.

Another feature that we didn’t cover is the ability of passes to contain a web API URL where apps can register for push notifications. This allows you to push any updates to passes to the individual users. This goes hand in hand with Apple’s Push Notification service for updating passes. Read the documentation on Apple’s website for all the features of Passbook and PassKit.

I hope that you’re beginning to see the promise of Passbook, and that it doesn’t have to be only for big corporate uses. With the information in this chapter, you can come up with your own usage patterns. Your knowledge of Passbook and barcode scanning will allow you to innovate at both ends.

But Apple’s Passbook system couldn’t exist without system-level support for displaying barcodes. In the next chapter we’ll look at how iOS generates 2D barcodes.