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

PassBook服务javascript

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

  1. 登机牌(Boarding pass)java

  2. 优惠券(Coupon)   ios

  3. 活动票据、入场券(Event ticket)git

  4. 购物卡、积分卡(Store Cards)算法

  5. 普通票据(自定义票据)(Generic pass)编程

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

130915096512753.png

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

Pass Packageapp

├── icon.png

├── icon@2x.png

├── logo.png

├── logo@2x.png

├── thumbnail.png

├── thumbnail@2x.png

├── background.png

├── background@2x.png

├── strip.png

├── strip@2x.png

├── 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

211.png

下载证书后,将此证书导入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“。

322.png

有了上面的准备工做,下面看一下如何制做一个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 "icon@2x.png":"83438c13dfd7c4a5819a12f6df6dc74b71060289", 4 "icon.png":"83438c13dfd7c4a5819a12f6df6dc74b71060289", 5 "logo@2x.png":"83438c13dfd7c4a5819a12f6df6dc74b71060289", 6 "logo.png":"83438c13dfd7c4a5819a12f6df6dc74b71060289", 7 "strip@2x.png":"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、icon@2x.png、logo.png、logo@2x.png、strip.png、strip@2x.png 、pass.json、manifest.json、signature压缩成pass包(这里命名为”mypassbook.pkpass“)。

zip -r mypassbook.pkpass manifest.json pass.json signature logo.png logo@2x.png icon.png icon@2x.png strip.png strip@2x.png

到这里一个pass制做完成了,此处能够在mac中打开预览:

130915153081291.png

到 这里一个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
复制代码

 

运行效果:

rrrr.gif

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

相关文章
相关标签/搜索