iOS开发——高级技术&PassBook服务

PassBook服务

Passbook是苹果推出的一个管理登机牌、会员卡、电影票、优惠券等信息的 工具。Passbook就像一个卡包,用于存放你的购物卡、积分卡、电影票、礼品卡等,而这些票据就是一个“Pass”。和物理票据不同的是你可以动态更 新Pass的信息,提醒用户优惠券即将过期;甚至如果你的Pass中包含地理位置信息的话当你到达某个商店还可以动态提示用户最近商店有何种优惠活动;当 用户将一张团购券添加到Passbook之后,用户到了商店之后Passbook可以自动弹出团购券,店员扫描之后进行消费、积分等等都是 Passbook的应用场景。Passbook可以管理多类票据,苹果将其划分为五类:

  1. 登机牌(Boarding pass)
  2. 优惠券(Coupon)
  3. 活动票据、入场券(Event ticket)
  4. 购物卡、积分卡(Store Cards)
  5. 普通票据(自定义票据)(Generic pass)

苹果的划分一方面出于不同票据功能及展示信息不同,另一方面也是为了统一票据的设计,下面是苹果官方关于五种票据的布局设计布局:

既然一个票据就是一个Pass,那么什么是Pass呢?在iOS中一个Pass其实就是一个.pkpass文件,事实上它是一个Zip压缩包,只是这个压缩包要按照一定的目录结构来设计,下面是一个Pass包的目录结构(注意不同的票据类型会适当删减):

Pass Package

├── icon.png

├── [email protected]

├── logo.png

├── [email protected]

├── thumbnail.png

├── [email protected]

├── background.png

├── [email protected]

├── strip.png

├── [email protected]

├── manifest.json

├── fr.lproj

│ └── pass.strings

├── de.lproj

│ └── pass.strings

├── pass.json

└── signature

也就是说在Passbook应用中显示的内容其实就是一个按照上面文件列表来组织的一个压缩包。在.pkpass文件中除了图标icon、缩略图thumbnail和logo外最重要的就是pass.json、manifest.json和signature。

  • 1.pass.json

这个文件描述了Pass的布局、颜色设置、文本描述信息等,也就是说具体Pass包如何展示其实就是通过这个JSON文件来配置的,关于pass.json的具体配置项在此不再一一介绍,大家可以查看苹果官方帮助文档“Pass Design and Creation”。这里主要说一下其中关键的几个配置项:

passTypeIdentifier:pass唯一标识,这个值类似于App ID,需要从开发者中心创建,并且这个标识必须以“pass”开头(例如下面的示例中取名为“pass.com.cmjstudio.mypassbook”)。

teamIdentifier:团队标识,申请苹果开发者账号时会分配一个唯一的团队标识(可以在苹果开发者中心--查看账户信息中查看”Team ID“)。

barcode:二维码信息配置,主要指定二维码内容、类型、编码格式。

locations:地理位置信息,可以配置相关位置的文本信息。

  • 2.manifest.json

manifest.json 从名称可以看出这个文件主要用来描述当前Pass包中的文件目录组织结构。这个文件记录了除“manifest.json”、“signature”外的 文件和对应的sha1哈希值(注意:哈希值可以通过”openssl sha1 [ 文件路径]“命令获得)。

  • 3.signature

signature是一个签名文件。虽然manifest.json存储了哈希值,但是大家都知道hash算法是公开的,如何保证一个pass包是合法的,未经修改的呢?那就是使用一个签名文件来验证。

了 解了以上内容后基本上对于如何定义一个pass包有了简单的概念。有了pass包之后对于添加pass到passbook应用是比较简单的。但事实上通常 大家看到的passbook应用中添加的pass包并不是手动组织的,而是通过程序来完成pass包制作的。举例来说:如果你在美团上购买一张电影票之 后,会告诉你一个优惠码,这个优惠码会显示到pass中。由于这个优惠码是动态生成的,所以直接手动制作出一个pass包是不现实的。通常情况下pass 包的生成都是通过后台服务器动态生成,然后返回给iOS客户端来读取和添加的,手动制作pass包的情况是比较少的,除非你的票据信息是一成不变的。当然 为了演示Passbook应用,这里还是会以手动方式演示一个pass包的生成过程,了解了这个过程之后相信在服务器端通过一些后台程序生成一个pass 包也不在话下(下面的生成过程均可通过服务器端编程来实现)。

同其他Apple服务开发类似,做Passbook开发同样需要一些准备工作:

在 苹果开发者中心新建Pass Type ID(例如这里新建一个“pass.com.cmjstudio.mypassbook”),并且基于这个Pass Type ID创建一个Passbook证书(在mac上找到钥匙串,选择”从证书颁发机构请求证书“,生成一个证书请求文件;将此文件上传到对应的Pass Type ID下生成证书文件)如下图:Pa

下载证书后,将此证书导入Mac中(此处配置的Pass Type ID对应pass.json中的”passTypeIdentitifier“,此证书用于生成签名文件signature。)。

在 Xcode中-Targets-Capabilities启用Pasbook服务,这里需要注意的是”Allow all team pass types“选项,如果勾选了这一项,那么pass.json中的passTypeIdentifier和teamIdentifier就可以是任何团队 创建的任何Pass项目了,这里使用前面创建的项目,所以选择”Allow subset of pass types“。

有了上面的准备工作,下面看一下如何制作一个Pass:

  • 根据所选择的Passbook类型准备图片素材,由于这里以一个Store Card举例,所以需要准备icon、logo和strip三类图片。
  • 配 置pass.json,这里还是强调一下passTypeIdentifier和teamIdentifier,前者就是上面在开发者中心创建的Pass Type ID(”pass.com.cmjstudio.mypassbook“),后者是对应的团队标识,其他信息根据实际情况配置。
 1 {
 2     "formatVersion":1,
 3     "passTypeIdentifier":"pass.com.cmjstudio.mypassbook",
 4     "serialNumber":"54afe978584e3",
 5     "teamIdentifier":"JB74M3J7RY",
 6     "authenticationToken":"bc83dde3304d766d5b1aea631827f84c",
 7     "barcode":{"message":"userName KenshinCui","altText":"会员详情见背面","format":"PKBarcodeFormatQR","messageEncoding":"iso-8859-1"},
 8     "locations":[
 9                  {"longitude":-122.3748889,"latitude":37.6189722},{"longitude":-122.03118,"latitude":37.33182}],
10     "organizationName":"CMJ Coffee",
11     "logoText":"CMJ Coffee",
12     "description":"",
13     "foregroundColor":"rgb(2,2,4)",
14     "backgroundColor":"rgb(244,244,254)",
15     "storeCard":{
16         "headerFields":[{"key":"date","label":"余额","value":"¥8888.50"}],
17         "secondaryFields":[{"key":"more","label":"VIP会员","value":"Kenshin Cui"}],
18         "backFields":[
19                       {"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"},
20                       {"key":"phone","label":"联系方式","value":"4008-888-88"},
21                       {"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日,不与其他优惠券同时使用"},
22                       {"key":"support","label":"技术支持","value":"http://www.cmjstudio.com\n\n                                            \n                                            \n                                          "}]
23     },
24     "labelColor":"rgb(87,88,93)"
25 }

根据pass所需文件创建manifest.json文件,可以通过”openssl sha1 [文件路径]“分别计算出所有文件的哈希值:

1 {
2     "pass.json":"3292f96c4676aefe7122abb47f86be0d95a6faaf",
3     "[email protected]":"83438c13dfd7c4a5819a12f6df6dc74b71060289",
4     "icon.png":"83438c13dfd7c4a5819a12f6df6dc74b71060289",
5     "[email protected]":"83438c13dfd7c4a5819a12f6df6dc74b71060289",
6     "logo.png":"83438c13dfd7c4a5819a12f6df6dc74b71060289",
7     "[email protected]":"885ff9639c90147a239a7a77e7adc870d5e047e2",
8     "strip.png":"885ff9639c90147a239a7a77e7adc870d5e047e2"
9 }

接下来下来准备生成signature文件:

a. 通过前面导入的Pass Type证书(Pass Type ID:pass.com.cmjstudio.mypassbook)导出个人信息交换(.p12)文件并指定密码(假设密码为456789),保存 成”mypassbook.p12“(注意是导出证书而不是导出证书下的专用秘钥)。

b.在钥匙串中找到”Apple Worldwide Developer Relations Certification Authority“证书导出增强保密邮件(.pem),保存成”AWDRCA.pem“。

c.将.p12证书转化为.pem证书mypassbook.pem(需要输入导出时设置的密码456789),输入如下命令:

openssl pkcs12 -in mypassbook.p12 -clcerts -nokeys -out mypassbook.pem -passin pass:456789

d.从.p12导出秘钥文件mypassbookkey.pem(这里设置密码为123456):

openssl pkcs12 -in mypassbook.p12 -nocerts -out mypassbookkey.pem -passin pass:456789 -passout pass:123456

e.根据AWDRCA.pem、mypassbook.pem、mypassbookkey.pem、manifest.json生成signature文件(按照提示输入mypassbookkey.pem导出时设置的密码123456):

openssl smime -binary -sign -certfile AWDRCA.pem -signer mypassbook.pem -inkey mypassbookkey.pem -in manifest.json -out signature -outform DER

将 icon.png、[email protected]、logo.png、[email protected]、strip.png、[email protected] 、pass.json、manifest.json、signature压缩成pass包(这里命名为”mypassbook.pkpass“)。

zip -r mypassbook.pkpass manifest.json pass.json signature logo.png [email protected] icon.png [email protected] strip.png [email protected]

到这里一个pass制作完成了,此处可以在mac中打开预览:

到 这里一个Pass就只做完成了,下面就看一下在iOS中如何添加这个Pass到Passbook,这里直接将上面制作完成的Pass放到Bundle中完 成添加。当然这些都是一步步手动完成的,前面也说了实际开发中这个Pass是服务器端来动态生成的,在添加时会从服务器端下载,这个过程在示例中就不再演 示。iOS中提供了PassKit.framework框架来进行Passbook开发,下面的代码演示了添加Pass到Passbook应用的过程:

 1 //
 2 //  ViewController.m
 3 //  Passbook
 4 //
 5 //  Created by Kenshin Cui on 14/4/5.
 6 //  Copyright (c) 2015年 cmjstudio. All rights reserved.
 7 //
 8 #import "ViewController.h"
 9 #import
10 @interface ViewController ()
11 @property (strong,nonatomic) PKPass *pass;//票据
12 @property (strong,nonatomic) PKAddPassesViewController *addPassesController;//票据添加控制器
13 @end
14 @implementation ViewController
15 - (void)viewDidLoad {
16     [super viewDidLoad];
17 }
18 #pragma mark - UI事件
19 - (IBAction)addPassClick:(UIBarButtonItem *)sender {
20     //确保pass合法,否则无法添加
21     [self addPass];
22 }
23 #pragma mark - 属性
24 /**
25  *  创建Pass对象
26  *
27  *  @return Pass对象
28  */
29 -(PKPass *)pass{
30     if (!_pass) {
31         NSString *passPath=[[NSBundle mainBundle] pathForResource:@"mypassbook.pkpass" ofType:nil];
32         NSData *passData=[NSData dataWithContentsOfFile:passPath];
33         NSError *error=nil;
34         _pass=[[PKPass alloc]initWithData:passData error:&error];
35         if (error) {
36             NSLog(@"创建Pass过程中发生错误,错误信息:%@",error.localizedDescription);
37             return nil;
38         }
39     }
40     return _pass;
41 }
42 /**
43  *  创建添加Pass的控制器
44  *
45  *  @return
46  */
47 -(PKAddPassesViewController *)addPassesController{
48     if (!_addPassesController) {
49         _addPassesController=[[PKAddPassesViewController alloc]initWithPass:self.pass];
50         _addPassesController.delegate=self;//设置代理
51     }
52     return _addPassesController;
53 }
54 #pragma mark - 私有方法
55 -(void)addPass{
56     if (![PKAddPassesViewController canAddPasses]) {
57         NSLog(@"无法添加Pass.");
58         return;
59     }
60     [self presentViewController:self.addPassesController animated:YES completion:nil];
61 }
62 #pragma mark - PKAddPassesViewController代理方法
63 -(void)addPassesViewControllerDidFinish:(PKAddPassesViewController *)controller{
64     NSLog(@"添加成功.");
65     [self.addPassesController dismissViewControllerAnimated:YES completion:nil];
66     //添加成功后转到Passbook应用并展示添加的Pass
67     NSLog(@"%@",self.pass.passURL);
68     [[UIApplication sharedApplication] openURL:self.pass.passURL];
69 }
70 @end

运行效果:

注意:如果大家对于Pass不是太熟悉,刚开始可以使用一些制作工具来完成Pass制作,例如:PassSource、国内的PassQuan等都支持在线制作Pass包。

时间: 2024-10-06 20:01:41

iOS开发——高级技术&PassBook服务的相关文章

iOS开发——高级技术&iCloud服务

iCloud服务 iCloud 是苹果提供的云端服务,用户可以将通讯录.备忘录.邮件.照片.音乐.视频等备份到云服务器并在各个苹果设备间直接进行共享而无需关心数据同步问题,甚至 即使你的设备丢失后在一台新的设备上也可以通过Apple ID登录同步.当然这些内容都是iOS内置的功能,那么对于开放者如何利用iCloud呢?苹果已经将云端存储功能开放给开发者,利用iCloud开发者 可以存储两类数据:用户文档和应用数据.应用配置项.前者主要用于一些用户文档.文件的存储,后者更类似于日常开放中的偏好设置

iOS开发——高级技术&蓝牙服务

蓝牙服务 蓝牙 随着蓝牙低功耗技术BLE(Bluetooth Low Energy)的发展,蓝牙技术正在一步步成熟,如今的大部分移动设备都配备有蓝牙4.0,相比之前的蓝牙技术耗电量大大降低.从iOS的发展史也不难看 出苹果目前对蓝牙技术也是越来越关注,例如苹果于2013年9月发布的iOS7就配备了iBeacon技术,这项技术完全基于蓝牙传输.但是众所周知苹果 的设备对于权限要求也是比较高的,因此在iOS中并不能像Android一样随意使用蓝牙进行文件传输(除非你已经越狱).在iOS中进行蓝牙传输

iOS开发——高级技术&通讯录服务

通讯录服务 AddressBook iOS中带有一 个Contacts应用程序来管理联系人,但是有些时候我们希望自己的应用能够访问或者修改这些信息,这个时候就要用到 AddressBook.framework框架.iOS中的通讯录是存储在数据库中的,由于iOS的权限设计,开发人员是不允许直接访问通讯录数据库 的,必须依靠AddressBook提供的标准API来实现通讯录操作.通过AddressBook.framework开发者可以从底层去操作 AddressBook.framework的所有信息

iOS开发——高级技术&GameCenter服务

GameCenter服务 Game Center是由苹果发布的在线多人游戏社交网络,通过它游戏玩家可以邀请好友进行多人游戏,它也会记录玩家的成绩并在排行榜中展示,同时玩家每经过一定 的阶段会获得不同的成就.这里就简单介绍一下如何在自己的应用中集成Game Center服务来让用户获得积分.成就以及查看游戏排行和已获得成就. 由 于Game Center是苹果推出的一项重要服务,苹果官方对于它的控制相当严格,因此使用Game Center之前必须要做许多准备工作.通常需要经过以下几个步骤(下面的准

iOS开发——高级技术&社交服务

社交服务 Social 现 在很多应用都内置“社交分享”功能,可以将看到的新闻.博客.广告等内容分享到微博.微信.QQ.空间等,其实从iOS6.0开始苹果官方就内置了 Social.framework专门来实现社交分享功能,利用这个框架开发者只需要几句代码就可以实现内容分享.下面就以一个分享到新浪微博的功能为例 来演示Social框架的应用,整个过程分为:创建内容编辑控制器,设置分享内容(文本内容.图片.超链接等),设置发送(或取消)后的回调事件,展示控 制器. 程序代码: 1 // 2 //

iOS开发——高级技术&内购服务

内购服务 大家都知道做iOS开发本身的收入有三种来源:出售应用.内购和广告.国内用户通常很少直接 购买应用,因此对于开发者而言(特别是个人开发者),内购和广告收入就成了主要的收入来源.内购营销模式,通常软件本身是不收费的,但是要获得某些特权就 必须购买一些道具,而内购的过程是由苹果官方统一来管理的,所以和Game Center一样,在开发内购程序之前要做一些准备工作(下面的准备工作主要是针对真机的,模拟器省略Provisioning Profile配置过程): 前四步和Game Center基本

iOS开发——高级技术OC篇&运行时(Runtime)机制

运行时(Runtime)机制 本文将会以笔者个人的小小研究为例总结一下关于iOS开发中运行时的使用和常用方法的介绍,关于跟多运行时相关技术请查看笔者之前写的运行时高级用法及相关语法或者查看响应官方文档. 下面就来看看什么是运行时,我们要怎么在iOS开发中去使用它. 官方介绍: 这里我们主要关注的是最后一种! 下面来看看Runtime的相关总结 #pragma mark 获取属性成员 /********************************************************

iOS开发——高级技术&摇一摇功能的实现

摇一摇功能的实现 在AppStore中多样化功能越来越多的被使用了,所以今天就开始介绍一些iOS开发的比较实用,但是我们接触的比较少的功能,我们先从摇一摇功能开始 在 UIResponder中存在这么一套方法 1 - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0); 2 3 - (void)motionEnded:

iOS开发——高级技术精选OC篇&Runtime之字典转模型实战

Runtime之字典转模型实战 如果您还不知道什么是runtime,那么请先看看这几篇文章: http://www.cnblogs.com/iCocos/p/4734687.html http://www.cnblogs.com/iCocos/p/4676679.html http://www.cnblogs.com/iCocos/p/4725527.html 关于runtime的详细介绍及其相关的小实例 好了,这里就不多废话了,直接开干! 先来看看怎么使用Runtime给模型类赋值 iOS开发