Beginning Passbook in iOS 6: Part 1/2

Marin Todorov

This post is also available in: Chinese (Simplified), Russian

Learn Passbook in the iOS 6 SDK!

Note from Ray: This is the second iOS 6 tutorial in the iOS 6 Feast! This tutorial is an abbreviated version of one of the chapters from our new book iOS 6 By Tutorials. Marin Todorov wrote this chapter – the same guy who wrote most of the “bonus” chapters in iOS 5 by Tutorials. Enjoy!

This is a blog post by iOS Tutorial Team member Marin Todorov, a software developer with 12+ years of experience, an independent iOS developer and the creator of Touch Code Magazine.

The passes implementation in iOS 6 is the hottest technology coming out from Apple right now, and it’s groundbreaking for more reasons than one might imagine.

Passes are the result of some awesome fusion. Four separate technologies all combine together to deliver a completely new experience to iPhone users:

  1. The new iOS framework PassKit
  2. The new Passbook app bundled with iOS
  3. Apple’s push notification service (this time delivery is guaranteed)
  4. Your own server code!

Passes are very different from any other Apple technology you’ve used before. What makes them unique is that passes are a concept wrapped around a file format. It’s up to you to create a pass file, deliver and present it to the user in any way you like. And the choice of technology and programming language to do that is also up to you!

It hardly needs to be said that with this setup, you have much more control over how you implement things than you normally do with Apple technology.

Since Apple does not handle the mechanisms behind passes, you need to employ a bunch of different technologies to make them work. In this tutorial, you’ll use Objective-C and iOS; use JSON; send multi-part emails with attachments; use OpenSSL to digitally sign files; and more.

The tutorial is divided into two parts:

  1. First, you’ll learn how to create a pass by hand. You’ll start with an empty file and finish with a completely styled and digitally-signed pass.
  2. In the second part, you’ll develop a small iOS app in order to preview passes in the iPhone Simulator or on your device. You’ll also learn about different kinds of passes, thus becoming a Pass Pro.

The trip through this chapter will be wild, but also very rewarding – by the end of it, you’ll have mastered the very latest in Apple technology!

Part 1: Understanding and building Passes

Passes are everything in your pocket

Apple’s simplified explanation of passes is that they are “everything in your pocket.” I like that line very much, because it demonstrates so well how imaginative you can and should be about creating your pass applications and services. Passes can be anything.

But what are they, anyway?”, you might ask.

Well, here’s how a pass looks on the iPhone:

You can easily spot a few different elements on the front of this pass that give you important information: a logo and a company name on the top, the words “Free hug!”, which clearly denote what this pass is all about, and also information concerning its validity (start date, duration).

Then there’s that barcode at the bottom. It’s much like the barcodes you’re already used to seeing on train tickets, airplane boarding passes, store cards, etc. If you think about it, a pass on your iPhone can carry the same information as any of those paper passes you are used to stuffing in your pockets, right? Some text, a barcode – and that’s it. Trust me, though: a digital pass on your iPhone can also do a lot more.

What makes a pass, a pass

Look again at what’s on the pass below and consider the different sections it has:

All types of passes have these important areas in common:

  1. Top header. A top ribbon containing an easy-to-identify logo and a company name. This header area is the part of the pass a user will see when they open a full deck of passes in Passbook. It includes the most essential info you want to provide to the user, so they can easily spot the pass they need.
  2. Main content area. A section containing the substance of the pass. Each pass type has different styling for this section, and it usually shows the information that you want most prominently displayed once the pass is open. It’s very useful for labels like “20% off,” “One free coffee,” “Balance: $120” or anything else of the sort.
  3. Additional info. The third section is for additional information – material that’s still very important (the validity of the promotion and the start date in the example), but definitely not as important as what the pass is all about.
  4. Barcode. The barcode contains encoded information that can be easily transferred to other systems by scanning it with a barcode reader. In the example above, the barcode contains a secret code. When decoded by a scanner, it entitles the bearer of the pass to one free hug (to be delivered immediately).

By now you’re probably considering which of the paper passes, store cards, etc. that you use on a daily basis can be converted to a digital pass on your iPhone!

Do I board with this pass, or do I get a free coffee?

Before you dive into coding, have a look at the different types of passes.

Apple has defined four types of passes, each for a common use, as well as a fifth type for “generic” use. Why these different pass types, and how do you recognize them?

The pre-defined pass types are each styled to draw attention to different pieces of information that suit the purpose of the pass. There’s a reason why the layout and content of your gym membership card is different from your concert ticket! The first needs your picture on it while the second doesn’t, for example.

Layout is the main way to differentiate between passes, but UI features like rounded corners and paper cutouts also make passes easily distinguishable. The differences are small, but noticeable, and that’s one of the reasons you have to make sure you use the correct type for your pass.

Here are the four pre-defined pass types:

  • Coupon
  • Boarding pass
  • Store card
  • Event ticket

Then of course, there is the generic type of pass. This tutorial will cover all five types in detail in Part 2.

For now, have a look at the boarding pass example below. You can see it’s pretty similar to the hug coupon from earlier, but has some important differences: it features a great two-column layout that makes it very easy to spot the departure and arrival cities; the departure platform number, time and seat number are also well-placed.

By now I am sure you are convinced that passes are a great thing for the iPhone! Now let’s turn to how passes are set up, and how to make one!

The guts of the pass

This section will introduce the building blocks for a pass. A pass comes to the user as a file with a .pkpass extension. (“pkpass” standing for PassKit Pass – totally makes sense, right?)

The .pkpass file is just an ordinary .zip file with a custom extension. If you rename one to ZIP and extract it, you’ll find several files. Here are the contents of the Free Hug Pass you saw earlier:

  • pass.json – the description of the pass information fields, their content, and meta information.
  • manifest.json – the file that describes the list of files inside the pass and the SHA1 checksums of each of those files.
  • signature – a detached DER signature of manifest.json, generated using an Apple-provided certificate.
  • background.png – the image to show on the front of the pass.
  • background@2x.png – the retina-sized image for the front of the pass.
  • logo.png – the logo to show in the pass header. Apple recommends a solid one-color logo. The image size is up to you, but the height shouldn’t be more than 50px in order to fit inside the header.
  • logo@2x.png – the retina counterpart of logo.png.
  • icon.png – a small icon for the pass, used when the pass comes as an attachment in Mail. As of the time of writing, there is still no documentation about the icon’s size, but it looks to be 29×29 pixels (bigger size icons are scaled down, so they look fine as well).
  • icon@2x.png – the retina icon file.
  • strip.png and strip@2x.png – the image strip, used as background behind the primary fields; used only for the coupon and store card passes.

And that’s all!

As you can see, the main file of the pass is the JSON file pass.json. Inside it you declare all the contents of the front and back of the pass. Along with this JSON file, you provide all images the pass should display (in the case of a coupon, you can supply only background.png and its retina counterpart). Finally, you need a manifest file, which states the original SHA1 checksums of all those files above, and a detached signature signed by you, so that Passbook can verify that the pass hasn’t been amended since you created it.

Let’s write some JSON!

You’re at the point where you can write some code. Let’s see if you can reproduce the Free Hug coupon!

But wait! JSON isn’t Objective-C. It’s not even a programming language of any sort. It’s just a markup language used to describe data structures… So, how do you write JSON? Actually, you can use any text editor – Xcode, TextMate, Coda or even TextEdit. In this chapter, you’re going to use Xcode.

From Xcode’s menu choose File/New/File… and then choose iOS/Other/Empty for the file type. Name the new file pass.json and save it in a folder of your choice. Note you probably want to create a new folder to store the pass in, because you’ll be putting a lot of pass-related files in the same folder and it will be nice to keep it all together.

You should now be looking at a tragically empty window, like this one:

But’s that’s OK – no worries!

For those of you not familiar with JSON notation – it’s pretty easy. You can use numbers, strings, arrays, and dictionaries. The information is written out like this:

14.37457for numbers 
“Some text here!” – for strings
[object1, object2, object3,]for arrays


{“key1”: object1, “key2”: object2, “key3”: object3,}for dictionaries

Object1, object2, object3 and so forth can be any of the four types of objects above – i.e. you can have arrays of dictionaries, dictionaries that hold arrays, strings, numbers, and so on.

You can read more on JSON here:

Note: You might notice that Apple’s proprietary plist file format stores the same types of primitive data that JSON stores – arrays, dictionaries, numbers, and the like. You might wonder why Apple chose to use JSON instead of the plist file format we all know and love.

Well, passes are most likely to be generated in an environment that is not iOS or OS X – most likely, passes will be generated on a web server in response to a request from a user. Therefore Apple wanted to make it easier for you to generate passes in all possible web-scripting languages, and since JSON is well-supported in PHP, .NET, Ruby, Python and so forth, in the end JSON probably seemed like the best choice.

Let’s start with the barebones of the Free Hug coupon! Copy this code into your pass.json file:

    "formatVersion" : 1,
    "passTypeIdentifier" : "",
    "serialNumber" : "001",
    "teamIdentifier" : "<YOUR TEAM IDENTIFIER>",
    "organizationName" : "Free Hugs LLC",
    "description" : "Coupon for 1 Free Hug"

This is the bare minimum of meta-information you need to provide:

  • formatVersion – the file format version, and since this is a brand-new file format, you’re using 1 (note that 1 is a number; if you provide a string for the value, the file won’t validate).
  • passTypeIdentifier – this is the identifier of the Pass. It’s pretty similar to the bundle identifier in an iOS app. More will be said about this identifier in a minute.
  • serialNumber – this is the serial number of the pass. You generate this number any way you like – it can be numeric, like “00193” (note that it still needs to be written out as a string value), or a combination of letters and numbers, like the serial numbers you’ve seen on airplane boarding passes (for example, “XS83A”).
  • teamIdentifier – this is the unique 10-character identifier Apple assigns to you as an iOS developer. If you’ve been creating your own iOS apps, you should already be familiar with it. To find your team identifier, log onto the iOS Member Center and click the name of your organization. You will find it there next to a label titled “Company/Organization ID”. I’ll show you another way to find it later on as well.
  • organizationName – the name of the issuing entity.
  • description – a short description of the pass.

This is a lot of information, so let’s see how is it useful to Apple.

Since the passes are not necessarily connected to an iOS app, there’s no automatic way for Apple to connect a pass to a given iOS developer account (which it needs to do to validate the pass contents). Passes might arrive to the user’s device independent from an app, via mail or web download (or another way). This is why the teamIdentifier is included in the meta information inside the pass – to connect the pass instance to an iOS developer.

Once Apple knows the identity of the developer who created the pass, they take the passTypeIdentifier to figure out which type of pass it is (of all the ones defined by a given developer account). Every pass type has its own certificate, so Apple can use this certificate and validate the signature included in the pass bundle – i.e., make sure nobody tampered with the pass contents.

Finally, the serial number is used to identify the unique instance issued for the given pass type.

To recap, consider an example:

  • Joe’s Café has an iOS developer account with Apple. Thus, they use their team identifier on all their passes.
  • They have store cards with preloaded store credit, which users can use to order yummy coffees in the shop. Store cards have passTypeIdentifier “”.
  • They also have discount coupons that have a different passTypeIdentifier – “”.
  • A given user can own more than one store card (for example, they bought one and a friend gave them one as a present), so the serial number is used to distinguish between two store cards of the same pass type (for example, “0134” and “0274”).
  • Passes from the same passTypeIdentifier will be grouped together inside Passbook. When the user is at Joe’s Café, they’ll tap the stack of Joe’s Café store cards in Passbook, and choose the one they want to use – probably the one that still has credit on it!

By now you should understand pretty well how pass identification works. So “pass” this section and move on to the next, where you’ll create your first pass type.

Get me the certificate!

Head to the iOS Developer Portal (, and after you log in, open up the iOS Provisioning Portal from the menu on the right-hand side.

If you’ve already been checking out the new stuff for iOS 6, you might have noticed the new item in the left menu called Pass Type IDs. Click on that link and on the next page, you’ll see a list of all the pass types you’ve already created (probably empty at this point).

Click the New Pass Type ID button and you’ll go to a page where you can create a new type. In the description field enter “Free Hug Pass” and in the Identifier field enter “”. For the Pass Type ID, Apple recommends the reversed domain notation with a prefix of “pass.” So that’s the format you’re using.

Note: For the purposes of this chapter you can certainly use “com.yourdomain”, but in production applications remember that you should replace com.yourdomain with the actual reverse notation for your domain. ☺

Also note that if you decide to change the identifier here to something other than “”, you’ll also have to update the passTypeIdentifier value in pass.json accordingly.

Next, simply click Submit to create your pass.

By the very way that light indicator is not lit up in green, you might already guess there’s something missing. Yes – you are right. You still need to generate the pass certificates. Click on Configure to do that. The next page that comes up is a good place to spot the full identifier of your pass.

Here you can see your teamIdentifier (it’s the first 10 characters beginning with ABC) and update pass.json with it – make sure to replace only the placeholder and leave the quotes around it!

All right! Your pass.json metadata is now updated. However, there’s still an extra step to get your certificate imported into your development environment.
Back in the iOS Provisioning Portal, click the Configure button:

This will launch the Pass Certificate Assistant (*fancy name!), which will guide you through the process of generating your certificate. Pay attention to the dialog and follow the steps.

After you upload your signing request, your certificate will be generated in a timely manner and you should see the success dialogue:

Click Continue one more time and then click Download to get the certificate file. After the file downloads, find and double click it to import it into the Keychain. Note that it’s most probably in the Downloads folder inside your user folder, unless you’ve set another default download location in your browser.
If Keychain asks you to confirm the import, click the Add button:

And then you should see your certificate in Keychain Access:

w00t – you’re done making your certificate! Now you have real metadata in your JSON file and the proper certificate for when the time comes to sign the pass.

Passes come in style this year!

Let’s continue building the pass.json file – next up is styling its looks.

Open up pass.json and at the end of the line defining the “description” key, add a comma – you need this because you’re going to be adding more keys to that dictionary. Just before the closing curly bracket, add:

    "logoText" : "Free Hugs LLC",
    "foregroundColor" : "rgb(255, 255, 255)",
    "backgroundColor" : "rgb(135, 129, 189)",
    "labelColor" : "rgb(45, 54, 129)"

Here’s what those keys do:

  • logoText – this is the text that shows up in the pass header next to your logo image.
  • foregroundColor – the color of the text.
  • backgroundColor – the background color of the pass. Passbook will take the background color code and create a nice gradient based on it that gives the front of the pass a very nice visual appearance when presented to the user. Apple recommends using vibrant colors.
  • labelColor – depending on your background color, the labels (or hints) on the pass will be rendered in a color that is nicely recognizable over the background. If you want, though, you can specify your own color code for those labels.

Now your pass has some style! Heidi Klum would be proud.

You’re going to keep adding elements until you have the bare minimum to proceed to building and testing in Passbook. Next, you’ll add a barcode.
Sounds complicated, right? Luckily, it’s incredibly easy to do this. PassKit supports three different types of barcodes (all of them being 2D barcode formats): QR, PDF417 and Aztec. To illustrate what I mean:

In other words, passes don’t support those old-fashioned barcodes you usually see on the packaging of items in the grocery store and (anticipating your question) support for them is not planned. Instead, PassKit uses fancy 2D formats, which are easier for image-based scanning devices (like the iPhone) to read.
You will use the PDF417 standard for the Free Hug coupon (the middle option in the picture above), so add a comma after the last line of the code (again before the closing bracket) and paste in the barcode JSON:

    "barcode" : {
        "message" : "All you need is love",
        "format" : "PKBarcodeFormatPDF417",
        "messageEncoding" : "iso-8859-1"

Believe it or not, this is all you need to do – Apple will take care of generating the barcode for you! The barcode dictionary has three keys:

  • message – this is the data you’d like the barcode to contain. It can be a unique code, the bearer’s client ID, or anything else. In the case of the Free Hug pass, it’s just a text message that authorizes the bearer to a promotional hug.
  • format – the barcode format name. To generate a 2D barcode, use one of the constants : PKBarcodeFormatQR, PKBarcodeFormatPDF417 or PKBarcodeFormatAztec.
  • messageEncoding – the name of the text encoding used to decode the message. If you use a non-“latin1” language, you will want to use UTF8 or any other text encoding that suits you (if you use standard English letters and numbers, the default to go with is “iso-8859-1”).

So far, the pass source code should look something like this:

    "formatVersion" : 1,
    "passTypeIdentifier" : "",
    "serialNumber" : "001",
    "teamIdentifier" : "ABC1230000",
    "organizationName" : "Free Hugs LLC",
    "description" : "Coupon for 1 Free Hug",
    "logoText" : "Free Hugs LLC",
    "foregroundColor" : "rgb(255, 255, 255)",
    "backgroundColor" : "rgb(135, 129, 189)",
    "labelColor" : "rgb(45, 54, 129)",
    "barcode" : {
        "message" : "All you need is love",
        "format" : "PKBarcodeFormatPDF417",
        "messageEncoding" : "iso-8859-1"

Next you’ll add some valuable information to the front side of the pass.

Once again, after the closing bracket of the barcode dictionary add a comma. (You keep doing this because I’d like for you to stick to having a valid JSON file at all times. Once you’re used to writing valid JSON, you can save yourself lots of time while debugging down the road.)

Go ahead and add the key denoting a coupon type of pass (again, paste this just before the final closing bracket):

    "coupon" : {

Inside this empty dictionary you will be adding all the definitions and data to show information on the coupon pass. In between the enclosing brackets of “coupon” add:

       "primaryFields" : [
           "key" : "offer",
           "label" : "for you",
           "value" : "Free hug"

This structure looks a bit weird at first glance, but believe me – it all makes sense. First you add a new key called “primaryFields”, the value of which is an array. Why an array? Because all sections can display one or more fields, so you need a list to specify them one after another.

Each dictionary in the list describes one field. You’ve probably already figured it all out, but let me spell it out just in case. For each field you’ve got the following basic keys:

  • key – the field name. In this case, the “offer” field is the one that shows up in the main content area of the pass.
  • label – the accompanying label to the field. In this case, “for you” will show up in small letters below the text.
  • value – the text the field shows on the pass. In this case, “Free hug!” will show up very large in the majority of the content area.

There are more keys you can use for each field, but you’ll have a look at those later on.

The important thing is – you now have a complete pass.json file! Sweet!

Time to make it beautiful, baby!

They say an image is worth a thousand words – lucky for you, there’s no space for thousand words on the front side of the pass, so when in need you might as well use an image.

Go ahead and download the assets I’ve prepared for you: Extract the files and inside the FreeHugCoupon folder you will find a bunch of PNG files. Copy them over into your pass work folder.

And that’s it – you’re done! Phew, that was easy.

Wait, what? You don’t have to add any code inside pass.json to tell Passbook which image files to load. That’s right!

Passbook will automatically load image files following standard naming conventions. This means images named icon.png; icon@2x.png; logo.png; logo@2x.png; strip.png and strip@2x.png will be displayed on the pass, if provided. No need to do anything but include these files in the pass bundle. (There’s also few more images that this chapter will cover later on.)

Note: There’s one nasty gotcha about the pass images, which took me a while to figure out – the image files need to be exported as PNG24 format. For some reason the much smaller-in-size PNG8 format just won’t show up in Passbook.

“Let’s give that pass a try! I want to see it already!”, for sure you are crying in despair.

Unfortunately, until the pass bundle is complete, signed and zipped you cannot preview the pass. Passbook won’t display any invalid (incomplete) passes. So muster a little more patience and keep going.

The pass manifest

The pass manifest is another JSON file you need to create, and it describes all the files included in the pass bundle and their SHA1 checksums.

You can make this yourself by generating the SHA1 checksums for each file yourself (as I’ll show you in a minute), but so that you can move faster with building your first pass I’ve included an already-generated manifest.json file in the file you already downloaded and extracted. Find manifest.json inside the folder where you extracted the zip file and copy it over to your pass work folder.

It’s contents are as follows:

 "pass.json":"<INSERT YOUR PASS SHA1 HERE>"

The SHA1 checksums for the images are already pre-filled, but the final checksum – the one for your pass.json file – is not. You are going to generate its SHA1 yourself. It’s quite easy – open up Terminal and navigate to your pass folder.

Note: If you aren’t familiar with navigating directories in the Terminal, do this: move your pass files into a folder on your Desktop and call it “FreeHugCoupon”, then launch Terminal and enter this command:

cd ~/Desktop/FreeHugCoupon

There you go.

Enter this command at the Terminal prompt:

openssl sha1 pass.json

The output of the command should look something like this (the actual checksum will be different for you):

SHA1(pass.json)= c24766ef5aa92197eace640fcc4fb584a505a733

Select the alphanumeric checksum value and in your manifest.json file replace “” with the checksum string. Save the file and you’re done! (Make sure you leave the quotes alone.)

NB! It’s important that you do not edit pass.json anymore until told to do so. If you add even one character to pass.json, the SHA1 checksum will change and your manifest.json will become invalid, since the checksum given there will no longer match the checksum of the modified pass.json file.

This is the last source file you need for your pass. Awesome!

Can I have your signature, please?

Now comes the most interesting part of creating a pass.

Remember the certificate you got from Apple for your pass type? You’ve imported it to your Keychain and you haven’t touched it since. Now you’re going to export the certificate and the key in PEM format, so that you can use them with OpenSSL.

Open up Keychain Access, select Certificates from the left menu (under Categories) and find the certificate called “Pass Type ID:”. Make sure you’ve selected the item itself and not the private key underneath:

Next right-click on the certificate and choose from the popup menu Export “Pass Type ID:”… Save the exported file as “Certificates.p12” inside your working pass folder. You’ll be presented with a dialog to choose a password:

To make the process a bit easier, just click OK – the certificate will be exported with no password protection.

Note: At this point you might be prompted to enter the password for the login keychain. If you are, then simply providing your user password should suffice.
The Certificates.p12 file now contains both the pass certificate and your private key. OpenSSL needs those in separate files, so now you have to extract them from the .p12 file.

Switch back to Terminal – it’s time for OpenSSL magic!

After making sure the current directory is the correct one (to double check, enter “ls –al” and hit Enter – you should see the file listing of the folder, and it should contain your Certificates.p12 file), enter the following command:

openssl pkcs12 -in Certificates.p12 -clcerts -nokeys -out passcertificate.pem -passin pass:

That’ll export only the pass certificate in PEM format and save it as “passcertificate.pem” inside the same folder. (OpenSSL will spit out the message “MAC verified OK” if the operation is successful.)

Next, export the key as a separate file with this command:

openssl pkcs12 -in Certificates.p12 -nocerts -out passkey.pem -passin pass: -passout pass:12345

Note that this time, you need to provide a password in order to export the key file. In this case, just use “12345” – obviously for production environments it’s advisable to use a strong password (doh!) – so, nothing of the “password1” or “passw00t” sort, please.

To sign your pass bundle you will need one more certificate – the WWDR Intermediate certificate, which authorizes the issuer of your own certificate – Apple. Chances are you already have it installed in your Keychain. Open up Keychain Access, select the “Certificates” category and look for a certificate called “Apple Worldwide Developer Relations Certification Authority” (yes, this is a quite long name indeed):

If by any chance you don’t have this certificate already imported, then open up in your browser this web page: Here you can freely download the most important Apple certificates you might need. Scroll down, find the WWDR certificate, download the .cer file and import it in Keychain.

You’re ready to go on with exporting the certificate. Back in Keychain Access right click on the certificate name and choose the Export option in the popup menu:

In the “Save as…” dialogue find the File format drop box and choose Privacy Enhanced Mail (.pem) option:

In the text field at the top of the dialogue give the file the name “WWDR.pem”, select your working pass directory as destination, and hit the Save button to finish the export.

You’re ready to create the signature. Enter this command:

openssl smime -binary -sign -certfile WWDR.pem -signer passcertificate.pem -inkey passkey.pem -in manifest.json -out signature -outform DER -passin pass:12345

Read through the command line above once more – it’s quite easy to understand all the parameters. The signer parameter is your pass certificate’s file name; inkey is the key file used to sign manifest.json; in is the input file name; out is the output file name; outform is the output format (you need “DER” to create a detached signature); and finally, passin is the password for the key file.

Now you have your signature and the production of the pass is almost complete.

The last remaining step is to combine the various files for the pass into a .pkpass file. Enter this command in the Terminal:

zip -r freehugcoupon.pkpass manifest.json pass.json signature logo.png logo@2x.png icon.png icon@2x.png strip.png strip@2x.png

By using the shell command “zip” you create a ZIP file called freehugcoupon.pkpass and the archive will contain all the files in the list that follows.
Believe it or not… that’s it! High fives all around! You did it!

Show me or I don’t believe it!

Yes, you’ve finally reached the point where you possess a complete and valid pass that you can see on your iOS 6-powered device.

Create an email message to yourself (or to the email account you have set up on your iOS 6 device) and attach the .pkpass file you just created. Send it over, open the mail in and voila! You should see the attachment turn into a pass, like so:

If you see the pass show up – congratulations! You’ve made it!

If not, don’t be disappointed – it’s a long and error-prone process, so you’ll have to go back to the very beginning and check that you performed all the necessary steps. Make sure your JSON files are valid and that you’ve exported your certificate and key correctly.

Tip: If you want to check the validity of your JSON files, use an online tool like to quickly proof your code.

Time to see the pass! Tap on it inside the email message and Passbook should pop up showing you some greatness!

This is pretty awesome! Tap the Add button at the top-right corner and you’ll see a neat animation of the pass sliding down (into the deck of passes, but yours is probably empty at this point) and then you will return to Mail.

Note: If you want a few additional passes in your Passbook to see how it looks when it’s less empty, try visiting using your mobile browser. The site has samples for a bunch of passes that should prove to be interesting. ☺

Now exit Mail and find and launch the Passbook app. Aha! It’s your first very own pass. Congratulations!

Preview the pass in Passbook, front and back (in case you’re wondering, you can access the back of the pass by tapping the small italic “i” on the bottom right-hand corner of the pass):

You must admit, the pass does look beautiful, but it’s not very informative. Yes – you’re going to add more fields to it in a moment.

I bet you are itching right now to try shredding the pass – go ahead! After all, you can now create as many as you want, so – shred some. ☺ Tap the trash bin button and…

Where to go from here?

Now you know the basics of creating a pass and distributing it over email. However there’s more to passes!

In part two of this tutorial you will learn:

  • how to add information to the pass
  • how to create different styles of passes
  • how to use all the features the pass file format offers
  • how to format numbers, dates, add links to maps, and much more!

And if you want to learn even more, check out iOS 6 by Tutorials, which contains a part three to this very tutorial, that leads you through the process of automating creation of passes and distributing them from your web server.

In addition, iOS 6 by Tutorials contains another entire chapter called “Intermediate Passbook” that shows you how to build an amazing web server based store credit card system that can update passes on the fly with push notifications – cool stuff!

In the meantime, if you have any questions or comments on what you’ve learned so far, please join the forum discussion below!

This is a blog post by iOS Tutorial Team member Marin Todorov, a software developer with 12+ years of experience, an independant iOS developer and the creator of Touch Code Magazine. You can also find me on

Marin Todorov

Marin Todorov is an independent iOS developer and publisher with background in various platforms and languages. He started developing on an Apple ][ more than 20 years ago and keeps rocking till today. Meanwhile he has worked in great companies like Monster and Native Instruments, has lived in 4 different countries, and (more recently) has worked on 10+ titles on the App Store.

Besides crafting code, Marin also enjoys teaching and training others. He sometimes speaks at iOS conferences.

Throughout his career he has authored or contributed to 7 great book titles, including "iOS7 by Tutorials", "iOS6 by Tutorials", "iOS Games by Tutorials", and O'Reilly's "Adobe AIR Cookbook". He maintains Touch Code Magazine, his tech blog about iOS development and also has a successful video course on game programming.

User Comments


[ 1 , 2 ]
  • Hi!
    Good tutorial. I was wondering if there is a way to access the icon.png image that shows up on the email attachment in xcode so that i can use it to show up in a table.

    Thank you!
  • Hi, I tried the tutorial, everything went smoothly, except:

    1. I put the .pkpass file on a local web server, I tried clicking a direct link to the file, hoping it would open on my iOS sim/device, but all I got is "safari was unable to open the file". This also happened with the official iOS pass samples on the Passbook Programming Guide. While on the simulator, no errors come up on the console log.

    2. I tried putting the pkpass in an email, it comes up ok, but when I click "add", the coupon is not added to passbook.

    3. I tried creating a pass with If I use their "on the fly" method, I get a good coupon, and I am able to save it. If I choose "download pkpass file" and then use it as described above in #1/#2 - same errors.

    The coupon is signed correctly, using correct team id and type id.

    My JSON is (I garbled the team/type ids):

    "formatVersion" : 1,
    "passTypeIdentifier" : "",
    "serialNumber" : "123",
    "teamIdentifier" : "XXXXXXXX",
    "organizationName" : "my brand",
    "description" : "my coupon",

    "logoText" : "logo text",
    "foregroundColor" : "rgb(255, 255, 255)",
    "backgroundColor" : "rgb(135, 129, 189)",
    "labelColor" : "rgb(45, 54, 129)",

    "barcode" : {
    "message" : "650438-5103453453",
    "format" : "PKBarcodeFormatPDF417",
    "messageEncoding" : "iso-8859-1"

    "coupon" : {
    "primaryFields" : [
    "key" : "offer",
    "label" : "for you",
    "value" : "Free hug"

    I tested it with the online validation tool, it's valid.

    any ideas?
  • Are you using a development device or a "real device"?
  • Hi, I tried both.
    Anyway, I just found the cause of the issue. Seem that the Simulator supports drag-drop of a pkpass from Finder on the Sim. If I do that, I DO see a detailed error message in the system log (I am using the Console app), so I found the problem:
    1. My json was changed after I created its sig in manifest.json, so I updated the sig
    2. If I want the pkpass file to be served as a pass, it's not enough to provide a direct link to it, I also need to change the content type to application/

    After I handled both of these issues, I was able to serve the pkpass file from my web server.
  • WHat do you mean by: "Apples push notification service (this time delivery is guaranteed)"

    APNs are never guaranteed delivery, and Apple's passbook documentation says updates are not guaranteed.
  • Hello Marin,

    Thank you for the great post! It helped me a lot to have a head start understanding about Passbook :)

    I had one question about your description about Passbook push notification.

    3. Apples push notification service (this time delivery is guaranteed)

    As I was browsing through Apple documentation later, I could not find this part. Moreover, I found following sentence in [url=""]the documentation[/url] which looks to me somewhat contradicting with the above description.

    ... 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.

    Can you point me the part that says push notification for Passbook is indeed guaranteed delivery?
  • They said it in the WWDC videos.

    I'm not saying that means its true. :)
  • strip.png and strip@2x.png the image strip, used as background behind the primary fields; used only for the coupon and store card passes.

    to be precise, you can have strip.png also on "Event ticket", as you can see on the official docs ... 5-CH4-SW45
  • you mentioned that passes are grouped in passbook using type Identifier and category, while it is grouped by type Identifier, category, and relevant date.
    and I am not sure about type identifier.
  • Hi..

    i have seen both the tutorials 1 and 2...

    i managed to get the desired output...

    in the 2nd tutorial, i added the passes u had provided in the file and they were displayed...

    however, when i delete those passes, they are still being displayed...

    i cant seem to figure out how this is happening...

    pls help...
  • What does the Xcode console say?
  • Hi,

    This works for me.
    My problem come when i wont to use my one pics. They are PNG-8 and i can't convert them to PNG-24.
  • Using Apple's "Signpass" to create the .pass is much easier and simpler. Simply create a folder named xxx.pass and keep the pass.json and all the images there and use the "signpass" to create the passes.
  • Hi,

    I want to create one pass and i need to create many instances of that particular pass and i need to get push notifications from APPLE based on locations on every pass.

    Is it Possible?..Please help me ...
    Anil Kumar
[ 1 , 2 ]

Other Items of Interest

Ray's Monthly Newsletter

Sign up to receive a monthly newsletter with my favorite dev links, and receive a free epic-length tutorial as a bonus!

Advertise with Us!

Hang Out With Us!

Every month, we have a free live Tech Talk - come hang out with us!

Coming up in May: Procedural Level Generation in Games with Kim Pedersen.

Sign Up - May

Coming up in June: WWDC Keynote - Podcasters React! with the podcasting team.

Sign Up - June

Vote For Our Next Book!

Help us choose the topic for our next book we write! (Choose up to three topics.)

    Loading ... Loading ...

Our Books

Our Team

Tutorial Team

... 55 total!

Editorial Team

... 21 total!

Code Team

  • Orta Therox

... 1 total!

Translation Team

  • Myeong Hoon

... 38 total!

Subject Matter Experts

  • Richard Casey

... 4 total!