WWDC.ai

What's new in Wallet

Learn how iOS 27 Wallet passes add Poster Generic, new barcode formats, featured actions, and Pass Designer/Pass Builder workflows.

Watch on Apple Developer

TL;DR

  • iOS 27 adds the Poster Generic pass style for artwork-forward membership, loyalty, and store cards; include a Generic style fallback for iOS 26 and earlier.
  • Wallet passes gain EAN-13, Code 39, Codabar, and ITF barcode formats using the existing barcodes array; provide fallback barcodes or a prominent manual credential ID for older OS versions.
  • Featured actions let any pass style expose up to two prioritized actions below the pass face using a top-level featuredActions array.
  • New tooling includes Pass Designer for WYSIWYG pass templates and Pass Builder for server-side personalization, signing, validation, and command-line generation.

iOS 27 pass updates

iOS 27 expands Wallet passes with a new visual pass style, more barcode choices, a flexible pass actions API, and new tooling for template-driven pass generation. The changes target common pass use cases such as membership cards, loyalty programs, store cards, and operational workflows where passes need to be customized and distributed at scale.

  • Poster Generic is a new pass style for bold artwork-driven pass faces.
  • New barcode formats are EAN-13, Code 39, Codabar, and Interleaved 2 of 5 (ITF).
  • Featured actions expose relevant actions below the pass face for all pass styles.
  • Pass Designer creates .pkpasstemplate files; Pass Builder personalizes and signs them on Mac or Linux.

Poster Generic pass style

Poster Generic is adopted by adding the posterGeneric top-level style key to pass.json. Its pass face can include a background image, primary logo, header fields, primary fields, a single footer field, and an optional barcode. If more than one footer field is supplied, only the first is displayed.

Poster Generic requires iOS 27 or later. To keep passes addable on iOS 26 and earlier, include the existing generic style key alongside posterGeneric, with relevant fields for each style.

  • Good fit: membership cards, loyalty programs, store cards, and passes where colorful artwork should dominate.
  • Compatibility guidance: include a generic fallback for customers on iOS 26 and earlier.
  • Layout constraint: only one footer field is shown on the pass face.

Adopt Poster Generic with Generic fallback

Use posterGeneric for iOS 27 and provide generic fields for earlier iOS versions.

{
  "posterGeneric": {
    "headerFields": [
      { "key": "memberID", "label": "Guest No.", "value": "102035" }
    ],
    "footerFields": [
      { "key": "membershipType", "value": "Family Pass" }
    ]
  },
  "generic": {
    "headerFields": [
      { "key": "memberID", "label": "Guest No.", "value": "102035" }
    ],
    "footerFields": [
      { "key": "membershipType", "value": "Family Pass" }
    ]
  }
}

New barcode formats and fallback strategy

Wallet passes in iOS 27 support four additional barcode formats through the existing Barcode object and barcodes array in pass.json: EAN-13, Code 39, Codabar, and ITF. For example, Codabar is specified with PKBarcodeFormatCodabar.

Older iOS releases do not support these new formats. If a pass only provides a new iOS 27 barcode type, no barcode is rendered on iOS 26 and earlier. The recommended approach is to list barcodes in priority order, starting with the preferred new format and falling back to a supported format such as QR.

  • Provide multiple barcodes when possible, ordered by preference.
  • If multiple formats are not possible, show the credential ID prominently in a primaryField or headerField.
  • Train staff for manual-entry workflows so an unscannable pass does not block the customer.

Codabar with QR fallback

Lead with the preferred new barcode type and include a supported fallback for iOS 26 and earlier.

{
  "barcodes": [
    {
      "format": "PKBarcodeFormatCodabar",
      "message": "123456789",
      "messageEncoding": "iso-8859-1"
    },
    {
      "format": "PKBarcodeFormatQR",
      "message": "123456789",
      "messageEncoding": "iso-8859-1"
    }
  ]
}

Featured actions are a new iOS 27 API for showing relevant actions below the pass face across all pass styles. Add a top-level featuredActions key to pass.json; each action has a unique identifier, an action type, and a value such as a URL. Wallet renders the action with an appropriate icon and localized call to action.

  • Each pass can contain up to two featured actions.
  • Actions should be supplied in priority order.
  • Use only the most meaningful and relevant actions for the customer.
  • Supported action types and expected values are documented in the Wallet Passes documentation.

Add a membership benefits action

Defines a featured action that links the user to membership offers or benefits.

{
  "featuredActions": [
    {
      "identifier": "my-offer-id",
      "type": "membershipBenefits",
      "url": "www.example.com/offers"
    }
  ]
}

Pass Designer workflow

Pass Designer is a Mac WYSIWYG editor that provides a true-to-iOS rendering while designing a pass. It can configure identity and signing settings, pass style, images, barcodes, fields, and semantics when supported by the selected pass style.

The demonstrated workflow creates a Poster Generic dog daycare membership pass: choose the Poster Generic style, add a dog portrait background, configure header and primary fields, use a PDF417 barcode for membership check-in, add a primary logo, set label colors, and add a footer. Pass Designer saves the result as a .pkpasstemplate file for later personalization.

  • Use Pass Designer to experiment with Poster Generic before changing production pass generation.
  • Use placeholder values in template fields that will later be replaced server-side.
  • A missing label on the first Poster Generic primary field produces a bold title-like value presentation.

Pass Builder for server-side personalization and signing

Pass Builder is a Swift on Server package for Mac and Linux. It takes templates created in Pass Designer and provides APIs to personalize, validate, sign, and build distributable passes. It also includes the buildpass command-line executable.

On the server, load a .pkpasstemplate with PassPackage, set field values, set images, configure barcodes and featured actions, then sign the pass with a pass signing certificate and the WWDR intermediate certificate. Pass Builder handles generating the manifest, creating the detached signature, packaging the bundle, and writing the .pkpass output.

Pass Builder can also be used from other programming languages. The session calls out native Java bindings generated by swift-java, protobuf definitions for the Pass Package format, and the buildpass command-line executable for personalization and signing.

  • Add Pass Builder as a Swift package dependency to the server package manifest and target.
  • Use PassPackage to access template contents and package.pass to edit pass.json fields.
  • Use PassCertificate and PassSigner to sign the personalized package for distribution.
  • Consult the Pass Builder documentation for buildpass command-line usage.

Add Pass Builder to a Swift package

Registers Pass Builder as a dependency for a Swift server target.

// Package.swift
import PackageDescription

let package = Package(
  name: "MyServer",
  products: [
    .library(name: "MyServer", targets: ["MyServer"])
  ],
  dependencies: [
    .package(path: "./path/to/PassBuilder")
  ],
  targets: [
    .target(
      name: "MyServer",
      dependencies: [
        .product(name: "PassBuilder", package: "PassBuilder")
      ]
    )
  ]
)

Personalize and sign a pass template

Loads a template, customizes fields, image, barcode, and featured action, then signs the pass for distribution.

import PassBuilder

func createPass(for doggo: MemberModel) async throws -> URL {
  var package = PassPackage(url: "template.pkpasstemplate")

  package.pass.fields.setValue(doggo.name, forKey: "DOG_NAME")
  package.pass.fields.setValue(doggo.favoriteToy, forKey: "LOVES")
  package.pass.fields.setValue(doggo.id, forKey: "MEMBER_ID")

  package.background = PassImage(url: doggo.photoURL)
  package.pass.barcodes = [
    Pass.Barcode(message: doggo.id, format: .pdf417)
  ]
  package.featuredActions = [
    Pass.Action(id: "action-1", type: "viewMembership", url: doggo.membershipURL)
  ]

  let passCertificate = try PassCertificate(url: "pass.p12", password: "s3cr3t")
  let wwdrCertificate = try PassCertificate(url: "wwdr.cer")
  let signer = PassSigner(
    passCertificate: passCertificate,
    wwdrCertifiate: wwdrCertificate
  )

  let destinationURL = URL(string: "/www/passes/" + doggo.id)!
  try signer.signPass(package, writingTo: destinationURL)
  return destinationURL
}

Resources

Unofficial, not associated with Apple. BySuperwall

On this page

Ask AI