Passbook 是苹果发布的 iOS 6 技术中最火热的一个, 它所带来的开创性超过我们的想象。
Passbook 是一些是一个非常棒的组合。 四项独立的技术结合到一起,为 iPhone 用户带来了一个全新的体验:
Passbook 和你曾经用到过的其他苹果的技术很不同。 让他变得与众不同的是关于一个文件格式的概念。 由你来创建 Passbook 文件, 然后用你希望的方式将他们展现给用户。 用什么技术和编程语言来实现它也完全取决于你!
毫无疑问, 通过这样的设置,相比其他苹果的技术, 你能够对你实现的东西有更多的控制。
因为苹果并没有处理 Passbook 的后端机制, 你需要使用一系列不同的技术来实现它。 在这篇教程中, 你将会用到 Objective-C 和 iOS,使用 JSON, 发送带有附件的多部分 Email, 使用 OpenSSL 对文件进行数字签名, 还有更多。
这篇教程被分为两个部分:
这个章节看起来有些凌乱, 但非常有好处 – 看完它之后, 你将会精通苹果最新的技术!
苹果关于 Passbook 的介绍中说 “你口袋里面的一切东西”。 我非常喜欢这句话, 因为它非常好的演示了你怎样能够并且应该创造性的创建你的应用程序和服务。 Passbook 可以是任何东西。
“但他们是什么呢?”, 你可能会这样问.
好吧, 这就是 Passbook 在 iPhone 上面的样子:
你能够很容易的认出这个 Pass 上面的几个不同的元素, 他们给了你一些重要的信息:一个 logo 和 公司的名称在最上方, “Free hug!” 清楚的描述了这个 Pass, 并且还有关于它的可用性的信息 (起始时间,持续时间)。
然后,在最下面,有一个条形码。 它和你在火车票,飞机票,购物券上面看到的条形码很象。如果你仔细的想一想, 你的 iPhone 中的 Pass 可以和那些塞满你口袋的纸质的票据保存同样的信息,对吧? 一些文字,一个条形码 – 就是这些了。相信我,你的 iPhone 上面的数字票卷可以做更多的事情。
再看一下 pass 中有什么, 想一想它拥有的不同部分:
现在,你可能会想纸质的票和购物券是什么样的。 这些你每天用到的东西可以被转换到 iPhone 上面。
在你写任何代码之前, 看一下不同类型的 pass。
苹果定义了 4 种不同的 pass, 每个都很常用, 还有第 5 种, 用作 “普遍” 用途。 为什么有这么多不同的 pass 呢, 你怎样识别他们呢?
预定义的这些 pass 类型,每一个都是为了显示不同种类的信息,以适应不同的用途。这也是为什么你的健身房会员证和你的音乐会门票的布局和内容是不同的! 前者需要你的照片,而后者不需要。
布局是区分这些不同种类的 pass 的主要方式, 但是一些 UI 特性, 比如圆角,剪纸同样能很容易的识别出 pass 来。 这些不同之处很小, 但是很明显, 这也是为什么你要确保用的是正确的 pass 类型的原因。
这里是四个预定义的 pass 类型:
但让, 还有通用类型的 pass。 教程的第二部分会讨论所有这五种类型。
现在,看一下下面这个登机牌的例子。 你会看到他和前面的那个拥抱优惠券很像, 但有一些关键的不同点:它提供了两列的布局方式, 这样能够很容易的找出离开和到达的城市; 离开的站台号,事件和座位号也都摆放整齐。
现在,我确定你已经被说服了, pass 是 iPhone 上面一个很伟大的东西! 让我们看看 pass 是如何设置的, 并且如何创建一个!
这部分将会介绍 pass 的构成部分。 pass 通过一个扩展名为 .pkpass 的文件展现给用户。 (“pkpass” 的意思是 PassKit Pass – 很好理解,对吗?)
.pkpass 只是一个 .zip 文件。 如果你将它重新命名为 ZIP 并解压它, 你会找到一些文件。 这是你前面看到的Free Hug Pass 的内容:
这就是所有了!
正如你看到的, pass 的主文件是 pass.json 这个 JSON 文件。 在它里面你声明了这个 pass 正面和反面的所有信息, 你提供了这个 pass 需要显示的所有图片(在优惠券的情况中, 你仅仅需要指定background.png和它的视网膜版本)。最终,你需要一个清单文件,它包含了所有这些文件的 SHA1 校验和,和一个分开的签名, 这样 Passbook 能够验证这个 pass 在你创建之后没有被修改过。
现在你可以写一些代码了。 让我们看看你能否重新创建一个Free Hug pass!
等一下! JSON 不是 Objective-C。 它甚至不是任何一种编程语言。 它仅仅是一个标记语言, 用来描述数据结构。 那么,你如何写 JSON 呢? 实际上你可以使用任何的文本编辑器 – Xcode, TextMate, Coda 或者 TextEdit. 在这章中, 你会用到 Xcode。
在 Xcode 的菜单中, 选择 File/New/File… 然后选择 iOS/Other/Empty 作为文件类型。 将新文件命名为pass.json 并将它保存到你选择的目录中。 注意你可能想要创建一个新的目录来存放 pass, 因为你会将很多和 pass 相关的文件存放到同一个目录中, 将他们放在一起是一个不错的选择。
你现在应该能看到这个空白的窗口, 就像这个:
但那没什么问题 – 不用担心!
你可以了解更多关于 JSON 的信息:http://en.wikipedia.org/wiki/JSON
你可能注意到了,苹果的 plist 文件存放着和 JSON 一样的信息 – 数组,字典,数字和其他。你可能会感到奇怪, 为什么苹果用 JSON 而不用 plist 呢。
是这样, pass 很有可能是在非 iOS 或者 OS X 的环境下生成的 – 更有可能的是, pass 是由 web 服务器作为对用户请求的响应生成的。 苹果想让你能够很容易的从所有的 web 脚本语言中生成这个文件, 因为 JSON 都被 PHP, .NET, Rubym Python 这样的语言良好的支持,最终, JSON 看起来是最佳的选择。
让我们从 Free Hug Pass 的架构开始! 将这些代码复制到 pass.json 文件中:
{ "formatVersion" : 1, "passTypeIdentifier" : "pass.com.yourdomain.couponfreehug", "serialNumber" : "001", "teamIdentifier" : "<YOUR TEAM IDENTIFIER>", "organizationName" : "Free Hugs LLC", "description" : "Coupon for 1 Free Hug" }
这是你需要提供的最小量的元数据:
这包含了很多信息, 所以让我们看看他们如何被苹果应用。
因为 pass 不是必须要和 iOS 应用相关联, 所以没有一个自动化的方式来让 pass 和指定的 iOS 开发者账号相关联(需要验证 pass 中的内容), Pass 可以独立于应用到达用户的设备上, 通过邮件或者下载的方式, 这也是为什么在 pass 的元数据中要包含 teamIdentifier 了 – 用于将 pass 和开发者账号相关联。一旦苹果知道了创建这个 pass 的开发者标识,它就会用 passTypeIdentifier 来确定它是哪种类型的 pass。 每种类型的 pass 都有它自己的证书,这样苹果就能过通过这个证书来验证包含在 pass 中的签名了 – 确保没有人篡改 pass 的内容。
最后, serialNumber 为指定的 pass 类型分配的序列号。
复习一下, 想一下这个例子:
现在你应该明白 pass 标识是如何工作的了。 所以, “通过” 这节,去看看下面的吧, 你将会创建你自己的 pass 类型。
进入 iOS Developer Portal (https://developer.apple.com/devcenter/ios/index.action), 在你登录进去之后, 在右边的菜单栏中打开 iOS Provisioning Portal。
如果你已经得到了签出到最新的 iOS 6 版本了,你可能已经注意到左边多了一个菜单项 Pass Type IDs。 点击那个链接,在接下来的页面中, 你将会看到你已经创建过的 pass 类型的列表(这时可能还是空的)。
点击 New Pass Type ID 按钮, 你将会进入一个创建新的类型的页面。 在描述区域填入 “Free Hug Pass”, 在标识区域填入 “pass.com.yourdomain.couponfreehug”。 对于 Pass Type ID, 苹果推荐使用以 “pass“ 开头的反向域名表示法。 这就是你要用的格式。
注意: 对于这章的目的来说, 你可以使用 “com.yourdomain” 这种形式, 但是在正式的应用中, 记住要将 com.yourdomain 这种替换成实际你自己的域名的方向表示法。?
还要注意,如果你决定将标识从 “pass.com.yourdomain.couponfreehug” 修改为别的, 你还要相应的修改 pass.json 文件中的 passTypeIdentifier 的值。
接下来, 点击 Submit 按钮来创建你的 pass。
顺便说一句,那个指示灯没有变成绿色, 你可能已经猜到,还缺一些东西。 你是对的。 你还需要生成一个 pass 证书。 点击 Configure 按钮。 将要展示的下一个页面是说明 pass 的标识的好地方。
这里你能看到你的 teamIdentifier (以 ABC 开头的前10个字符), 用这个 ID 来更新 pass.json 文件 – 确保仅替换占位符,并保留两边的引号!
好了! 你的 pass.json 现在更新了。 然而, 还有一些额外的步骤将你的证书导入你的开发环境。
返回 iOS Provisioning Portal, 点击 Configure 按钮:
这将会打开 Pass Certificate Assistant (*奇特的名字!), 它将会引导你完成证书的生成。 仔细看一下对话框中的内容,并跟随它的步骤。
当你提交你的签名请求之后, 你的证书将会及时的生成出来,并且你应该看到一个成功对话框:
点击 Continue 几次, 然后点击 Download 按钮来得到证书文件。 文件被下载后, 找到他,并双击它将它导入到钥匙串中。 注意大多数情况下它在你的用户目录中的 Downloads 文件夹中,除非你在浏览器中设置了另外一个默认下载地址。
如果钥匙串让你确定是否导入, 点击 Add 按钮:
然后, 你将会在钥匙串中看到你的证书:
你已经完成了证书的制作! 现在你在 JSON 文件里有了真实的数据, 并且当需要签名的时候你有了正确的证书。
让我们继续构建 pass.json 文件 – 接下来修改它的外观。
打开 pass.json 并且在最后定义一个 ”description“ 键, 添加一个逗号 – 因为你需要在字典中增加多个键。 在大括号结束前, 添加:
"logoText" : "Free Hugs LLC", "foregroundColor" : "rgb(255, 255, 255)", "backgroundColor" : "rgb(135, 129, 189)", "labelColor" : "rgb(45, 54, 129)"
这些键的作用:
现在你的 pass 有了一些样式! Heidi Klum 会感到很荣幸。
除非你达到了在 Passbook 中构建并测试的最小要求, 否则你还需要继续添加更多的元素。 接下来,你将会添加一个条形码。
听起来很复杂,对吗? 幸运的是,做起来很简单。 PassKit 支持三种不同的条形码 (所有这些都是二维条码格式):QR,
PDF417 and Aztec。
描述一下我的意思:
换句话说, pass 不支持那些老式的条形码, 你通常会在杂货店的商品包装上看到它们, 并且今后也不会支持它们。 PassKit 使用的是 2D 格式,可以让基于图片扫描的设备(像是 iPhone) 很容易的阅读它。
你将会使用 PDF417 标准来构建 Free Hug 优惠券的条形码 (上面这些图的中间那个), 在代码的最后一行添加一个逗号(在结尾大括号的前面),并把它粘贴到 barcode 的 JSON 中:
"barcode" : { "message" : "All you need is love", "format" : "PKBarcodeFormatPDF417", "messageEncoding" : "iso-8859-1" }
不管你信不信, 这是所有你需要做的 – 苹果会帮你生成一个条形码! barcode 字典有三个键:
目前为止, pass 的源代码看起来是这样的:
{ "formatVersion" : 1, "passTypeIdentifier" : "pass.com.yourdomain.couponfreehug", "serialNumber" : "001", "teamIdentifier" : "ABC1230000", "organizationName" : "Free Hugs LLC", "description" : "Coupon for 1 Free Hug", "logoText" : "Free Hugs LLC", "foregroundColor" : "rgb(255, 255, 255)", "backgroundColor" : "rgb(135, 129, 189)", "labelColor" : "rgb(45, 54, 129)", "barcode" : { "message" : "All you need is love", "format" : "PKBarcodeFormatPDF417", "messageEncoding" : "iso-8859-1" } }
接下来,你会添加一些有价值的信息到 pass 的正面。
再说一便, 在 barcode 字典的结尾大括号后面添加一个逗号。(你要保持这样, 因为我希望你的 JSON 文件在任何时候都是有效的。 一旦你习惯于写有效的 JSON, 你可以节省很多调试的时间。)
继续并添加一个键,用来表示这个 pass 是一个优惠券(将这段代码粘贴到最后一个结尾大括号的前面):
"coupon" : { }
在这个空的字典中, 你将会添加所有的定义和数据来显示优惠券上面的信息。
在 “coupon” 中添加:
"primaryFields" : [ { "key" : "offer", "label" : "for you", "value" : "Free hug" } ]
这种结构第一眼看上去比较奇怪, 但是相信我 – 它是有意义的。 首先你添加了一个新键 “primaryFields”, 它的值是一个数组。 为什么是数组呢? 因为每一节都可以显示一个或多个字段,所以你需要一个有序列表来指定他们的先后顺序。
在个列表中的每一个字典都描述了一个字段。 你大概已经看明白它们了, 但让我用例子来说明它。 对于每一个字段你都会得到如下几个基本键:
对于每一个字段,还有很多键可以用, 但你会在稍后看到它们。
重要的东西是 – 你现在有了一个完整的 pass.json 文件! 太酷了!
他们说一张图片顶得上千言万语 – 你很幸运, 在 pass 的正面没有地方显示上千个文字, 所以为了适应这个限制, 你也要使用图片。
下载我为你准备的资源:PassAssets.zip。 解压这些文件, 并在 FreeHugCoupon 目录下,你将会找到一系列的 PNG 文件。 将它们拷贝到你的 pass 工作目录中。
就是这样 – 你完成了! 非常容易。
等一下, 什么? 你不需要在 pass.json 添加任何代码来告诉 Passbook 要加载哪一张图片。 没错!
Passbook 会根据标准的命名规范来加载图片。这意味着名称为 icon.png; icon@2x.png; logo.png; logo@2x.png; strip.png and strip@2x.png 的图片
将会显示在 pass 上面。 除了需要把这些文件包含在 pass 的包中, 不需要在做任何其他事情(教程后面还会用到更多的图片。)
注意: 这里有一点 pass 图片比较难理解的地方 – 我花了一段时间才弄明白 – 图片文件需要导出成 PNG24 格式。 由于某些原因,比较小尺寸的 PNG8 格式不会显示在 Passbook 上面。
“让我们试试这个 pass 吧! 我已经想看看它了!”,
不幸的是, 在 pass 包完成,并且签名,压缩之前, 你不能够预览它。 Passbook 不能显示任何无效的(不完整的) pass。 所以,再忍耐一会儿, 继续工作。
pass 清单文件是另外一个你需要创建的 JSON 文件, 并且它描述了 pass bundle 中包含的所有文件和他们的 SHA1 校验和。
你可以通过自己生成 SHA1 校验和(稍后我会给你展示),但为了更快的创建完你的第一个 pass, 我将一个已经生成好的 manifest.json 文件放到了 PassAssets.zip 文件中,你已经下载并解压它了。在你解压 zip 的地方找到 manifest.json 文件, 将它拷贝到你的 pass 工作目录中。
它的内容如下:
{ "strip.png":"25b4c9ff2bafe056f3e28379db0ef3fb460c718b", "strip@2x.png":"dee775ed6fb3c7278b84c65853401e760caabc92", "icon.png":"8eaa0896db93f2165fa417df3d002ce9c61fcd92", "icon@2x.png":"555ce7f70f2f44fb7ac9d9f46df5738ec6250f37", "logo.png":"e8c4edfbcae41d9d88fad7137d8ed30ae5f73e67", "logo@2x.png":"1f9b1cc4c75b380ade07e9f2b7f37f988d9d14c3", "pass.json":"<INSERT YOUR PASS SHA1 HERE>" }
这些图片的 SHA1 校验和已经填好了, 但是最终的校验和 – pass.json 文件的 – 还没有。
你将会自己生成它的 SHA1。 这非常简单 – 打开终端并定位到你的 pass 目录。
注意: 如果你不熟悉如何在终端定位目录, 这样做: 将你的 pass 文件移动到桌面的 “FreeHugCoupon” 文件夹中, 然后打开终端,输入这个命令:
cd ~/Desktop/FreeHugCoupon |
这样就好了
在终端提示符中输入这个命令:
openssl sha1 pass.json
命令行的输出看起来是这样(实际的校验和可能会不同):
SHA1(pass.json)= c24766ef5aa92197eace640fcc4fb584a505a733
注意!
一个很重要的事情,就是在我没让你修改 pass.json 这个文件之前, 不要再修改它了。即便你仅仅向 pass.json 添加了一个字符, SHA1 校验和就会改变, 这样你的 manifest.json 文件将会失效,因为这里给出的校验和不再和修改后的 pass.json 文件的校验和相匹配。
这是你最后一个要修改的源文件了。 棒极了!
现在,进行创建 pass 中最有趣的一部分。
还记得你为你的 pass 类型从苹果获得的证书吗? 你已经将它导入到钥匙串中了, 并且还没有接触过它。 现在你将会把这个证书和秘钥导出成 PEM 格式, 这样你可以把它们用于 OpenSSL。
打开钥匙串访问, 在左边的菜单中选择证书(在类型下面),并找到叫做 “Pass Type ID: pass.com.yourdomain.couponfreehug” 的证书。 确保你选中的是证书本身,而不是它下面的私钥:
接下来, 右键点击这个证书, 在弹出菜单中选择导出 “Pass Type ID: pass.com.yourdomain.couponfreehug”…,将导出的文件保存成 “Certificates.p12” 到你的工作目录中。将会有一个弹出框,让你输入一个密码:
为了让这个过程更简单一点, 直接点击 OK – 这个证书将会导出为不带密码保护的。
注意: 在这是,你可能会被要求输入登陆钥匙串的密码。 如果是这种情况, 直接输入你电脑的用户密码就足够了。 Certificates.p12 文件现在包含了 pass 的证书和私钥。 OpenSSL 需要单独的两个文件, 所以现在你需要将他们从 .p12 文件中提取出来。
切换回终端 – 是 OpenSSL 魔术的时候了!
在确保当前目录是正确的之后 (输入 “ls -al” 然后点击 Enter 键 – 你应该看到这个目录的文件列表,并且这个列表应该包含你的 Certificates.p12 文件), 输入如下命令:
openssl pkcs12 -in Certificates.p12 -clcerts -nokeys -out passcertificate.pem -passin pass: |
这将仅将 pass 证书导出为 PEM 格式,并在同一个目录中把它保存成 “passcertificate.pem”。(如果这个操作成功的话, OpenSSL 将会输出 “MAC verified OK” 消息。)
接下来, 通过这个命令将私钥也导出成单独的文件:
openssl pkcs12 -in Certificates.p12 -nocerts -out passkey.pem -passin pass: -passout pass:12345 |
注意到这次, 你需要提供一个密码来导出这个私钥文件。 在这个例子中, 仅使用 “12345″ – 在生产环境中, 应当使用一个强密码 – 不能是 “password1” 或者 “passw00t” 这种东西。
为了给你的 pass bundle 签名, 你需要另外一个证书 –
To sign your pass bundle you will need one more certificate – WWDR Intermediate 证书, 用来验证发给你证书的发布者 – 苹果。 你已经将它安装到钥匙串中了。 打开钥匙串访问, 选择 “证书” 分类, 并找到一个叫做 “Apple Worldwide Developer Relations Certification Authority” 的证书(是的,这确实是一个很长的名字):
如果万一你没有这个证书, 那么打开你的浏览器, 访问这个页面http://www.apple.com/certificateauthority/。在这里你可以下载你可能需要的最重要的苹果证书。 翻到下面,找到 WWDR 证书, 下载 .cer 文件, 并导入到钥匙串中。
你已经准备好导出这个证书了。 返回到钥匙串访问, 右键点击证书名称并在弹出的菜单中选择导出选项:
在 “另存为…” 对话框中, 找到 format 下拉框,并选择 Privacy Enhanced Mail (.pem) 选项:
在对话框顶部的文本框中, 输入文件的名称 “WWDR.pem”, 选择 pass 的工作目录作为目标, 然后点击保存按钮来完成导出。 你已经可以创建签名了, 输入这个命令:
openssl smime -binary -sign -certfile WWDR.pem -signer passcertificate.pem -inkey passkey.pem -in manifest.json -out signature -outform DER -passin pass:12345 |
仔细看一看上面的命令行 – 非常容易理解所有的参数。 signer 参数是你的 pass 证书的文件名; inkey 是用于对 manifest.json 签名的私钥文件; in 是输入文件的文件名; out 是输出文件的文件名;outform 是输出的格式(你需要用 “DER“ 来创建一个分离的签名); 最后, passin 是私钥的密码。
现在你有了你的签名, pass 的创建基本完成了。
还剩下最后一步, 就是将 pass 中的多个文件集中到 .pkpass 文件中。 在终端输入这个命令:
zip -r freehugcoupon.pkpass manifest.json pass.json signature logo.png logo@2x.png icon.png icon@2x.png strip.png strip@2x.png |
通过使用 shell 命令 “zip”, 你创建一个叫做 freehugcoupon.pkpass 的 ZIP 文件, 并且这个档案包中包含了后面列表中的所有文件。
不管你是否相信。。。 就是这样! 全部都完成了! 你做到了!
是的, 你最终到达了, 你拥有了一个完整并有效的 pass, 你可以在 iOS 6 的设备上看到它了。
创建一个 email 消息(或者到你在 iOS 6 设备中设置的邮箱账号) 并附带一个你刚刚创建的 .pkpass 文件。 发送出去, 打开 Mail.app 并看一看! 你应该在附件中看到这个 pass, 像是这样:
如果你看到这个 pass 了 – 祝贺你! 你创建好它了!
如果没有, 不要失望 – 这是一个很长并容易出错的过程,你要回到开始阶段, 然后检查一些是否执行了所有必须的步骤。 确保你的 JSON 文件是有效的并且正确地导出了你的证书文件和私钥。
提示:如果你想验证 JSON 文件的有效性, 使用这个在线工具: http://jsonlint.com/ 来快速的验证你的代码。
是时候看看这个 pass 了! 在邮件消息中点击它, 然后 Passbook 将会弹出来并显示给你伟大的东西!
这非常棒! 点击右上角的 Add 按钮, 你将会看到一个精致的动画效果, pass 滑了下去(进入 pass 中, 但是你很有可能是空的) 然后你会返回到 Mail 中。
注意: 如果你想在你的 Passbook 中看到更多的 pass,可以用你的移动浏览器访问 http://passk.it/samples。 这个网站上面有一系列非常有趣的 pass 的样本。
现在,退出 Mail, 并打开 Passbook 应用。 这是你的第一个 pass。 祝贺你!
在 Passbook 预览一下这个 pass, 正面和背面(你可能会感到奇怪, 你可以通过点击右下角的那个小的斜体 “i” 来访问 pass 的背面):
iOS 6 Passbook 入门 1/2,布布扣,bubuko.com
原文:http://blog.csdn.net/ozhengxu/article/details/26456245