iOS 6 Passbook 入门 2/2
2014-11-26 14:16
197 查看
原文地址:点击打开链接
这是 iOS6 盛宴 的第二篇教程! 这篇教程是我们的新书 iOS
6 By Tutorials 中的一个缩略版本。 Marin Todorov 是这个章节的作者 — 他也写了 iOS 5 by Tutorials 大部分 “奖励” 章节。 希望你喜欢。
这是 iOS 教程团队成员 Marin
Todorov 的一篇博客, 一个有着12年经验的软件开发者,独立 iOS 开发者,并且是 Touch
Code Magazine 的创始人。
如果你看过这个系列的第一部分,
那么你应该知道如何构建一个 pass 包, 如何给他们签名, 如何通过邮件发送他们。我确信,你已经迫不及待的想要更深入的了解苹果这个最热门并且最新的技术了。
系好安全带 – 我们将继续上次没完成的部分!
关于 pass 更多的信息
pass 有两面: 在正面你可以在一些预定义的区域中添加文本信息; 在背面, 你可以尽可能的显示你想显示的信息。 让我们先对正面进行一些维护。☺打开 pass.json 并找到 primaryFields 数组的定义。 在它的同一级上, 在 coupon 字典中, 你将会添加更多的段, 来显示更多的信息。
你将添加另外的键到 coupon 字典上, 你首先需要添加一个逗号, 然后定义这个新键。当你将要在 coupon 字典添加另外一个键时, 你需要首先添加一个逗号, 然后再定义这个新键。在文件最后一个结尾方括号后面添加这个逗号(看看下面这张图片指出的位置)。
在逗号的下一行, 将 JSON 代码粘贴过去:
"secondaryFields" : [ { "key" : "expires", "label" : "Valid for", "value" : "Lifetime" } ], "auxiliaryFields" : [ { "key" : "date", "label" : "Promo starts on", "dateStyle" : "PKDateStyleMedium", "timeStyle" : "PKDateStyleNone", "value" : "2013-01-11T00:00Z" } ] |
这些是 pass 的正面的一些附加字段。 他们不像主字段那么重要, 但仍然足够重要,所以要留在正面。
auxiliary 字段可能会引起你特别的兴趣 – 它包含了一些你之前没有用到过的属性。 这个字段, 和你用到它其他字段不同, 它是一个日期字段。 Passbook 会处理将 日期/时间 值转换成用户所在的本地化时间的工作, 并将它格式化为本地化的文本显示。
看一下日期字段的属性:
value – 它是一个 W3C datatime 格式化后的值(关于它的文档, 可以看一下这里 http://www.w3.org/TR/NOTE-datetime)。
dateStyle – 用于格式化日期部分的风格; 必须是这些其中之一:PKDateStyleNone, PKDateStyleShort, PKDateStyleMedium,
PKDateStyleLong or PKDateStyleFull。
timeStyle – 和 date 字段的风格一样; 使用同样的常量来定义时间的风格。
这就完成了! 现在你可以进行另外一次构建, 并且看一下 pass 这时候是什么样子了! 你已经觉得很有趣了吧?
要执行的构建步骤:
确保 JSON 代码看起来没问题 (否则,确保用 http://jsonlint.com/ 来检测它)。
在终端里, 进入你的工作目录, 生成 pass.json 文件的 SHA1 校验和:
openssl sha1 pass.json |
为 pass 生成一个分离的签名:
openssl smime -binary -sign -certfile WWDR.pem -signer passcertificate.pem -inkey passkey.pem -in manifest.json -out signature -outform DER -passin pass:12345 |
zip -r freehugcoupon.pkpass manifest.json pass.json signature logo.png logo@2x.png icon.png icon@2x.png strip.png strip@2x.png |
任务完成了! 你的 pass 应该看起来和下面的图片一样:
正面基本完成了, 可以在背面做一些事情了!
打开 pass.json 并且在最后一个方括号后面添加一个逗号(现在你应该很熟练的能将逗号放在正确的位置上了)。 在逗号后面, 为卡片的背面添加一个字段:
"backFields" : [ { "key" : "extras", "label" : "Extras", "value" : "Your friends receive 50% off price" }, { "key" : "phone", "label" : "For more info", "value" : "800-1234567890" }, { "key" : "terms", "label" : "TERMS AND CONDITIONS", "value" : "Free hugs last 18 seconds and must be claimed on your birthday. Bring your pass or an id" } ] |
现在 – 是时候看一下你刚刚添加的字段在 pass 上看起来是什么样的了。 根据前面的说明再次构建, 并且通过电子邮件将 pass 发送到你的设备上。 按下 “i” 按钮, 然后背面将会显示出来 – 它应该看起来和下面的图片一样:
目前还不错! 再看看电话号码 – 它会自动被转换成链接,点击它你就可以直接拨打电话。 你可以在背面添加其他一些交互信息 – 像是地址(将会在地图中打开) 和电子邮箱(将会在 Mail 应用中打开)。
Pass 预览应用
你可能已经感觉到了, 如果构建和预览 pass 的过程能够更简单快速一点,那就更棒了。我的意思是, 继续, 我们一定要在每次想预览 pass 的时候, 必须要用邮件发送给我们自己吗?
当然 – 好消息! 因为我知道在你找到合适的 pass 之前, 你将会尝试多种颜色的组合, 图片和文字, 在这部分章节中, 你将会创建一个 iOS 应用, 它可以让你更快速的在 iPhone 模拟器中预览你的 pass。
注意: OS X 10.8.2 现在支持直接在你的 MAC 上面预览 pass。如果你双击 .pkpass 文件, 你将会看到 pass 的外观。 但是, 检测 pass 是否有效的唯一一个方法是,
在你的设备和模拟器上面打开它, 并试着导入它。
还有一个方法可以将 pass 安装到 Passbook 中, 我之前没有提到。 除了将 pass 通过 email 发送,并直接在 web 服务器上下载它, 你还可以使用 iOS 6 中新的 PassKit framework, 来通过 iOS 应用来安装 pass。
PassKit 是一个非常简单的 framework, 它仅包含了 3 个类。 为了创建一个简单的 pass 预览应用, 你将会用到 PKAddPassesViewController。这个类接受一个 PKPass 并将它显示到屏幕上。
在现实情况中, 你的应用很可能从服务端抓取一个 pass, 或者从 iClound 中得到它, 但在这个例子中, 你仅用到在你应用本地包中的 pass。
开始吧!
在 Xcode 的菜单中, 选择 File/New/Project…, 然后选择 iOS/Application/Single View Application 并且点击 Next。将项目命名为 “PassesPreview”, 并确保它是一个 iPhone 应用。 还要确保 Use Storyboards 和 Use Automatic Reference Counting 是选中的。 将项目保存到你选定一个位置。
在 Project Navigator 中, 选择 Xcode 项目(项目树中的第一个选项), 并在右边的条目中,确保 “PassesPreview” target 是选中的。 接下来点击 Build Phases 选项卡, 然后打开 Link Binary With Libraries 条目。
点击 (+) 按钮, 在 frameworks 的列表中双击 “PassKit.framework” 来将它包含到你的 Xcode 项目中 (或者选择 PassKit.framework 然后点击(+)按钮)。
现在选择 MainStoryboard.storyboard – 应用的界面显示出来了。 你需要一个全屏的表格, 所以将一个 TableView 拖动到主界面中。
接下来, 按住 Ctrl 并且将控制器对象拖动到下面的调色板中。 一个弹出框将会显示出来。 点击 “dataSource”, 然后重复这个操作, 并且第二次的时候,选择 “delegate”。 这个表格现在正确的连接到你的视图控制器中了。
现在,完成一些 Objective-C 的东西!
打开 ViewController.m 并将它的内容替换成这样:
#import "ViewController.h" #import <PassKit/PassKit.h> //1 @interface ViewController () //2 <UITableViewDelegate, UITableViewDataSource, PKAddPassesViewControllerDelegate> { NSMutableArray *_passes; //3 } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //4 if (![PKPassLibrary isPassLibraryAvailable]) { [[[UIAlertView alloc] initWithTitle:@"Error" message:@"PassKit not available" delegate:nil cancelButtonTitle:@"Pitty" otherButtonTitles: nil] show]; return; } } @end |
首先, 你导入 PassKit framework 头文件。
在 ViewController 的类扩展中, 你让它实现 UITableView 的数据源和代理协议, 最后,还有一个 PKAddPassesViewControllerDelegate 协议。
你声明了一个数组实例变量来保存所有 pass 文件包的列表。
最终在 viewDidLoad 里面, 如果 [PKPassLibrary isPassLibraryAvailable] 的结果是 NO, 那么你将显示一个消息, 来让用户知道他们的 Passbook 不可用。(你不属于这种情况的用户,但这是一个好机会来向你展示如何检测 Passbook 的可用性, 所以我把它放到了这里。)
我们的目标是检测这个 app 中是否带有 pass 包, 如果有的话, 显示他们的一个列表。当用户点击某个 pass 的文件名时, 这个应用也会显示一个漂亮的预览视图。
在 viewDidLoad 的最后, 添加如下代码:
// 1 initialize objects _passes = [[NSMutableArray alloc] init]; //2 load the passes from the resource folder NSString* resourcePath = [[NSBundle mainBundle] resourcePath]; NSArray* passFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:resourcePath error:nil]; //3 loop over the resource files for (NSString* passFile in passFiles) { if ( [passFile hasSuffix:@".pkpass"] ) { [_passes addObject: passFile]; } } |
首先初始化了一个 _passes 数组。
将应用所有资源文件的列表添加到 passFiles 数组中。
检测 passFiles 数组中所有的文件名, 并且将所有扩展名为 .pkpass 的文件添加到 _passes 数组中。
非常简单! 你有了你应用中所有 pass 文件名的列表。 接下来, 将他们显示到表格中!
在 ViewController.m 中添加三个方法, 来让 TableView 运行起来:
#pragma mark - Table View - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return _passes.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; if (!cell) cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier:@"Cell"]; NSString *object = _passes[indexPath.row]; cell.textLabel.text = object; return cell; } |
注意一下新的改变: 你可以通过 _passes.count 这种形式来访问 count 方法(不是属性)得到数组中元素的总数。 从数组(或字典中)中取出元素非常简单:
NSString *object = _passes[indexPath.row];
这些改变, 像是通过 . 表示法来调用方法, 在 iOS 6 之前就有了, 但他们仍然是新的。 其他关于数组的表示法就是全新的了, 你可以在第一章 “What’s New in Objective-C” 中了解到。
这就足够了 – 你可以运行这个项目, 并且没有任何警告和错误, 并且在屏幕上显示一个空的 TableView。
好了, 是时候包含一些 pass 文件到这个应用中了。 首先下载我为你准备好的: Passes.zip。解压这些文件,
将所有的 .pkpass 文件从 Passes 目录拷贝到你的 Xcode 项目根目录中。
注意: 确保这些文件添加到 PassesPreview target 中。默认情况下, Xcode 不会包含它们, 因为他们不是代码文件,也不是其他已知的 iOS 资源文件。
注意: 当你设计你自己的 pass 时,不要选中 “Copy items into …” 复选框。将 .pkpass 文件从 Pass 目录链接到 Xcode 项目中更加简单。当你更改代码或者替换图片后,
然后重新构建 pass 并且重启 Xcode 项目, 并且修改后的 pass 将会显示到屏幕上。
好了, 现在你在应用中得到了一些 pass, 点击 Run 你将会看到 pass 的列表:
最终, 你需要添加代码来在屏幕上显示选中的 pass, 将他们添加到 ViewController.m 中:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { //1 NSString* passName = _passes[indexPath.row]; [self openPassWithName:passName]; } -(void)openPassWithName:(NSString*)name { //2 NSString* passFile = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: name]; //3 NSData *passData = [NSData dataWithContentsOfFile:passFile]; //4 NSError* error = nil; PKPass *newPass = [[PKPass alloc] initWithData:passData error:&error]; //5 if (error!=nil) { [[[UIAlertView alloc] initWithTitle:@"Passes error" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"Ooops" otherButtonTitles: nil] show]; return; } //6 PKAddPassesViewController *addController = [[PKAddPassesViewController alloc] initWithPass:newPass]; addController.delegate = self; [self presentViewController:addController animated:YES completion:nil]; } |
首先, 当表格的一行被选中后, 你调用 openPassWithName 方法。
在 openPassWithName 中, 你重新创建了 .pkpass 文件的完整路径。
然后你读取了 .pkpass 文件的内容,并放到一个 NSData 实例中。
然后你通过初始化方法 initWithData:error: 创建一个新的 PKPass 对象。
你通过 error 变量来检测一切的加载问题。
最后, 你创建一个新的 PKAddPassesViewController 实例 – 这是一个特殊的视图控制器, 接受一个 PKPass 对象作为参数, 并显示它。 将 delegate 属性赋值为 self, 并且模态的显示这个控制器到屏幕上。
你还需要一个方法 – 当用户关闭 pass 对话框时会被调用。 (你在这里不会做太多特别的操作,但为了你以后开发更复杂的功能,你最好知道还有这么一个选择。)
添加 PKAddPassesViewController 代理协议必须的一个方法:
#pragma mark - Pass controller delegate -(void)addPassesViewControllerDidFinish: (PKAddPassesViewController*) controller { //pass added [self dismissViewControllerAnimated:YES completion:nil]; } |
这和你在 Mail 应用中打开一个 pass 附件时显示的对话框是完全一样的。注意, 如果你在 Passbook 中已经有了一个同样的 pass, 那么右上角的 Add 按钮将会被禁用。
成功了!
最后一步 – 在 viewDidLoad 的最后,添加如下代码:
if ([_passes count]==1) { [self openPassWithName:[_passes objectAtIndex:0]]; } |
现在, 现在你知道了关于如何创建一个优惠券的所有步骤, 并且你知道了怎样简单的测试和预览你的 pass。 这些技能的组合可以到达我们的下一个主题: 熟悉不同种类的 pass。
pass 的风格详解…
接下来,你将会看到关于不同风格 pass 的详细讲解。这里有一个预览, 当他们导入到 Passbook 中看起来是怎样的 – 你可以看到每个类型都有一个小的触摸区域:
怎么创建不同的 pass 呢? 回到 FreeHug 优惠券的源代码中,并打开 pass.json。在顶层的字典中,你添加了一个键叫做 “coupon” – 这个键的值是一个包含字段定义的字典。
所有的 pass 都以同样的方式工作 – 你仅需要做的是将这个 key 的名称从 coupon 修改为你想要的风格名称!
Santa 应得的假期旅行
为了让这个部分的例子更加有趣, Vicki Wenderlich 计划了 Santa 的假期旅行, 并准备了他这个应得的假期中所有需要的 pass。通过他 iPhone 的 Passbook 中提前购买好的优惠券,VIP卡和机票, Santa 可以不需要在它的玩具袋里面携带任何多余的纸张。第一个例子当然是 Santa 非飞往 Tahiti 的机票。这是这个章节资源中的 BoardingPass.pkpass 里面的 pass.json 文件的内容。{ "formatVersion" : 1, "passTypeIdentifier" : "pass.com.iOS6-By-Tutorials", "serialNumber" : "AX6184HJDG", "teamIdentifier" : "ABC1230000", "barcode" : { "message" : "AXB739-StClaus-A280", "format" : "PKBarcodeFormatQR", "messageEncoding" : "iso-8859-1" }, "organizationName" : "Reindeer Airways LLC", "description" : "Train Boarding Pass", "logoText" : "Reindeer Airways", "foregroundColor" : "rgb(255, 255, 255)", "backgroundColor" : "rgb(230, 72, 56)", "boardingPass" : { "headerFields" : [ { "key" : "header", "value" : "1", "label" : "Seat" } ], "primaryFields" : [ { "key" : "from", "value" : "NorthPole" }, { "key" : "to", "value" : "Tahiti" } ], "secondaryFields" : [ { "key" : "meal", "label" : "Meal", "value" : "Milk & Cookies" } ], "auxiliaryFields" : [ { "key" : "departure", "label" : "Departure:", "dateStyle" : "PKDateStyleMedium", "timeStyle" : "PKDateStyleMedium", "value" : "2012-12-27T10:35Z" } ], "backFields" : [ { "label" : "terms & conditions", "key" : "terms", "value" : "Ticket is non-refundable. Please specify which type of cookie you want upon check-in: chocolate chip, peanut butter, or M&M sugar cookie." } ], "transitType" : "PKTransitTypeAir" } } |
transitType, 根据你正在创建的 boardingPass 的类型, 你可以用这些预定义的常量之一:PKTransitTypeAir, PKTransitTypeTrain, PKTransitTypeBus, PKTransitTypeBoat, 和 PKTransitTypeGeneric。
这就是创建 coupon 和 boarding pass 的不同之处了! 上面的源代码的结果就是这个漂亮的登机牌:
你能在这个登机牌上面找到 Santa 的饮食偏好吗? 这样才能让服务员知道 – 他打算进行一个轻松的飞行!
登机牌样式的考虑
注意到主字段使用了一个非常大的字体, 所以这里只能显示很少的文字。 比较长的目的地名称,像是 “San Francisco”, 将会被截断, 所以要考虑用目的地的代码来替代名称。最好是将城市的全名用作标签, 将代码用作值。
登机牌不显示任何图片, 所以只需要 icon 和 logo 图片文件。
一个好主意是,将头部字段用作机场登机口, 站台或者座位号
确保你为你的登机牌用了正确的 transit type! 下面是不同类型显示出来的图标样式:
这里还有一个所有你可以用到的字段的预览(当然,你不需要用到所有的字段; 这里给了你这些可用字段的样式和位置的预览):
当你设计新的 pass 的时候, 有一个点重要的是你必须注意的:不同样式的条形码占据了 pass 的正面不同大小的区域。PDF417 条形码是横向布局, 所以它可以很好的放在卡片的底部 – 为 pass 的字段留下更多空间(就像上面的例子)。 另外一方面 QR 条形码是正方形的, 它在垂直区域占据更多的空间。看一下同样的 pass 使用了 QR 条形码之后,是什么样子:
你可以很明显的看到, 字段之间的垂直距离变短了, 这样条形码仍然能够放到卡片上;因此: 总要将 pass 设计到正确类型的条形码上, 这样你能够得到正确的字段布局。
注意: 如果你要重用任何这部分章节中例子中的代码, 不要忘记修改 team 和 pass type 的标识 – 否则, 你的 pass 将不能被导入到 Passbook 中。
你是高级会员吗?
接下来, 让我们看看购物券。 这些非常流行, 并且已经被广泛使用了, 所以我打赌, 很多商家都想用 iPhone 的 pass 格式来数字化他们的购物券。这里有一个购物券的例子。 Santa 打算进行一些户外运动, 所以它买了 Tahiti 冲浪和潜水学校的高级套餐。它的 pass 还方便的向他展示了他在这个学校的账户里,还剩下多少预付费的课程。正如你看到的, 购物券的文件布局在某些方面和优惠券很像,但是 header 的样式是不同的。 快速的看一下上面这个 pass 的源代码:
{ "formatVersion" : 1, "passTypeIdentifier" : "pass.com.iOS6-By-Tutorials", "serialNumber" : "00012", "teamIdentifier" : "ABC1230000", "barcode" : { "message" : "q2eq3aaa", "format" : "PKBarcodeFormatPDF417", "messageEncoding" : "iso-8859-1" }, "organizationName" : "Tahiti Surf & Snorkel", "description" : "Diving Lessons", "logoText" : "Tahiti Surf & Snorkel", "foregroundColor" : "rgb(255, 255, 255)", "backgroundColor" : "rgb(68, 200, 190)", "storeCard" : { "headerFields" : [ { "key" : "lessons", "label" : "Lessons", "value" : "4" } ], "primaryFields" : [ { "key" : "balance", "label" : "Class", "value" : "Premium" } ], "secondaryFields" : [ { "key" : "memberName", "label" : "Name", "value" : "Mr. Claus" } ], "backFields" : [ { "key" : "date", "label" : "Valid from:", "dateStyle" : "PKDateStyleMedium", "timeStyle" : "PKDateStyleNone", "value" : "2013-01-01T00:00Z" }, { "key" : "date", "label" : "Valid until:", "dateStyle" : "PKDateStyleMedium", "timeStyle" : "PKDateStyleNone", "value" : "2013-01-03T00:00Z" }, { "key" : "terms", "label" : "TERMS AND CONDITIONS", "value" : "Lessons must be used between 1/1/2013 and 3/1/2013. Appointments for lessons must be made no less than 48 hours in advance. Customer must be able to swim." } ] } } |
Passbook 自动检测日期, 并把他们变成链接。 当他们被点击时, 会给用户展示一个动作菜单, 可以将他们带入日历中的某一天, 或者帮助他们在日历中为特定的一天或一个阶段创建一个事件。 棒极了!
购物券样式考虑
通常, 购物券中包含了客户在这个商店的余额。一个好主意是,将这些信息放到 pass 的主区域中。
Passbook 还可以展示出不同样式的货币格式, 所以如果你要显示余额, 考虑一下将他们展示成用户自己的货币,像是这样:
Passbook 甚至能够自动删除日元小数点之后的数字,因为日元不用小数! (1 是可能的最小值)。
为了修改货币余额的样式, 你需要一个数字值(不带双引号的数字) 并且有另外的键用来定义使用什么货币。 对日元来说, 代码如下:
{ "key" : "amount", "label" : "Current credit store", "value" : 45.20, "currencyCode" : "JPY" } |
它是一张门票, 它是一个 iPhone!
下一个 pass 类型是活动门票 – 它可以是音乐会门票, 电影票或者其他任何类型的你可以参与的门票!回到 PassPreview 应用, 选择 ConcertTicket.pkpass。 一个漂亮的门票展现出来:
正如你看到的,Santa 没有很早的睡觉 – 它打算享受一下草裙舞表演和海边的夜晚。
当你提前计划好并将所有的门票放到口袋里非常容易 – 方便的存到你的 iPhone 里面吧!
活动门票有一些独特的特性。 如果你提供了一个背景图片文件, 它会拉伸,模糊, 并设置成整张卡片的背景。 如果你提供了一个预览图(thumbnail.png 和 thumbnail@2x.png), 图片会显示在右边。
注意, 因为背景图片会填满整个 pass 的正面, 你不再需要在你的 pass.json 文件中指定 “backgroundColor” 属性了。
除了点比较特殊,其他的地方你都已经知道了:
{ "formatVersion" : 1, "passTypeIdentifier" : "pass.com.iOS6-By-Tutorials", "serialNumber" : "000024567", "teamIdentifier" : "ABC1230000", "barcode" : { "message" : "12946390566", "format" : "PKBarcodeFormatQR", "messageEncoding" : "iso-8859-1" }, "organizationName" : "Tahiti Beach Hula Show", "description" : "Entrance ticket to Tahiti Beach Hula Show", "logoText" : "Tahiti Beach Hula Show", "foregroundColor" : "rgb(255, 255, 255)", "backgroundColor" : "rgb(242, 121, 55)", "eventTicket" : { "primaryFields" : [ { "key" : "name", "value" : "Tahiti Beach Hula" } ], "secondaryFields" : [ { "key" : "location", "label" : "Location", "value" : "Next to Maxi's Martini Bar" } ], "auxiliaryFields" : [ { "key" : "date", "label" : "Event date", "dateStyle" : "PKDateStyleMedium", "timeStyle" : "PKDateStyleMedium", "value" : "2012-12-29T19:00Z" } ], "backFields" : [ { "key" : "terms", "label" : "Terms & conditions", "value" : "This ticket may cause happiness and good cheer! Free lei with ticket." } ] } } |
活动门票样式的考虑
如果你提供了一个背景图片, 但没提供缩略图, 那么 Passbook 将也会在右边缩略图的区域显示背景图片。
你可以禁用背景上的模糊效果 – 苹果用这种效果来突出文字信息。
对于像是会议这类的活动门票, pass 正面缩略图的位置是放置参会者照片的好地方。
最终, 这里是活动门票正面所有可用的字段区域。
你一直都需要的 pass!
最后, 我们得到了你一直需要的 pass, 或者说是创建。 或者说是创建和得到。最后一种类型的 pass 是通用 pass。 它有基本的样式,可以提供多种不同的文本域, 可以在正面显示一张图片, 并且, 你可以用它来实现所有种类的 pass, 其他四种 pass 不能很好适应的 – 优惠券, 登机牌, 购物券,或者活动门票。
现在, 我们发现 Santa 饮料的选择: 它想在海边喝一杯凉的马提尼, 享受吧, Santa!
打开 PassPreview 并点击 GenericPass.pkpass:
正如你看到的, 其他四种类型的样式都和这个不是很适应。 它给持有者提供 Maxi’s Martini Bar 的 VIP 休息室和每天一杯的马提尼。 它更像是酒吧的会员卡, 没有已存在的预定义样式。
但是这个通用的 pass 看起来非常棒! 是呀 – 你仍然机会去用我们已经讨论过的方式来自定义它! 在 pass.json 中没有什么特别的, 除了 pass 类型的键变成了 generic:
{ "formatVersion" : 1, "passTypeIdentifier" : "pass.com.iOS6-By-Tutorials", "serialNumber" : "123456", "teamIdentifier" : "ABC1230000", "barcode" : { "message" : "7465-454-2234-1", "format" : "PKBarcodeFormatPDF417", "messageEncoding" : "iso-8859-1" }, "organizationName" : "Maxi's Martini Bar", "description" : "Generic Pass Example", "logoText" : "Maxi's Martini Bar", "foregroundColor" : "rgb(33, 33, 33)", "backgroundColor" : "rgb(122, 230, 88)", "generic" : { "headerFields" : [ { "key" : "header", "value" : "VIP" } ], "primaryFields" : [ { "key" : "member", "value" : "Santa Claus" } ], "secondaryFields" : [ { "key" : "faux1", "value" : "" }, { "key" : "secondary1", "label" : "Rewards Earned", "value" : "Free Specialty Martini", "textAlignment" : "PKTextAlignmentRight" } ], "auxiliaryFields" : [ { "key" : "faux2", "value" : "" }, { "key" : "status", "value" : "Level 3", "label" : "Membership Status", "textAlignment" : "PKTextAlignmentRight" } ], "backFields" : [ { "label" : "terms & conditions", "key" : "terms", "value" : "Must show proof of ID to claim rewards." } ] } } |
这个字段是干什么用的?
{ "key" : "faux1", "value" : "" }, |
那么,如果你想在第二个副标题的位置显示一块文本, 但是你不想在第一个副标题上显示任何信息呢?
哈哈! 定义一个 faux 类型的副标题, 并赋予空值并不带有任何 label(像是上面的代码), 非常棒!
另一个需要注意的地方是上面代码用到的 “textAlignment” 键。 使用这个键, 你可以告诉 Passbook 如何为一个文本域指定文字的对齐方式。 你可以从以下预定义的常量中选择一个:PKTextAlignmentLeft, PKTextAlignmentCenter, PKTextAlignmentRight, PKTextAlignmentJustified, and PKTextAlignmentNatural。
这里是你可以在通用 pass 中用到的所有可用字段的预览:
好了! 你基本完成了, 我希望这次学习是有意义的! 你知道了关于设计,***和预览 pass 的一切信息。 OK! You’ve made it this far and I hope the trip was rewarding! 你已经学习到所有东西了!
相关文章推荐
- iOS 6 Passbook 入门 1/2 | Ray Wenderlich
- iOS 6 Passbook 入门 2/2
- iOS 6 Passbook 入门 1/2
- iOS 6 Passbook 入门 1/2
- Ios 入门 ----WebView 控件
- IOS 入门开发之创建标题栏UINavigationBar的使用(二)
- IOS 入门开发之分页栏TabBar的使用(四)
- IOS 入门开发之导航栏按钮切换(三)
- IOS 入门开发之创建第一个应用程序
- Obejctive-C 2.0 Mac和iOS开发实践指南(Objective-C 2.0最佳入门指南)
- Ios 入门 ----基本的控件 (二)
- Ios 入门 ----基本的控件 (二)
- Ios 入门 ----Helloword
- IOS 入门介绍1-----IOS简单介绍
- Become a iOS coder iOS入门文档
- Ios 入门 ----基本的控件 (三)
- IOS 入门开发之分页栏TabBar的使用(四)
- IOS 入门开发之构建第一个应用程序(一)
- Ios 入门 ----基本的控件
- IOS 入门介绍3------iOS里面Frameworks介绍(续)