/PassKitHelper

Helper library for all your Apple PassKit (Apple Wallet, Apple Passbook) needs.

Primary LanguageC#MIT LicenseMIT

PassKit Helper

Helper library for all your Apple PassKit (Apple Wallet, Apple Passbook) needs: create passes, sign pass packages, receive [de]install notifications and send pass updates.

Attention: Apple Developer Account required!

NuGet

Features

  1. Create pass packages (*.pkpass files):
    • With Fluent-styled PassInfoBuilder and PassPackageBuilder
    • Using byte[] and/or Stream as content images
    • Using byte[] or Stream or X509Certificate2 as certificates
    • Receive MemoryStream as result (save it to file or write to HttpResponse)
  2. Receive notifications from Apple about pass [de]installations and send updates:
    • Add UsePassKitMiddleware into your Startup.Configure()
    • Implement IPassKitService for real processing.

Samples

1. Configure to create passes

For console app

var options = new PassKitOptions()
{
    PassCertificate = new X509Certificate2(File.ReadAllBytes("pass.pfx")),
    AppleCertificate = new X509Certificate2(File.ReadAllBytes("AppleWWDRCA.cer")),
    ConfigureNewPass =
        p => p.Standard
                .PassTypeIdentifier("your-pass-type-identifier")
                .TeamIdentifier("your-team-identifier")
                // Add more "defaults" here if needed
};

IPassKitHelper passKitHelper = new PassKitHelper(options);

For web app

public void ConfigureServices(IServiceCollection services)
{
    services.AddPassKitHelper(options =>
    {
        options.PassCertificate = new X509Certificate2(File.ReadAllBytes("pass.pfx"));
        options.AppleCertificate = new X509Certificate2(File.ReadAllBytes("AppleWWDRCA.cer"));
        options.ConfigureNewPass =
            p => p.Standard
                    .PassTypeIdentifier("your-pass-type-identifier")
                    .TeamIdentifier("your-team-identifier")
                    // Add more "defaults" here if needed
    });
}

2. Creat pass and pass package file

var pass = passKitHelper.CreateNewPass()
    // Ths pass already have `PassTypeIdentifier`, `TeamIdentifier` 
    //   and all other values you configured in options.
    .Standard
        .SerialNumber("PassKitHelper")
        .OrganizationName("PassKit")
        .Description("PassKitHelper demo pass")
    .VisualAppearance
        .Barcodes("1234567890128", BarcodeFormat.Code128)
        .LogoText("PassKit Helper demo pass")
        .ForegroundColor("rgb(44, 62, 80)")
        .BackgroundColor("rgb(149, 165, 166)")
        .LabelColor("rgb(236, 240, 241)")
    .StoreCard
        .PrimaryFields
            .Add("version")
                .Label("Library version")
                .Value(libraryVersion)
        .AuxiliaryFields
            .Add("github")
                .Label("GitHub link")
                .Value("https://github.com/justdmitry/PassKitHelper");

var passPackage = passKitHelper.CreateNewPassPackage(pass)
    .Icon(await File.ReadAllBytesAsync("images/icon.png"))
    .Icon2X(await File.ReadAllBytesAsync("images/icon@2x.png"))
    .Logo(await File.ReadAllBytesAsync("images/logo.jpg"))
    .Strip(await File.ReadAllBytesAsync("images/strip.jpg"))
    .Strip2X(await File.ReadAllBytesAsync("images/strip@2x.jpg"));

MemoryStream packageFile = await passPackage.SignAndBuildAsync();

// Now you have to "deliver" package file to user using any channel you have
//   (save as attachment in email, download from your webapp etc)
await File.WriteAllBytesAsync("Sample.pkpass", packageFile.ToArray());

Code above will create this beautiful pass:

3. Implementing WebService for interaction

3.1. Implement IPassKitService

public class PassKitService : IPassKitService
{
    public Task<int> RegisterDeviceAsync() {}

    public Task<int> UnregisterDeviceAsync() {}

    public Task<(int status, string[]? passes, string? tag)> GetAssociatedPassesAsync() {}

    public Task<(int statusCode, MemoryStream? passData)> GetPassAsync() {}

    public Task ProcessLogsAsync() {}
}

3.2. Register in Startup

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddSingleton<IPassService, PassService>();
}

public void Configure(IApplicationBuilder app)
{
    ...
    app.UsePassKitMiddleware("/callbacks/passkit");
    ...
}

3.3. Send push updates

When users install your pass packge to their iOS and Mac devices - Apple server call your RegisterDeviceAsync. Save pushToken value in database, and when you need to update pass on user device - call IPassKitHelper.SendPushNotificationAsync(pushToken).

Installation

Use NuGet package PassKitHelper

Dependencies

For netcoreapp3.1:

  • Microsoft.Extensions.Http, v3.1.1
  • Newtonsoft.Json, v12.0.2
  • System.Security.Cryptography.Pkcs, v4.6.0

For netstandard2.0:

  • Microsoft.AspNetCore.Http.Abstractions, v2.1.1
  • Microsoft.Extensions.DependencyInjection.Abstractions, v2.1.1
  • Microsoft.Extensions.Logging.Abstractions, v2.1.1
  • Microsoft.Extensions.Http, v2.1.1
  • Newtonsoft.Json, v12.0.2
  • System.Security.Cryptography.Pkcs, v4.6.0

Dvelopment & Testing

You need netcore3.1 to run build and tests;

Tests can be run with dotnet test.

Credits