iOS PassKit Wallet 开发(Passbook 开发)_wentianen的博客-程序员宝宝_passkit

技术标签: wallet  passbook  ios  

简介

Wallet 的前身叫 Passbook,对用户来说,,它是一个票据凭证的综合管理中心,你可以把你的登机牌、电影票、优惠券等所有凭证添加到 Wallet,在里面可以查看凭证的余额、使用期限、使用地点等信息,使用时直接通过 Wallet 就能看到你所有的票据和凭证。

对于开发者而言,支持 Wallet ,可以给用户提供更统一便利的管理凭证的方式,便于用户使用。

image.png

Wallet 可以通过 “Passes” 来进行添加,苹果的 Passes 可以包含图片(logo、thumbnail)、条码、二维码、文字、日期等,可以通过 APNs 推送更新信息。

pass 库包含用户的 passes 信息, 用户可以通过 Wallet 查看和管理 passes

一、分类

可以被添加到Wallet的票据凭证共分为以下5类。

  • Boarding pass
    登机牌,如飞机票、火车票

image.png

  • Coupon
    优惠券,如打折券、减免券。一般为一次性使用的券。

image.png

  • Event ticket
    票,如电影票、演出票

image.png

  • Generic
    通用类型。

image.png

  • Store card
    购物卡。可以显示余额等信息。

image.png

你可以根据你的App需要支持的类型来选择票据凭证的类型。

二、创建凭证

在这里创建一个电影票 pass 来举例。

image.png

1. Creating and Populating the Pass Package(创建一个包含Pass所有信息和资源文件的文件夹)

Passes 的创建需要一个 pass.json 文件,这个 pass.json 文件包含 pass 的所有信息,如票据类型,logo、icon资源图片,过期时间、票据描述等信息。将 pass.json 和需要的图片资源文件一起放入一个文件夹,然后从这个文件夹生成 Pass。

创建步骤:

  1. 创建一个 filmTicket.pass 文件夹,使用 .pass 作为文件夹的后缀名,放在 Documents 目录下。
  2. 这里下载示例文件。
  3. 解压缩,将 Event.pass 文件夹中的所有内容拷贝到 filmTicket.pass 文件夹中。
    image.png

2.Setting the Pass Type Identifier and Team ID(设置PassTypeId和Team ID)

每一个 pass 都需要通过一个 PassTypeID 关联到一个开发者账号下。所有的 PassTypeID 都通过开发者账号中心管理。想要创建 pass ,必须到开发者账号下配置你的 PassTypeID

**创建 PassTypeID **

  1. 到你的开发者账号中心,找到Certificates, Identifiers & Profiles,选择 Identifiers
  2. Identifiers 下, 选择 Pass Type IDs
  3. 点击右上角 + 按钮。
  4. 填写描述和 Pass Type ID 并提交。
    image.png

查看 Team ID:

开发者账号下,选择 MemberShip
image.png

**添加 PassTypeIDTeam IDpass.json **

打开 filmTicket.pass 文件夹下的 pass.json , 将 PassTypeIDTeam ID 替换为自己开发者账号下的。

{
...
"passTypeIdentifier" : "your pass type identifier",
"teamIdentifier" : "your Team ID",
...
}

3. Signing and Compressing the Pass(签名并压缩 pass

As part of building your production environment, you will need to set up a system for automatically signing and compressing passes as described in Passes Are Cryptographically Signed and Compressed. For this tutorial, a very simple tool for signing passes is included.

下载签名证书

  1. Certificates, Identifiers & Profiles, 选择 Identifiers
  2. 在 Identifiers 下,选择 Pass Type IDs.
  3. 选择你已经创建好的 pass type identifier, 点击编辑。
  4. 如果已经存在证书文件,直接点击下载即可。如果没有,点击创建,按照提示创建一个(与创建 APNs 推送证书基本一样)。
    image.png

生成 .pkpass 后缀的压缩文件

  1. 找到上面已经下载的文件包,找到 signpass 工程,使用 Xcode 打开并运行。
  2. 选中 Xcode 中 Products 文件夹下的 signpass 文件,右击鼠标,Show in Finder
    image.png
  3. 拷贝 signpass 文件到 filmTicket.pass 文件夹的同级目录(Documents)下。
  4. 执行以下语句:
cd ~/Documents
./signpass -p filmTicket.pass

上面语句会生成 filmTicket.pkpass 文件,也就是我们需要的压缩后的 pass

4. 查看 pass

在 Mac 中直接双击就能打开查看。或者打开你的模拟器,将 filmTicket.pkpass文件拖拽到你的模拟器,就能添加这个 pass 到你模拟器的 Wallet 应用。

5. 修改信息,并重新生成 pass

原有 pass.json 文件内容

{
  "formatVersion" : 1,
  "passTypeIdentifier" : "pass.com.apple.devpubs.example",
  "serialNumber" : "nmyuxofgna",
  "teamIdentifier" : "A93A5CM278",
  "webServiceURL" : "https://example.com/passes/",
  "authenticationToken" : "vxwxd7J8AlNNFPS8k0a0FfUFtq0ewzFdc",
  "relevantDate" : "2011-12-08T13:00-08:00",
  "locations" : [
    {
      "longitude" : -122.3748889,
      "latitude" : 37.6189722
    },
    {
      "longitude" : -122.03118,
      "latitude" : 37.33182
    }
  ],
  "barcode" : {
    "message" : "123456789",
    "format" : "PKBarcodeFormatPDF417",
    "messageEncoding" : "iso-8859-1"
  },
  "organizationName" : "Apple Inc.",
  "description" : "Apple Event Ticket",
  "foregroundColor" : "rgb(255, 255, 255)",
  "backgroundColor" : "rgb(60, 65, 76)",
  "eventTicket" : {
    "primaryFields" : [
      {
        "key" : "event",
        "label" : "EVENT",
        "value" : "The Beat Goes On"
      }
    ],
	"secondaryFields" : [
      {
        "key" : "loc",
        "label" : "LOCATION",
        "value" : "Moscone West"
      }
    ]
  }
}

需要修改 eventTicket 的子级内容

  1. 描述信息
    image.png
  2. 条形码改为二维码,添加描述
// 修改前
"barcode" : {
    "message" : "123456789",
    "format" : "PKBarcodeFormatPDF417",
    "messageEncoding" : "iso-8859-1"
}
// 修改后
"barcode" : {
    "altText" : "订单号:123456",
    "message" : "123456789",
    "format" : "PKBarcodeFormatQR",
    "messageEncoding" : "iso-8859-1"
}
  1. 删除原来生成的 filmTicket.pkpass 文件,重复上面的生成步骤。

6. pass.json 设计说明

  1. 样式和内容规范
  2. 相关 key-value 说明

三、在APP中提供Wallet凭证支持(添加凭证到Wallet)

直接上代码:记得 import PassKit

  1. 将上个步骤生成的 .pkpass 文件拖拽到工程,然后加载本地凭证数据。
@IBAction func showWalletPass(_ sender: Any) {
    guard PKPassLibrary.isPassLibraryAvailable() else {
        showAlert(message: "您的设备不支持Wallet")
        return
    }
    guard let fileUrl = Bundle.main.url(forResource: "Lollipop", withExtension: "pkpass") else {
        showAlert(message: "未找到票据凭证")
        return
    }
    guard let passData = try? Data.init(contentsOf: fileUrl) else {
        showAlert(message: "未找到票据凭证")
        return
    }
    var error: NSError?
    let pass = PKPass(data: passData, error: &error)
    if error != nil {
        showAlert(message: "\(String(describing: error?.localizedDescription))")
        return
    }
    if PKAddPassesViewController.canAddPasses() {
        showPass(pass: pass)
    } else {
        showAlert(message: "您的设备不支持Wallet")
    }
}
  1. 显示凭证信息:
func showPass(pass: PKPass) {
    passToAdd = pass
    let addPassVc = PKAddPassesViewController(pass: pass)
    addPassVc.delegate = self
    self.present(addPassVc, animated: true) {
    }
}
  1. 用户添加、取消后的回调操作:
extension ViewController: PKAddPassesViewControllerDelegate {
    func addPassesViewControllerDidFinish(_ controller: PKAddPassesViewController) {
        controller.dismiss(animated: true) { [weak self] in
            self?.showLookAlert(message: "添加完成")
        }
    }
}
  1. 查看 Wallet 中已添加的凭证:
guard let passURL = self?.passToAdd?.passURL else {
    return
}
if UIApplication.shared.canOpenURL(passURL) {
    UIApplication.shared.open(passURL, options: [:], completionHandler: { _ in
    })
}

四、更新凭证

当你购买了电影票,需要在指定的时间前去观看,超过了这个时间就过期了,那就需要更新凭证。
任何一个凭证凭证都可以通过它的 authentication tokenserial number 更新。

1. 更新流程简介

Updating a pass is a cooperative effort between the user’s device, Apple’s servers, and your servers. At a high level, it consists of the following steps, shown in Figure 6-1:

  1. pass 被设置为支持更新和安装,并且用户设备注册到你的服务器获取更新。
  2. 如果有变更,则触发更新,你的服务器发送推送通知。
  3. 用户收到推送后,从你的服务器查询更新的列表。
  4. 用户从你的服务器获取每个 pass 的最新版本到自己的设备。
    image.png

更新过程中需要使用的信息:
image.png

2. web server 注意事项

  1. 备份私钥和证书,并将其保存在安全的位置。
  2. 避免将私钥存储在Web服务器上,因为Web服务器通常具有较大的攻击面。一个更安全的方法是具有不同的服务器句柄创建和签名传递,并将完成的传递推送到您的Web服务器。
  3. 当与您的Web服务通话时,序列号,传递类型标识符和last-update标签全部包含在URL中。使其过长可能会对对URL长度造成限制的系统造成问题。
  4. 不要更改更新中的身份验证令牌。因为 passes 不能保证被更新,所以仍然可能有具有旧通行证和旧认证令牌的设备。您的服务器必须根据已经有效的每个令牌的列表来检查身份验证令牌。

五、Demo

WalletDemo

六、参考

Pass.json官方说明
Pass创建步骤官方文档

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/andanlan/article/details/78113486

智能推荐

CKAN2.8.4 Database Diagram about package and resource_清萝卜头的博客-程序员宝宝

参考链接:https://boykoc.github.io/ckan/2019/10/21/ckan-283-database-diagram.html

libev中的gcc内嵌函数_馒头2870的博客-程序员宝宝

在学习libev的过程中,遇到了大量的gcc内嵌函数,大多是为了提升性能而使用的,这里做一个汇总和介绍,持续更新1、__builtin_expect:该函数是gcc引入的,为的是让程序员讲最有可能执行的分支告诉编译器,达到性能提升的效果源码://判断GNU版本号,如果不是gcc编译器,则不使用__builtin_expect函数//否则如果主版本号大于major或者主版本号等于major但是次版本号大于minor则返回真 否则返回假//__GNUC__ 、__GNUC_MINOR__ 、__GN

程序员的编程经验分享_Westmoon的博客-程序员宝宝

<br /><br />1. 估算解决问题所需要的时间。不要怕,承认吧!我曾见过一些程序员为了解决一个特殊问题而坐在显示器前面8小时。为自己定一个时间限制吧,1小时、30分钟或甚至15分钟。如果在这期间你不能解决问题,那就去寻求帮助,或到网上找答案,而不是尝试去做“超级堆码员”。<br />2. 编程语言是一种语言,只是一种语言。随着时光推移,只要你理解了一种语言的原理,你会发现各种语言之间的相似之处 。你所选择的语言,你应该觉得“舒服”,并且能够写出有效(而且简洁)的代码。最重要的,让语言去适应项

gorm---最全讲解_最爱松露巧克力的博客-程序员宝宝_gorm

GORM使用指南官方文档目录1.安装gorm2.连接数据库2.1 MySQL2.2 PostgreSQL2.3 Sqlite32.4 不支持的数据库3.模型3.1 模型定义3.2 结构标签3.2.1 提供的结构标签3.2.2 关联的结构标签4 约定4.1 gorm.Model4.2 ID为默认主键4.3 多元化表名4.4 ...

2_5_LeetCode刷题总结(基本算法)动态规划_wangwangmoon_light的博客-程序员宝宝

编程总结每每刷完一道题后,其思想和精妙之处没有地方记录,本篇博客用以记录刷题过程中的遇到的算法和技巧给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。注意你不能在买入股票前卖出股票。输入: [7,1,5,3,6,4]输出: 5解释: 在第 2 天(股票价格 = 1)的时...

Java学习笔记——并发之ThreadLocal_兵兵有李_xjtu的博客-程序员宝宝_threadlocal<long> starttime = new threadlocal<long

ThreadLocal是一种线程本地存储机制,可以为使用相同变量的每个不同线程都创建不同的存储。因此,如果你有5个线程都要使用变量x锁表示的对象,线程本地存储就会产生5个用于x的不同存储块。1. ThreadLocal的用法    ThreadLocal在是泛型类,可以使用set方法设置变量的值,使用get方法获取变量值,示例代码如下:public class ThreadLoca

随便推点

2018-2019-2 20189206 《密码与安全新技术专题》课程总结_weixin_30677073的博客-程序员宝宝

20189206 2018-2019-2 《密码与安全新技术专题》 课程总结课程:《密码与安全新技术专题》班级: 1892姓名: 王子榛学号:20189206上课教师:王志强1.本学期讲座的学习总结第七次课 —— 各组论文学习第一组:在10秒内找到未知的恶意:在Google-Play规模上大规模审查新的威胁背景内容Android设备已经成为市场上的主流产品之一,也带来了一个充...

无法解析插件 org.springframework.boot:spring-boot-maven-plugin:2.4.5 报红解决方法_訴山海的博客-程序员宝宝_无法解析org.springframework

1.更换 org.springframework.boot 版本号(2.5.0是我尝试更换过的)2.查看自己的maven路径是否正确

c语言,Linux,入门_svenn_421的博客-程序员宝宝_c语言linux

LinuxC入门自学(数据类型、运算符、表达式)的10个问题1.#define PI 3.14int a=PI;printf(“%d\n”,a);——a=3Printf(“%d\n”,PI);——PI=13743895351&2 仅仅差一条语句,为什么结果差的这么多?答:define的作用:只做替换不做变换,即PI=3.14,int a=3.14,a=3

360数科股权曝光:周鸿祎持股14.4% 有75.1%投票权_leijianping_ce的博客-程序员宝宝

雷递网 雷建平 5月9日报道360数科日前递交20-F文件,文件显示,截至2022年2月28日,360集团董事长、CEO、360数科董事长周鸿祎持股为14.4%,有75.1%的投票权;360数科副董事长Wei Liu持股为1.2%。截至2022年2月28日,360数科股权结构FountainVest(方源资本)持股为7.5%,有2.2%的投票权;Morgan Stanle...

2 . 11 接口自动化 --- 接口依赖 &用例参数化_雨停江南Lujier的博客-程序员宝宝

一、 接口文档说明 综上: 充值接口 依赖登录接口返回的用户id信息二 、 接口依赖处理 &amp; 用例参数化处理1. 思路: 1) 接口依赖: 登录接口请求成功后,从响应体中提取用户id信息保存下来,充值接口传参时member_id传 登录接口提取的用户id 2) 用例参数化: a. 用例数据动态数据,如: 用户数据,用变量替代 ...

python 文件编码问题_VikingMei的博客-程序员宝宝

1. 在python中读取包含中文字符,然后输出到文件的时候,会出现:UnicodeEncodeError: 'ascii' codec can't encode characters in position 11-12: ordinal not in range(128)在代码中添加如下两行可以搞定,reload(sys)sys.setdefaultencoding("utf-8"