Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
A .Net Library for generating Passbook packages for iOS 6. Please get involved by forking and updating the repository.
branch: beta

This branch is even with tomasmcguinness:beta

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
Passbook.Generator.Tests
Passbook.Generator
Passbook.Sample.Web
packages
.gitignore
README.md
dotnet-passbook.sln
dotnet-passbook.v11.suo

README.md

dotnet-passbook

A .Net Library for generating Passbook packages for iOS 6

Why

The goal of this project is to build a library that can generate, sign and zip Passbook files for use with iOS 6's Passbook.

Certificates

Before you run the PassGenerator, you need to ensure you have all the necessary certificates installed. There are two required.

Firstly, you need to install the Apple WWDR (WorldWide Developer Relations) certificate. You can download that from here http://www.apple.com/certificateauthority/ . You must install it in the Local Machine's Intermediate Certificate store. I've hardcoded that location

Secondly, you need to installed your Passbook certificate, which you get from the Developer Portal. You must have a full iPhone developer account. There are instructions on my blog for generating a certificate if you're using a Windows Machine.

You can place this certificate in any of the stores, but it must be placed into the "personal" folder. When constructing the request for the pass, you specify the location and thumbprint for the certificate. If running this code in IIS for example, installing the certificate in the Local Machine area might make access easier. Alternatively, you could place the certificate into the AppPool's user's certification repository. When you install the certificate, be sure to note the certificate's Thumbprint.

Types of Pass

At present, there are two very simple pass types available with this code. They are just to give an idea of how the underlying PassGeneratorRequest can be customised.

Technical Stuff

To generate a pass, start by declaring a PassGenerator.

PassGenerator generator = new PassGenerator();

Next, create a PassGeneratorRequest. This is a raw request that gives you the full power to add all the fields necessary for the pass you wish to create. Each pass is broken down into several sections. Each section is rendered in a different way, based on the style of the pass you are trying to produce. For more information on this, please consult Apple's Passbook Programming Guide. The example below here will show how to create a very basic boarding pass.

Since each pass has a set of mandatory data, fill that in first.

PassGeneratorRequest request = new PassGeneratorRequest();
request.Identifier = "pass.tomsamcguinness.events";   
request.FormatVersion = 1;
request.SerialNumber = "121212";
request.Description = "My first pass";
request.OrganizationName = "Tomas McGuinness";
request.TeamIdentifier = "Team America";
request.LogoText = "My Pass";
request.BackgroundColor = "#FFFFFF";
request.ForegroundColor = "#000000";

Choose the location of your Passbook certificate

request.CertThumbprint = "22C5FADDFBF935E26E2DDB8656010C7D4103E02E";
request.CertLocation = System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser;

Next, define the background images you with to use. You must always include both standard and retina sized images.

request.BackgroundFile = @"C:/Icons/Starbucks/background.png";
request.BackgroundRetinaFile = @"C:/Icons/Starbucks/background@2x.png";

request.IconFile =@"C:/Icons/icon.png";
request.IconRetinaFile = @"C:/Icons/icon@2x.png";

request.LogoFile = @"C:/Icons/logo.png";
request.LogoRetinaFile = @"C:/Icons/logo@2x.png";

You can now provide more pass specific information. For a boarding pass the style must be set. All information is then added to fields in three sections. The primary, secondary and auxiliar sections.

request.Style = PassStyle.BoardingPass;

request.AddPrimaryField(new StandardField("origin", "San Francisco", "SFO"));
request.AddPrimaryField(new StandardField("destination", "London", "LDN"));

request.AddSecondaryField(new StandardField("boarding-gate", "Gate", "A55"));

request.AddAuxiliaryField(new StandardField("seat", "Seat", "G5" ));
request.AddAuxiliaryField(new StandardField("passenger-name", "Passenger", "Thomas Anderson"));

request.TransitType = TransitType.PKTransitTypeAir;

Adding a location is accomplished using the AddLocation

request.AddLocation(new LocationField(51.121212121,0.0123484835,"Piccadilly Circus");

Finally, you can add a BarCode.

request.AddBarCode("01927847623423234234", BarcodeType.PKBarcodeFormatPDF417, "UTF-8", "01927847623423234234");

Generate the pass, by passing the request into the Generator. This will create the signed manifest and package all the the image files into zip.

Pass generatedPass = generator.Generate(request);

Call GetPackage to get the zip file. This will return a byte[] representing all the data in the signed zipfile.

generatedPass.GetPackage()

Updating passes

To be able to update your pass, you must provide it with a callback. When generating your request, you must provide it with an AuthentionToken and a WebServiceUrl.

request.AuthenticationToken = "vxwxd7J8AlNNFPS8k0a0FfUFtq0ewzFdc";
request.WebServiceUrl = "http://192.168.1.59:82/api";

There are several methods that the Pass will invoke when it's installed and updated. To see a reference implementation of this, look at the PassRegistrationController class in the Passbook.Sample.Web project.

The method that is of most interest in the beginning is the Post method as this actually captures the PushToken for the passes. The UpdateController has a very simple mechanism for sending an update. At present, the device ID is hard-coded, but this should provide a working reference

Sample Web

As part of Passbook.Sample.Web project, you can run this and access the pages from your iPhone to see how the passes are installed and to see the registration and update mechanism is progress.

The project also includes some dummy requests, so illustrate how you can create wrappers around the basic PassGenerationRequest. The above BoardPass can be generated using the BoardingPassGeneratorRequest. Instead of adding the fields explicitly, this encapsulates this logic, so you can call

request.Origin = "San Francisco";
request.OriginCode = "SFO";

request.Destination = "London";
request.DestinationCode = "LDN";

request.Seat = "7A";
request.BoardingGate = "F12";
request.PassengerName = "John Appleseed";

request.TransitType = TransitType.PKTransitTypeAir;

/Home/Index will open a simple HTML page where you can choose the card type.
/Pass/EventTicket will generate an event based Pass (not fully functional).
/Pass/BoardingPass will generate simple baording card.

These passes are functional and can be saved Passbook.

Contribute

All pull requests are welcomed! If you come across an issue you cannot fix, please raise an issue or drop me an email at tomas@tomasmcguinness.com or follow me on twitter @tomasmcguinness

Something went wrong with that request. Please try again.