iOS開發——高級技術&PassBook服務

PassBook服務html

Passbook是蘋果推出的一個管理登機牌、會員卡、電影票、優惠券等信息的 工具。Passbook就像一個卡包,用於存放你的購物卡、積分卡、電影票、禮品卡等,而這些票據就是一個「Pass」。和物理票據不一樣的是你能夠動態更 新Pass的信息,提醒用戶優惠券即將過時;甚至若是你的Pass中包含地理位置信息的話當你到達某個商店還能夠動態提示用戶最近商店有何種優惠活動;當 用戶將一張團購券添加到Passbook以後,用戶到了商店以後Passbook能夠自動彈出團購券,店員掃描以後進行消費、積分等等都是 Passbook的應用場景。Passbook能夠管理多類票據,蘋果將其劃分爲五類:ios

  1. 登機牌(Boarding pass)git

  2. 優惠券(Coupon)   算法

  3. 活動票據、入場券(Event ticket)編程

  4. 購物卡、積分卡(Store Cards)json

  5. 普通票據(自定義票據)(Generic pass)服務器

蘋果的劃分一方面出於不一樣票據功能及展現信息不一樣,另外一方面也是爲了統一票據的設計,下面是蘋果官方關於五種票據的佈局設計佈局:app

130915096512753.png

既然一個票據就是一個Pass,那麼什麼是Pass呢?在iOS中一個Pass其實就是一個.pkpass文件,事實上它是一個Zip壓縮包,只是這個壓縮包要按照必定的目錄結構來設計,下面是一個Pass包的目錄結構(注意不一樣的票據類型會適當刪減):框架

Pass Packageide

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

相關文章
相關標籤/搜索