WWDC Quick Look 💓 By SwiftGGTeam
What's New in Wallet

What's New in Wallet

观看原视频

Highlight

iOS 27 为 Wallet Pass 带来 Poster Generic 新样式、四种新条码格式和 Featured Actions API,同时推出 Pass Designer(Mac 可视化设计工具)和 Pass Builder(Swift on Server 签名库),让设计、个性化和分发 Pass 不再需要手写 JSON 和第三方签名脚本。

核心内容

设计 Pass 的痛苦终于结束了

以前做一个 Wallet Pass,流程是这样的:打开文本编辑器,手写 pass.json,每个字段的键名、层级和格式都要查文档确认;图片丢进 bundle 里,但看不到最终效果,只能反复打包、传到手机、刷新 Wallet 来验证;签名环节更麻烦,要自己处理证书、生成 manifest、做 PKCS#7 签名、压缩成 .pkpass,很多团队依赖年久失修的开源脚本。

WWDC26 给了官方解法。Apple 推出了两个工具:Pass Designer 和 Pass Builder。

Pass Designer 是 Mac 上的所见即所得编辑器(06:03)。左侧边栏配置样式、图片、条码和字段,右侧实时渲染出与 iOS 真机一致的 Pass 预览。设计师可以直接拖拽图片、调整颜色、切换样式,导出 .pkpasstemplate 模板文件。

Pass Builder 是 Swift on Server 包(06:26),运行在 Mac 和 Linux 上。它提供类型安全的 Swift API 和 buildpass 命令行工具,负责把模板个性化、签名、打包成 .pkpass。签名所需的 manifest 生成、PKCS#7 签名、压缩等脏活全部自动化。

Poster Generic:让大图成为主角

iOS 27 新增了一种 Pass 样式叫 Poster Generic(00:36)。它适合会员卡、积分卡和储值卡这类需要视觉冲击力的场景。Pass 正面由背景图、主 Logo、header 字段、primary 字段、单个 footer 字段和条码组成。背景图占据主要视觉区域,字段信息叠加在图片上方。

使用方式是在 pass.json 顶层声明 posterGeneric 键(01:41):

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

需要注意两个限制:

  • Poster Generic 只支持一个 footer 字段。如果写了多个,只有第一个会显示(01:58)。
  • 它需要 iOS 27。为了兼容旧设备,建议同时保留 generic 键(02:12):
{
  "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" }
    ]
  }
}

这样 iOS 26 及更早版本会回落到 generic 样式,iOS 27 则展示 Poster Generic。

四种新条码,但要记得 fallback

iOS 27 新增了对 EAN-13、Code 39、Codabar 和 ITF 四种条码格式的支持(02:33)。在 pass.jsonbarcodes 数组中指定格式即可:

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

旧版本 iOS 不支持这些新格式。如果只提供一种新条码,iOS 26 及更早设备上 Pass 将不显示任何条码03:28)。

推荐的写法是按优先级提供多个条码,让系统选择设备能渲染的格式(03:37):

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

如果确实只能支持一种条码类型,Apple 建议把凭证 ID 放在 headerField 或 primaryField 中,方便前台人员手动输入(03:58)。

iOS 18 第二代活动票券引入了语义化 URL,可以在 Pass 下方显示操作按钮(比如查看活动日程)。iOS 27 把这个能力开放给了所有 Pass 样式04:42)。

pass.json 顶层定义 featuredActions 数组:

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

每个 action 包含唯一 ID、类型和值(通常是 URL)。Wallet 会在 Pass 下方渲染一个带彩色图标的按钮,并显示本地化的行动号召文案(05:15)。

每个 Pass 最多支持两个 featured actions。建议按优先级排序,只放最有意义的操作(05:24)。

详细内容

用 Pass Designer 设计模板

Pass Designer 的工作流很直接(06:58):

  1. 选择 Pass 样式(如 Poster Generic)
  2. 拖拽图片到 Images 区域设置背景图和主 Logo
  3. 在侧边栏添加 header、primary、footer 字段
  4. 配置条码类型和消息
  5. 调整颜色(Label Color、背景色等)
  6. 保存为 .pkpasstemplate 文件

一个实用技巧:Poster Generic 的第一个 primary field 如果省略 label,字段值会以粗体大标题形式呈现(08:26)。这适合放会员姓名、积分余额等核心信息。

用 Pass Builder 在服务器端批量生成

Pass Builder 是 Swift Package,通过 Package.swift 引入依赖(10:56):

// 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")
            ]
        ),
    ]
)

生成 Pass 的代码(11:05):

import PassBuilder

func createPass(for doggo: MemberModel) async throws -> URL {
    // 加载 Pass Designer 导出的模板
    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)
    ]

    // 添加 Featured Action
    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
    )

    // 签名并输出 .pkpass
    let destinationURL = URL(string: "/www/passes/" + doggo.id)
    try signer.signPass(package, writingTo: destinationURL)

    return destinationURL
}

关键点:

  • PassPackage 提供类型安全的 API 访问 pass bundle,包括 pass.fieldsbackgroundbarcodesfeaturedActions 等属性
  • PassImage 从 URL 加载图片资源
  • Pass.Barcode 支持 .pdf417.qr 等格式枚举
  • PassCertificate 加载 .p12 签名证书和 Apple WWDR 中间证书
  • PassSigner 封装了 manifest 生成、PKCS#7 签名和压缩打包的全部逻辑
  • signPass(package, writingTo:) 一步输出可直接分发的 .pkpass 文件

非 Swift 后端也能用

Pass Builder 不限定 Swift 后端。Apple 提供了两条路:

  1. swift-java 绑定:通过 swift-java 项目生成 Java 原生绑定,从 JVM 直接调用 Pass Builder API(13:54
  2. Protobuf + 命令行:Apple 开放了 Pass Package 格式的 protobuf 定义,可以用任何语言生成类型安全模型,然后调用 buildpass 命令行工具完成个性化和签名(14:03

核心启发

1. 会员/积分卡 App 的视觉升级

把用户的头像或品牌主视觉设为 Poster Generic 背景图,第一行 primary field 省略 label 显示用户名或积分余额,footer 放会员等级。Featured Action 挂「查看积分商城」和「兑换优惠券」两个按钮。用户打开 Wallet 一眼就能看到核心信息,点击直达操作。

入口:在 Pass Designer 中创建 Poster Generic 模板,后端用 PassPackage 注入用户数据。

2. 线下门店的扫码入场系统

健身房、瑜伽馆、共享办公空间可以用 Pass Builder 批量生成带 PDF417 条码的日卡/月卡。条码内容编码用户 ID 和有效期,门店闸机扫码即开。 fallback 条码用 QR Code 兼容旧设备。

入口:Pass.Barcode(message: userId, format: .pdf417) + barcodes 数组兜底 QR Code。

3. 活动票务的语义化操作

演唱会、展览票务在 Pass 下方挂两个 Featured Actions:「查看座位图」和「场馆导航」。用户到了现场不用翻找 App,直接从 Wallet 点击跳转。

入口:featuredActions 数组配置 typeurl,Wallet 自动渲染图标和文案。

4. 企业内部的访客通行证系统

公司前台用 Pass Designer 设计访客证模板,HR 系统调用 Pass Builder API 为每位访客生成带照片、访问区域和有效期的 Pass,邮件发送 .pkpass 附件。访客添加到 Wallet 后,门禁扫码即可通行。

入口:PassImage(url: photoURL) 设置访客照片 + Pass.Barcode 编码访客 ID。

5. 从第三方签名脚本迁移到官方工具链

还在用 Python/Node.js 开源库生成 Pass 的团队,可以把签名逻辑替换为 buildpass CLI 或 Pass Builder。这能彻底解决 OpenSSL 版本冲突、证书格式不兼容等运维问题。

入口:下载 Pass Builder 源码,用 PassSigner 替换现有签名逻辑,protobuf 定义兼容多语言后端。

关联 Session

评论

GitHub Issues · utterances