PKPass 是Apple定义的一套针对商家消费券、优惠券、火车机票等票据格式类文件。包含:图标icon、缩略图thumbnail和logo外最重要的就是pass.json、manifest.json和signature等文件的一个压缩包
1)、服务器端制作是比较通用的做法
这里有一个Java写的开源库:
Java版本制作PKPass的web service
2)、本地制作,按照下面的步骤:
1、去苹果开发者网站
申请Pass Type id,并且生成对应的证书(申请之前需要到钥匙串:从证书颁发机构请求证书)
2、制作pass.json
a、准备icon、logo和strip三类图片
b、 配置pass.json,这里还是强调一下passTypeIdentifier和teamIdentifier,前者就是上面在开发者中心创建的Pass Type ID(”pass.com.taokatao.mywallet“),后者是对应的团队标识,申请苹果开发者账号时会分配一个唯一的团队标识(可以在苹果开发者中心–查看账户信息中查看”Team ID“)。,其他信息根据实际情况配置。
{
"formatVersion": 1,
"passTypeIdentifier": "pass.com.taokatao.mywallet",
"serialNumber": "54afe978584e3",
"teamIdentifier": "MV9CCWC8NT",
"authenticationToken": "bc83dde3304d766d5b1aea631827f84c",
"barcode": {
"message": "userName CangyuZheng",
"altText": "会员详情见背面",
"format": "PKBarcodeFormatQR",
"messageEncoding": "iso-8859-1"
},
"locations": [
{
"longitude": -122.3748889,
"latitude": 37.6189722
},
{
"longitude": -122.03118,
"latitude": 37.33182
}
],
"organizationName": "CardMee",
"logoText": "CardMee",
"description": "",
"foregroundColor": "rgb(2,2,4)",
"backgroundColor": "rgb(244,244,254)",
"storeCard": {
"headerFields": [
{
"key": "date",
"label": "余额",
"value": "¥888.66"
}
],
"secondaryFields": [
{
"key": "more",
"label": "VIP会员",
"value": "Cangyu Zheng"
}
],
"backFields": [
{
"key": "records",
"label": "消费记录(最近10次)",
"value": " 9/23 ¥107.00 无糖冰美式\n 9/21 ¥58.00 黑魔卡\n 8/25 ¥44.00 魔卡\n 8/23 ¥107.00 无糖冰美式\n 8/18 ¥107.00 无糖冰美式\n 7/29 ¥58.00 黑魔卡\n 7/26 ¥44.00 魔卡\n 7/13 ¥58.00 黑魔卡\n 7/11 ¥44.00 魔卡\n 6/20 ¥44.00 魔卡\n"
},
{
"key": "phone",
"label": "联系方式",
"value": "4008-888-88"
},
{
"key": "terms",
"label": "会员规则",
"value": "(1)本电子票涉及多个环节,均为人工操作,用户下单后,1-2个工作日内下发,电子票并不一定能立即收到,建议千品用户提前1天购买,如急需使用,请谨慎下单; \n(2)此劵为电子劵,属特殊产品,一经购买不支持退款(敬请谅解); \n(3)特别注意:下单时请将您需要接收电子票的手机号码,填入收件人信息,如号码填写错误,损失自负;购买成功后,商家于周一至周五每天中午11点和下午17点发2维码/短信到您手机(周六至周日当天晚上发1次),请用户提前购买,凭此信息前往影院前台兑换即可; \n(4)订购成功后,(您在购买下单后的当天,给您发送电子券,系统会自动识别;如果您的手机能接收二维码,那收到的就是彩信,不能接收二维码的话,系统将会自动转成短信发送给您),短信为16位数,如:1028**********; 每个手机号码只可购买6张,如需购买6张以上的请在订单附言填写不同的手机号码,并注明张数(例如团购10张,1350755****号码4张,1860755****号码6张);\n(5)电子票有效期至2016年2月30日,不与其他优惠券同时使用"
},
{
"key": "support",
"label": "技术支持",
"value": "http://s.cardmee.net/camee/"
}
]
},
"labelColor": "rgb(87,88,93)"
}
3、创建manifest.json文件,可以通过”openssl sha1 [文件路径]“分别计算出所有文件的哈希值:
4、生成signature文件:
a.通过前面导入的Pass Type证书(Pass Type ID:pass.com.taokatao.mywallet)导出个人信息交换(.p12)文件并指定密码(假设密码为123123),保存成”mywallet.p12“(注意是导出证书而不是导出证书下的专用秘钥)。
b.在钥匙串中找到”Apple Worldwide Developer Relations Certification Authority“证书导出增强保密邮件(.pem),保存成”AWDRCA.pem“。
c.将.p12证书转化为.pem证书mywallet.pem(需要输入导出时设置的密码123123),输入如下命令:
openssl pkcs12 -in mywallet.p12 -clcerts -nokeys -out mywallet.pem -passin pass:123123
d.从.p12导出秘钥文件mywalletkey.pem(这里设置密码为123123)
openssl pkcs12 -in mywallet.p12 -nocerts -out mywalletkey.pem -passin pass:123123 -passout pass:123123
e.根据AWDRCA.pem、mywallet.pem、mywalletkey.pem、manifest.json生成signature文件(按照提示输入mywalletkey.pem导出时设置的密码123123):
openssl smime -binary -sign -certfile AWDRCA.pem -signer mywallet.pem -inkey mywalletkey.pem -in manifest.json -out signature -outform DER
5.将icon.png、icon@2x.png、logo.png、logo@2x.png、strip.png、strip@2x.png 、pass.json、manifest.json、signature压缩成pass包(这里命名为”mywallet.pkpass“)。
zip -r mywallet.pkpass manifest.json pass.json signature logo.png logo@2x.png icon.png icon@2x.png strip.png strip@2x.png
1、Xcode新建一个工程,Bundle Identifier中命名一个App ID
2、选择目标Target,点击“Capabilities”标签,打开Wallet开关。此时需要勾选:Allow all team pass types.但是你看到的下面:“Add the wallet feature to your App ID”前面是红色的。不要紧这是因为你还没有创建App ID,看下面
3、进入Apple 开发者网站,新建一个App ID,跟第一步的App ID一致,再来看看这个红色提示就消失了,正常的对勾形式出现
4、进入目标Target,General标签,让Xcode自动为我们管理证书
5、把上面制作的PKPass文件拖到项目中
6、编码读取并显示。so easy!
#import "ViewController.h"
#import <PassKit/PassKit.h>
@interface ViewController ()<PKAddPassesViewControllerDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
PKAddPassButton *pkAddBtn = [[PKAddPassButton alloc] initWithAddPassButtonStyle:PKAddPassButtonStyleBlack];
pkAddBtn.titleLabel.font = [UIFont systemFontOfSize:12];
pkAddBtn.frame = CGRectMake(100, 100, 220, 40);
[self.view addSubview:pkAddBtn];
[pkAddBtn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
}
- (void)btnClick:(PKAddPassButton *)button {
NSString *passPath=[[NSBundle mainBundle] pathForResource:@"mywallet" ofType:@"pkpass"];
NSData *passData = [[NSData alloc] initWithContentsOfFile:passPath];
NSError *error = nil;
PKPass *pass = [[PKPass alloc] initWithData:passData error:&error];
if (error) {
NSLog(@"创建Pass过程中发生错误,错误信息:%@",error.localizedDescription);
};
PKAddPassesViewController *vc = [[PKAddPassesViewController alloc] initWithPass:pass];
vc.delegate = self;
[self presentViewController:vc animated:true completion:nil];
}
-(void)addPassesViewControllerDidFinish:(PKAddPassesViewController *)controller{
NSLog(@"add pass finished.");
[self dismissViewControllerAnimated:true completion:nil];
}