如何为IOS6生成Pass
限于本人的能力与知识,仅做为参考交流使用。如有疑问,欢迎指正。
我的iPhone在上周下载了IOS6,第一个吸引我的Icon是Passbook.但是却没有发现任何的实例。因为Passbook的原因,我才下载了IOS6的。所以研究了一下API并学习怎么去建一个自己的pass。我想要分享的正是我学习中的经验。我甚至做出一个,用来自动处理并为你生成pass,一个基于GUI的友好服务界面来新建一些pass.
What is a pass? Pass是什么
实际上,一个pass就是一个zip包档案。它包含有以下的文件
1. logo.png (备选): 用于做logo的图片。
2. background.png (备选): 用于做背景的图的文件。
3. icon.png (备选): 用于做 icon的文件
4. manifest.json (必选):这个文件包含了一个除签名文件(因为它是使用manifest.json生成的)以外的一切文件的SHA1 hashes JSON还有它自己manifest.json,他的格式如下:
{
"pass.json" : "<sha1 pf pass.json file>",
"logo.png" : "sdfqefqefqef",
...
}
为了便于参考,在linux里面新建一个SHA1 hash最简单的方法是使用命令:
openssl SHA1 <filename>
5. signature (必选): 用manifest.json与证书一起生成的文件。
6. pass.json (必选): 它包含有一个json, 它存有专门用于pass显示的样式、格式与数据。
苹果有一个可用的参考,但是,不管怎么样,它离完整还有一段距离,而且它也没有一些重要的细节
真正让我们去理解pass.json的方法是试验-出错-试验:试着全用各种不同的选项去生成一大堆的pass,并在IOS6中观察它的输出。因此我搞了至少要两个星期。我也开发了些小工具来帮助我快速地做一些重复性的工作。开始时,它是一个C-shell脚本,通过命令行来生成iPass.pk。后来,它又被做到了一个有Pass设计工具,你可以通过它在GUI上修改一些值、标签。
让我给你一些我学习过程中的实例,它可仅仅包含苹果的文档所提到的那些内容。第一,提供了一些环境,结合各个文件的描叙,让我们一起看一看实例Pass的文件与它的JSON。
我们感兴趣的文件是:logoText,和 primary, secondary, auxiliary, 与一些头文件。在以上的截屏上,它们都有注解。对于每一个文件,我都填上了:<文件类型缩写><相对就文件队列中的序号>
如何人工生成Pass?
万一,你不想使用那个GUI去循环pass,你可以用我的C-shell 脚本。这个C-shell脚本事实上就是做了以下的工作。
Step 1:生成苹果开发证书
登录到苹果开发者入口,并请求一个pass类型的标识和你的证书。从key chain中导出为一个.p12文件
Step 2: 生成key.pem 和 certificate.pem
openssl pkcs12 -in "My PassKit Cert.p12" -clcerts -nokeys -out certificate.pem
openssl pkcs12 -in "My PassKit Cert.p12" -nocerts -out key.pem
Step 3: 收集文件
拷贝pass.json和一些logo/icon/背景图片文件一个目录下。
Step 4: 生成manifest.json
所有的工作就是生成一个含有SHA1 哈希的JSON,它里面有第三步之前所生成的所有文件。我使用以下的csh脚本去生成manifest.json。
set MANIFEST = ../manifest.json
echo '{' > $MANIFEST
foreach i (*)
set sha1 = `openssl sha1 $i | cut -d' ' -f2`
echo \'$i\' : \'$sha1\', >> $MANIFEST
end
echo '}' >> $MANIFEST
cp $MANIFEST .
Step 5:生成签名
运行以下的csh命令来得到签名文件:
set PASSWORD = xxxx openssl smime -passin pass:$PASSWORD -binary -sign -signer $CWD/certificate.pem -inkey $CWD/key.pem -in manifest.json -out signature xs-outform DER
现在,通过邮件,把它发送给你自己,并打开它。是不是帅呆了?
Step 6: Zip 一下pass
zip test.pkpass *
现在,通过email发送test.pkpass给你自己,看看是不是很神奇。
对本教程,, 或如果有任何疑问或讨论,请及时联系我。
以下是json.pass:
{
"passTypeIdentifier":"X.Y.Z",//Type Identified you will get from Apple Portal
"formatVersion":1,//Stays 1
"organizationName":"Flight Express",//The name which appears on push notifications
"serialNumber":"158cd3b6-2468-4067-80f2-75715eaf4ae0",//A number for you to identify this pass
"teamIdentifier":"AGK5BZEN3E",//Your Team ID
"description":"Demo pass",//Required but I haven't found its use yet
"foregroundColor":"rgb(54,80,255)",//color of the data text (note the syntax)
"backgroundColor":"rgb(209,255,247)",//duh!
"labelColor":"rgb(255,15,15)",//color of label text and icons
"logoText":"Boarding Pass",//Text that appears next to logo on top
"barcode":{ //Specification of the barcode (can be omitted)
"format":"PKBarcodeFormatQR",// Format can be QR, Text, Aztec, PDF417
"message":"Flight-GateF12",//What to encode in barcode
"messageEncoding":"iso-8859-1"//Encoding of the message
},
"relevantDate":"2012-07-12T19:23Z",//When to show pass on screen. ISO8601 formatted.
/* The following fields are specific to which type of pass. The name of this object specifies the type, e.g., boardingPass below implies this is a boarding pass. Other options include storeCard, generic, coupon, and eventTicket */
"boardingPass":{
/*headerFields, primaryFields, secondaryFields, and auxiliaryFields are arrays of field object. Each field has a key, label, and value*/
"headerFields":[//Header fields appear next to logoText
{
"key":"h1-label",//Must be unique. Used by iOS apps to get the data.
"label":"H1-label",//Label of the field
"value":"H1"//The actual data in the field
},
{
"key":"h2-label",
"label":"H2-label",
"value":"H2"
}
],
"primaryFields":[//Appearance differs based on pass type
{
"key":"p1-label",
"label":"P1-label",
"value":"P1"
},
{
"key":"p2-label",
"label":"P2-label",
"value":"P2"
},
{
"key":"p3-label",
"label":"P3-label",
"value":"P3"
},
{
"key":"p4-label",
"label":"P4-label",
"value":"P4"
},
{
"key":"p5-label",
"label":"P5-label",
"value":"P5"
}
],
"secondaryFields":[//Typically appear below primaryFields
{
"key":"s1-label",
"label":"S1-label",
"value":"S1"
},
{
"key":"s2-label",
"label":"S2-label",
"value":"S2"
},
{
"key":"s3-label",
"label":"S3-label",
"value":"S3"
},
{
"key":"s4-label",
"label":"S4-label",
"value":"S4"
},
{
"key":"s5-label",
"label":"S5-label",
"value":"S5"
}
],
"auxiliaryFields":[//Appear below secondary fields
{
"key":"a1-label",
"label":"A1-label",
"value":"A1"
},
{
"key":"a2-label",
"label":"A2-label",
"value":"A2"
},
{
"key":"a3-label",
"label":"A3-label",
"value":"A3"
},
{
"key":"a4-label",
"label":"A4-label",
"value":"A4"
},
{
"key":"a5-label",
"label":"A5-label",
"value":"A5"
}
],
"transitType":"PKTransitTypeAir"//Only present in boradingPass type. Value can
//Air, Bus, Boat, or Train. Impacts the picture
//that shows in the middle of the pass.
}
}