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.
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
barcodesarray; 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
featuredActionsarray. - 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
.pkpasstemplatefiles; 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
genericfallback 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
primaryFieldorheaderField. - 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
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
PassPackageto access template contents andpackage.passto editpass.jsonfields. - Use
PassCertificateandPassSignerto sign the personalized package for distribution. - Consult the Pass Builder documentation for
buildpasscommand-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
Related Sessions
Read between the strokes with PencilKit
Use PencilKit in iOS 27 and related platforms to recognize handwriting, index and search drawings, convert paths, track strokes, and slice strokes.
Live Activities essentials
Build and tune Live Activities with ActivityKit, WidgetKit, push updates, Dynamic Island landscape layouts, StandBy, small family, and App Intents.