Book Image

Instant Passbook App Development for iOS How-to

By : Keith D. Moon
Book Image

Instant Passbook App Development for iOS How-to

By: Keith D. Moon

Overview of this book

With iOS 6, Apple introduced the Passbook app as a central digital wallet for all the store cards, coupons, boarding passes, and event tickets that have become a popular feature of apps. The passes in Passbook can be tied to relevant locations and times, providing additional visibility for your brand or service. Instant Passbook App Development for iOS How-to is a step-by-step walkthrough of how to create, customize, deliver, and update a pass for Passbook, the newest and most exciting iOS 6 feature. With sample code and clear instructions you will be guided through the process and helped to avoid the pitfalls. Instant Passbook App Development for iOS How-to helps you understand Apple's Passbook feature, leading you through creating and distributing your first pass. Clear step-by-step instructions, along with sample code and resources, will get you up and running so you can integrate Passbook into your app or service. With this book you will learn how to create, customize, sign, deliver, and update your Passbook pass, with the help of sample code and clear instructions.
Table of Contents (7 chapters)

Delivering your Pass via an app (Medium)


Passes can be delivered through a companion iOS app. The app will provide a UI, using Apple's PassKit framework, allowing the user to view a Pass and choose to add it to their Passbook.

Getting ready

To follow these steps, it is assumed that you have some experience of Objective-C and creating iOS apps.

The example project, created as follows, can be downloaded from the following location:

http://passkit.pro/example-app

This app does not use Automatic Reference Counting (ARC), if you are using the code in an ARC environment, remove any calls to releasing objects.

How to do it…

  1. Open Xcode and create a new, single view project. The setup options used for the example project are shown in the following screenshot:

  2. In the Target settings, under Build Phases, expand the Link Binaries With Libraries section, and click on the + button. Search for the PassKit framework and add it. After this, the list of linked libraries should look like this:

  3. Add your previously created Pass to the project by dragging the file to the project navigator, in the example, this Pass is called Pass-Example-Generic.pkpass.

    In PKEViewController.h, replace the existing code with the following:
    #import <UIKit/UIKit.h>
    #import <PassKit/PassKit.h>
    
    @interface PKEViewController : UIViewController<PKAddPassesViewControllerDelegate>
    
    @property (nonatomic, retain) IBOutletUIButton *addPassButton;
    
    - (IBAction)addPassButtonPressed:(id)sender;
    
    @end
  4. In PKEViewController.m replace the existing code with the following:

    #import "PKEViewController.h"
    
    @interface PKEViewController ()
    
    @property (nonatomic, retain) PKPass *genericPass;
    
    @end
    
    @implementation PKEViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
      // Do any additional setup after loading the view, typically from a nib.
    
        // Create the PKPass from the bundled file
        // In a real App this may be retrive from the network.
    
    NSString *passFilePath = [[NSBundle mainBundle] pathForResource:@"Pass-Example-Generic" ofType:@"pkpass"];
    NSData *passData = [[NSDataalloc] initWithContentsOfFile:passFilePath];
    NSError *passError;
        _genericPass = [[PKPass alloc] initWithData:passData error:&passError];
        [passData release];
    
    }
    
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    - (void)dealloc {
    
        [_addPassButton release];
        [_genericPass release];
    
        [super dealloc];
    }
    
    #pragma mark - IBAction Methods
    
    - (IBAction)addPassButtonPressed:(id)sender {
    
        if (![PKPassLibrary isPassLibraryAvailable]) {
    
    NSLog(@"Passbook not available on this device");
            return;
    
        }
    
    PKAddPassesViewController *addPassViewController = [[PKAddPassesViewController alloc] initWithPass:self.genericPass];
    addPassViewController.delegate = self;
    
        [self presentViewController:addPassViewController animated:YES completion:^{
    
      NSLog(@"Add Pass view controller presented");
    
        }];
    
        [addPassViewController release];
    }
    
    #pragma mark - PKAddPassesViewControllerDelegate Methods
    
    - (void)addPassesViewControllerDidFinish:(PKAddPassesViewController *)controller {
    
        // Check if the Pass is now in the Pass Library
    
    PKPassLibrary *passLibrary = [[PKPassLibrary alloc] init];
    
        if ([passLibrary containsPass:self.genericPass]) {
    
            // If the Pass is now in the Library, we can't re-add it, only view it.
            [self.addPassButton setTitle:@"View Pass in Passbook" forState:UIControlStateNormal];
    
        } 
    
        [self dismissViewControllerAnimated:YES completion:^{
    
      NSLog(@"Add Pass view controller dismissed");
    
        }];
    
    }
    
    @end

    Open PKEViewController.xib, place a UIButton with the title Add Pass to Passbook on the view and connect it to IBOutlet addPassButton and IBActionaddPassButtonPressed for the sent event Touch Up Inside:

  5. Run the project in the iPhone Simulator. Tapping on the Add Pass To Passbook button will launch the PassKit UI, which displays the Pass and would allow the user to add the Pass to the Passbook app. At this stage however, the Pass will not be successfully added to the Passbook app as we need to use the correct provisioning profile.

  6. To build the app to an iPhone, we will need an appropriate provisioning profile. Therefore, you need to log in to the Apple Developer Center:

    https://developer.apple.com/account/ios/profile/profileList.action

  7. Under Provisioning, click on the New Profile button, and follow these steps:

  8. Choose a name for the development profile.

  9. Tick next to your certificate.

  10. Select the App ID in which you enabled Passes and generated certificates for previously.

  11. Choose the devices you will be using.

  12. Click on Submit.

  13. Once generated, download the provisioning profile and open it to load it into Xcode.

  14. In Target settings, under Info, ensure that the Bundle Identifier matches the app ID that was previously created and chosen in the profile creation.

  15. In Build Settings, under Code Signing Identity, ensure the profile created above is selected under Debug.

  16. Build to the device, and test that the presented Pass is successfully added to Passbook.

How it works…

The example app uses the PassKit framework to present a framework supplied view controller to the user, listen for a delegate callback when the user finishes interacting with the view controller and changes the button's title if the Pass was successfully added to Passbook.

Using the following code, the PKPass object is created from a NSData object:

NSString *passFilePath = [[NSBundle mainBundle] pathForResource:@"Pass-Example-Generic" ofType:@"pkpass"];
NSData *passData = [[NSDataalloc] initWithContentsOfFile:passFilePath];
NSError *passError;
_genericPass = [[PKPassalloc] initWithData:passData error:&passError];
[passData release];

For the sake of simplicity, in this example, the Pass is loaded from a file bundled with the app. It is much more likely in a real-world app that a Pass will be downloaded from a network resource.

PKPassLibrary provides access to the Passes contained in Passbook. It also provides a class method called isPassLibraryAvailable that will tell you if Passbook exists on that device, for example Passbook is not present on iPads. This method is used in the example app to decide whether to show the Pass view controller.

if (![PKPassLibrary isPassLibraryAvailable]) {
    NSLog(@"Passbook not available on this device");
    return;       
}

There's more…

Further documentation of the PassKit framework can be found in the following location:

https://developer.apple.com/library/ios/#documentation/UserExperience/Reference/PassKit_Framework/