iOS6:在你的企业系统中支持Passbook

前言

这是一篇翻译,感谢Jonathan Tang。

原文地址:iOS 6 Tutorial: Supporting Passbook within Your Enterprise Systems

正文

这是关于iOS6提供的被称为Passbook的新特性的第二篇教程。第一篇教程,iOS6:在你的App内使用Passbook(原文:iOS 6 Tutorial: Integrating Passbook into Your Applications )主要介绍了票据的相关信息以及如何在你的设备上创建和使用票据。

本篇教程描述了 Passbook Ecosystem,并且向你展示了如何动态的生成,传递和更新票据。我们还将大概的看一下与票据远程交互所需的web服务。

什么是Passbook Ecosystem

由于票据代表了一些用于展示的信息并且不包含任何可执行代码,你必须通过web服务或者app来与其进行交互。在Passbook Ecosystem中,一共有三个参与者:1)Conduit App,2)Companion App,3)Pass Server。

The Conduit

Conduit App是一种传递媒介,可能是email程序,web浏览器或者其他允许你获取和下载票据的应用。这个应用应该展示出票据的图标,名称以及组织名称(organization name)。例如,这是一个通过email传输的票据的例子:

iOS6:在你的企业系统中支持Passbook

Emailed Pass

The Companion

Companion App允许你请求,修改以及获取任何与应用相关联的票据。作为一个例子,一家冰激凌店的移动应用允许用户从网上预订一份甜点,然后自动向用户的库中添加一张优惠券或者会员卡,并且根据用户购买的金额自动更新用户的会员卡中的点数。你的应用将只能与经过授权访问的类型id的票据进行交互。

要想在代码中加载,访问以及修改票据,你需要使用PassKit框架,这个框架提供了Objective-C的API用来和用户的票据库进行交互。如果你想学习这方面的知识,请参考第一篇教程

The Server

Server是Passbook Ecosystem的骨干,它通过消息推送远程对票据进行创建,传输和更新。

在iPhone上,Passbook被设计为一个独立的系统级别的应用。即使用户并没有companion app,票据自身仍然是有用的。如果你要在你的企业中使用票据,conduit和companion app并不是必须的,因为票据server和苹果推送服务(APNs)可以远程的控制票据的整个生命流程。

Passbook能做什么 不能做什么

  • Companion app应该做到Passbook做不到的事情来增强用户体验,例如允许用户在应用中做出对票据的修改,比如向礼品卡中添加折扣,在登机牌中修改座位或者浏览要保存的优惠券。而且,你的应用不应该在用户不知情的情况下删除过期的票据。
  • 你应该创建创建数据库来保存需要的数据,而不是信任储存在票据中的数据。你应该从条形码中得到id然后询问你的数据库这张票据是否有效。
  • 与上一条类似的,你的server应该跟踪票据的有效性。票据的serial number(序列号)作为记录的id,票据中储存的数据只是一种快照(snapshot)。
  • 更新可能并不会及时的被传递,或者可能根本就没传递(译者:APNs推送的不可靠)。用户可能没有网络连接或者拒绝了票据的更新。因此,你应该更新你的本地数据库来记录票据的更新,在需要的时候进行查询。
  • 票据可能会被用户传递给他的朋友和家人。用户可能会将票据安装到多个iOS设备上。因此,你的server应该对这种权限做出限定。

在下面的章节中,我们将大概的查看实现票据web服务所需要的步骤。web服务所必要的步骤有:

1.为用户生成一个.pkpass文件。

2.将票据传输到设备上。

3.更新用户设备上得票据。

生成.pkpass文件

先让我们复习一下第一篇教程中创建.pkpass包的步骤:

1.为票据中得数据生成一个pass.json文件

2.为包种的内容生成manifest文件

3.使用票据证书生成签名文件

4.将文件夹压缩并且重命名为.pkpass后缀名

因此你的web服务将需要生成pass.json,manifest.json和签名文件。pass.json文件在第一篇教程中已经做了较好的描述。这里主要关注manifest.json和签名文件的生成。票据是由一个包含以下内容的文件夹生成的:

1.定义票据的pass.json。

2.图像(background.png,icon.png,strip.png,thumbnail.png)

3.manifest.json文件,包含了包中每个文件的hash值。

4.签名文件,即对manifes.json文件的PKCS#7签名文件。

manifest.json文件看起来是这样的:

{
    "pass.json" : "de440478cd0db57d35474d88f455e0bcdd0d3864",
    "icon.png" : "ba47a8021c8d74d2146d7244c8a0566be37df43b",
    "icon@2x.png" : "bd5442b4b08aa4dde333ec9ef0269e7fd93140b3”,
    "logo.png" : "780540b3a324bf66aeaee2d352283371356e9502",
    "logo@2x.png" : "a718ffd4e611e404dd3eb701454bcaefdabbe311"
}

manifest.json中包含包中除了自身和签名文件的所有文件。每个键都是票据目录中的相对路径。每个值都是文件对应的SHA1hash值。

给.pkpass文件签名就是使用与票据证书相关联的私钥对manifest.json进行PKCS#7的加密并保存为签名文件。你需要注意的一件重要的事情是在对票据签名时,你必须加载从WWDR下载的WWDR Intermediate 证书(Apple Worldwide Developer Relations intermediate certificate)。你需要从钥匙串中将WWDR证书导出为.pem文件,然后根据你的server的票据签名实现来确定如何使用它。

传输.pkpass文件

server生成票据之后,共有三种传输途径:1)通过email下载,2)通过网页下载,3)在应用中展示。

1.通过email传输,你只需要将.pkpass作为附件发送就可以了。Mail应用将会自动识别出附件的mimetype是.pkpass并且允许你添加到Passbook里。你也可以构建一个conduit app作为传递途径。

2.将MIME类型设置为application/vnd.apple.pkpass以供用户从网页上下载,Mobile Safari将会自动将其作为票据来处理。

3.你还可以在companion app中使用PassKit框架载入票据。这个框架的使用在第一篇教程中已经讲解过。

更新票据

票据是不可更改的。在一张票据生成之后你就不能更改了,你只能重新一张新的而不能修改旧的。并且在设备上也不能生成一张新的票据;你必须从web服务上或者其他地方获取到它。用户可以在companion app中向web服务请求票据更新或者web服务通过消息推送自动的更新设备上的票据。

如果你想通过推送向你的设备上发送票据,你需要将下面这一段添加到pass.json中:

pass.json: {
   ...
   "webServiceURL" : "https://www.myserver.com/pathto/service",
   "authenticationToken" : "PZ8GL23T24JEB41X6U",
   ...
}

webServiceURL是终端更新票据的基础信息。authenticationToken是一个用户设备和server共享的秘密字段。这个值由server为每个票据生成,用于确定对于某个票据的更新请求确实是由拥有这个票据的设备发出的。当设备做出的请求需要票据的authentication token进行鉴权时,请求的头部需要包含一个Authorization字段,它的值是"ApplePass <authentication token>"。

更新票据有三部分组成-用户的设备,苹果的server,以及你自己的server。你的server需要实现一个REST的web服务协议来允许这种交互的发生。server要想成功更新票据,需要实现下面这些服务:

1.设备注册

2.设备请求所有与其相关联的票据

3.设备请求某个票据的最新版本

4.设备发送给server错误日志

设备注册

设备通过发送一个POST请求给下面的endpoint,携带的数据是一个包含推送token的JSON字典,以及一个票据的authorization token作为头部。

https://<webServiceURL>/<version>/devices/<deviceLibraryIdentifier>
/registrations/<passTypeIdentifier>/<serialNumber>

每当票据要进行更新时,你的server就要发送一条推送通知到APNs,消息体是一个空得JSON字典。你可以在处理passbook更新的server上实现推送服务,也可以使用第三方的推送服务,比如Urban Airship或者Push Woosh。要想获得关于推送的更多的信息,请阅读 Apple’s Push Notification service documentation

设备请求所有与其相关联的票据

设备可以定期的向server发送GET请求获得所有票据:

https://<webServiceURL>/<version>/devices/<deviceLibraryIdentifier>
/registrations/<passTypeIdentifier>?passesUpdatedSince=<tag>

passesUpdatedSince参数是可选的,类似HTTP请求中的if-modified-since头域。你的web服务要返回一个在passesUpdatedSince之后更新过的票据的序列号集合。passesUpdatedSince格式是自定义的,完全由你的server自己决定。server返回一个JSON给设备,包含已更新的票据序列号的集合:

{
    "serialNumbers" : [ <serialNo.>, <serialNo.>, ... ],
    "lastUpdated" : <tag>
}

设备请求某个票据的最新版本

设备也可以通过下面的endpoint来请求更新一个指定的票据,在请求中需要携带一个authorization头域。

https://<webServiceURL>/<version>/passes/<passTypeIdentifier>
/<serialNumber>

如果请求鉴权通过,server需要返回请求的票据。你还可以在请求消息中支持if-modified-since头域,返回的头域中带有Last-modified:头域,或者在没有找到更新时以304作为返回码。

设备发送给server错误日志

一个可选但是强烈推荐的endpoint是日志服务URL。服务器将会在下面的endpoint收到一个POST请求,携带的数据是一个包含logs键,以及字符串数组作为值的JSON字典。

https://<webServiceURL>/<version>/log

结束

这个教程是关于iOS6提供的新特性,被称为Passbook的第二篇。在本篇教程里,我们讲解了Passbook ecosystem,以及远程更新票据所需要实现的web服务API。要想了解创建票据或者PassKit框架,请阅读第一篇教程

上一篇:《转载》Python并发编程之线程池/进程池--concurrent.futures模块


下一篇:python并行编程