iOS 6 Passbook 入门 2/2
2014-05-21 11:27
232 查看
如果你看过这个系列的第一部分,
那么你应该知道如何构建一个pass包,如何给他们签名,如何通过邮件发送他们。我确信,你已经迫不及待的想要更深入的了解苹果这个最热门并且最新的技术了。
系好安全带–我们将继续上次没完成的部分!
打开pass.json并找到
primaryFields数组的定义。在它的同一级上,在coupon字典中,你将会添加更多的段,来显示更多的信息。
你将添加另外的键到coupon字典上,你首先需要添加一个逗号,然后定义这个新键。当你将要在coupon字典添加另外一个键时,你需要首先添加一个逗号,然后再定义这个新键。在文件最后一个结尾方括号后面添加这个逗号(看看下面这张图片指出的位置)。
在逗号的下一行,将JSON代码粘贴过去:
"secondaryFields":[
{
"key":"expires",
"label":"Validfor",
"value":"Lifetime"
}
],
"auxiliaryFields":[
{
"key":"date",
"label":"Promostartson",
"dateStyle":"PKDateStyleMedium",
"timeStyle":"PKDateStyleNone",
"value":"2013-01-11T00:00Z"
}
]
现在除了primaryFields
字典,你有了secondaryFields和auxiliaryFields–
这些是pass的正面的一些附加字段。他们不像主字段那么重要,但仍然足够重要,所以要留在正面。
auxiliary字段可能会引起你特别的兴趣–它包含了一些你之前没有用到过的属性。这个字段,和你用到它其他字段不同,它是一个日期字段。Passbook会处理将日期/时间值转换成用户所在的本地化时间的工作,并将它格式化为本地化的文本显示。
看一下日期字段的属性:
value–
它是一个W3Cdatatime格式化后的值(关于它的文档,可以看一下这里http://www.w3.org/TR/NOTE-datetime)。
dateStyle–
用于格式化日期部分的风格;必须是这些其中之一:PKDateStyleNone,PKDateStyleShort,PKDateStyleMedium,PKDateStyleLongorPKDateStyleFull。
timeStyle–
和date字段的风格一样;使用同样的常量来定义时间的风格。
这就完成了!现在你可以进行另外一次构建,并且看一下pass这时候是什么样子了!你已经觉得很有趣了吧?
要执行的构建步骤:
确保JSON代码看起来没问题(否则,确保用http://jsonlint.com/来检测它)。
在终端里,进入你的工作目录,生成pass.json文件的SHA1校验和:
opensslsha1pass.json
将pass.json的SHA1校验和放入manifest.json文件中。
为pass生成一个分离的签名:
最终,将这些文件打包到.pkpass中:
通过电子邮件将文件发送到你的iOS6设备上!
任务完成了!你的pass应该看起来和下面的图片一样:
正面基本完成了,可以在背面做一些事情了!
打开pass.json并且在最后一个方括号后面添加一个逗号(现在你应该很熟练的能将逗号放在正确的位置上了)。
在逗号后面,为卡片的背面添加一个字段:
"backFields":[
{
"key":"extras",
"label":"Extras",
"value":"Yourfriendsreceive50%offprice"
},
{
"key":"phone",
"label":"Formoreinfo",
"value":"800-1234567890"
},
{
"key":"terms",
"label":"TERMSANDCONDITIONS",
"value":"Freehugslast18secondsandmustbeclaimedonyourbirthday.Bringyourpassoranid"
}
]
幸运的是,pass的背面是可以滚动的,所以你可以添加更多你需要的信息。(是的,有时候合同条款会占据很长的空间,所以滚动是很必须的。)
现在–是时候看一下你刚刚添加的字段在pass上看起来是什么样的了。根据前面的说明再次构建,并且通过电子邮件将pass发送到你的设备上。按下“i”按钮,然后背面将会显示出来–它应该看起来和下面的图片一样:
目前还不错!再看看电话号码–它会自动被转换成链接,点击它你就可以直接拨打电话。你可以在背面添加其他一些交互信息–像是地址(将会在地图中打开)和电子邮箱(将会在Mail应用中打开)。
我的意思是,继续,我们一定要在每次想预览pass的时候,必须要用邮件发送给我们自己吗?
当然–好消息!因为我知道在你找到合适的pass之前,你将会尝试多种颜色的组合,图片和文字,在这部分章节中,你将会创建一个iOS应用,它可以让你更快速的在iPhone模拟器中预览你的pass。
注意:OS
X10.8.2现在支持直接在你的MAC上面预览pass。如果你双击.pkpass文件,你将会看到pass的外观。但是,检测pass是否有效的唯一一个方法是,在你的设备和模拟器上面打开它,并试着导入它。
还有一个方法可以将pass安装到Passbook中,我之前没有提到。除了将pass通过email发送,并直接在web服务器上下载它,你还可以使用iOS6中新的PassKitframework,来通过iOS应用来安装pass。
PassKit是一个非常简单的framework,它仅包含了3个类。为了创建一个简单的pass预览应用,你将会用到PKAddPassesViewController。这个类接受一个PKPass并将它显示到屏幕上。
在现实情况中,你的应用很可能从服务端抓取一个pass,或者从iClound中得到它,但在这个例子中,你仅用到在你应用本地包中的pass。
开始吧!
在Xcode的菜单中,选择File/New/Project…,然后选择iOS/Application/SingleViewApplication并且点击Next。将项目命名为“PassesPreview”,并确保它是一个iPhone应用。还要确保UseStoryboards和UseAutomaticReferenceCounting是选中的。将项目保存到你选定一个位置。
在ProjectNavigator中,选择Xcode项目(项目树中的第一个选项),并在右边的条目中,确保“PassesPreview”target是选中的。接下来点击BuildPhases选项卡,然后打开LinkBinaryWithLibraries条目。
点击(+)按钮,在frameworks的列表中双击“PassKit.framework”来将它包含到你的Xcode项目中(或者选择PassKit.framework然后点击(+)按钮)。
现在选择MainStoryboard.storyboard–应用的界面显示出来了。你需要一个全屏的表格,所以将一个TableView拖动到主界面中。
接下来,按住Ctrl并且将控制器对象拖动到下面的调色板中。一个弹出框将会显示出来。点击“dataSource”,然后重复这个操作,并且第二次的时候,选择“delegate”。这个表格现在正确的连接到你的视图控制器中了。
现在,完成一些Objective-C的东西!
打开ViewController.m并将它的内容替换成这样:
#import"ViewController.h"
#import<PassKit/PassKit.h>//1
@interfaceViewController()//2
<UITableViewDelegate,UITableViewDataSource,
PKAddPassesViewControllerDelegate>
{
NSMutableArray*_passes;//3
}
@end
@implementationViewController
-(void)viewDidLoad
{
[superviewDidLoad];
//4
if(![PKPassLibraryisPassLibraryAvailable]){
[[[UIAlertViewalloc]initWithTitle:@"Error"
message:@"PassKitnotavailable"
delegate:nil
cancelButtonTitle:@"Pitty"
otherButtonTitles:nil]show];
return;
}
}
@end
这个代码非常基础并且只要4处需要解释的:
首先,你导入PassKitframework头文件。
在ViewController的类扩展中,你让它实现UITableView的数据源和代理协议,最后,还有一个PKAddPassesViewControllerDelegate协议。
你声明了一个数组实例变量来保存所有pass文件包的列表。
最终在viewDidLoad里面,如果[PKPassLibraryisPassLibraryAvailable]的结果是NO,那么你将显示一个消息,来让用户知道他们的Passbook不可用。(你不属于这种情况的用户,但这是一个好机会来向你展示如何检测Passbook的可用性,所以我把它放到了这里。)
我们的目标是检测这个app中是否带有pass包,如果有的话,显示他们的一个列表。当用户点击某个pass的文件名时,这个应用也会显示一个漂亮的预览视图。
在viewDidLoad的最后,添加如下代码:
这个简单的代码做的事情:
首先初始化了一个_passes数组。
将应用所有资源文件的列表添加到passFiles数组中。
检测passFiles数组中所有的文件名,并且将所有扩展名为.pkpass的文件添加到_passes数组中。
非常简单!你有了你应用中所有pass文件名的列表。接下来,将他们显示到表格中!
在ViewController.m中添加三个方法,来让TableView运行起来:
很简单的代码–已可能已经很多次用到它了。但是,
注意一下新的改变:你可以通过_passes.count这种形式来访问count方法(不是属性)得到数组中元素的总数。从数组(或字典中)中取出元素非常简单:
NSString*object=_passes[indexPath.row];
这些改变,像是通过.表示法来调用方法,在iOS6之前就有了,但他们仍然是新的。其他关于数组的表示法就是全新的了,你可以在第一章“What’sNewinObjective-C”中了解到。
这就足够了–你可以运行这个项目,并且没有任何警告和错误,并且在屏幕上显示一个空的TableView。
好了,是时候包含一些pass文件到这个应用中了。首先下载我为你准备好的:Passes.zip。解压这些文件,
将所有的.pkpass文件从Passes目录拷贝到你的Xcode项目根目录中。
注意:
确保这些文件添加到PassesPreviewtarget中。默认情况下,Xcode不会包含它们,因为他们不是代码文件,也不是其他已知的iOS资源文件。
注意:
当你设计你自己的pass时,不要选中“Copyitemsinto…”复选框。将.pkpass文件从Pass目录链接到Xcode项目中更加简单。当你更改代码或者替换图片后,然后重新构建pass并且重启Xcode项目,并且修改后的pass将会显示到屏幕上。
好了,现在你在应用中得到了一些pass,点击Run你将会看到pass的列表:
最终,你需要添加代码来在屏幕上显示选中的pass,将他们添加到ViewController.m中:
好了–代码稍微多了一点,但是很好理解:
首先,当表格的一行被选中后,你调用openPassWithName方法。
在openPassWithName中,你重新创建了.pkpass文件的完整路径。
然后你读取了.pkpass文件的内容,并放到一个NSData实例中。
然后你通过初始化方法initWithData:error:创建一个新的PKPass对象。
你通过error变量来检测一切的加载问题。
最后,你创建一个新的PKAddPassesViewController实例–这是一个特殊的视图控制器,接受一个PKPass对象作为参数,并显示它。将delegate属性赋值为self,并且模态的显示这个控制器到屏幕上。
你还需要一个方法–当用户关闭pass对话框时会被调用。(你在这里不会做太多特别的操作,但为了你以后开发更复杂的功能,你最好知道还有这么一个选择。)
添加PKAddPassesViewController代理协议必须的一个方法:
现在你可以再次运行项目,并且点击FreeHug.pkpass这行,非常酷!你可以预览这个pass,并且还可以将他们导入到你的iPhone模拟器总的Passbook应用中。
这和你在Mail应用中打开一个pass附件时显示的对话框是完全一样的。注意,如果你在Passbook中已经有了一个同样的pass,那么右上角的Add按钮将会被禁用。
成功了!
最后一步–在viewDidLoad的最后,添加如下代码:
如果你只有一个pass,这样可以省去你再多点击一下!
现在,现在你知道了关于如何创建一个优惠券的所有步骤,并且你知道了怎样简单的测试和预览你的pass。这些技能的组合可以到达我们的下一个主题:熟悉不同种类的pass。
这里有一个预览,当他们导入到Passbook中看起来是怎样的–你可以看到每个类型都有一个小的触摸区域:
怎么创建不同的pass呢?回到FreeHug优惠券的源代码中,并打开pass.json。在顶层的字典中,你添加了一个键叫做
“coupon”–这个键的值是一个包含字段定义的字典。所有的pass都以同样的方式工作–你仅需要做的是将这个key的名称从coupon修改为你想要的风格名称!
正如你看到的,这个文件的结构,和你之前的那个基本上是相同的,唯一不同的是这次用boardingPass替代了coupon键。还有另一个有趣的东西:在boardingPass字典中多了一个“transitType”。这个字段是boardingPass特有的,用来在pass的正面显示一个运送图标。
transitType,根据你正在创建的boardingPass的类型,你可以用这些预定义的常量之一:PKTransitTypeAir,PKTransitTypeTrain,PKTransitTypeBus,PKTransitTypeBoat,和PKTransitTypeGeneric。
这就是创建coupon和boardingpass的不同之处了!上面的源代码的结果就是这个漂亮的登机牌:
你能在这个登机牌上面找到Santa的饮食偏好吗?这样才能让服务员知道–他打算进行一个轻松的飞行!
登机牌样式的考虑
注意到主字段使用了一个非常大的字体,所以这里只能显示很少的文字。比较长的目的地名称,像是“SanFrancisco”,将会被截断,所以要考虑用目的地的代码来替代名称。最好是将城市的全名用作标签,将代码用作值。
登机牌不显示任何图片,所以只需要icon和logo图片文件。
一个好主意是,将头部字段用作机场登机口,站台或者座位号
确保你为你的登机牌用了正确的transittype!下面是不同类型显示出来的图标样式:
这里还有一个所有你可以用到的字段的预览(当然,你不需要用到所有的字段;这里给了你这些可用字段的样式和位置的预览):
当你设计新的pass的时候,有一个点重要的是你必须注意的:不同样式的条形码占据了pass的正面不同大小的区域。PDF417条形码是横向布局,所以它可以很好的放在卡片的底部–为pass的字段留下更多空间(就像上面的例子)。另外一方面QR条形码是正方形的,它在垂直区域占据更多的空间。看一下同样的pass使用了QR条形码之后,是什么样子:
你可以很明显的看到,字段之间的垂直距离变短了,这样条形码仍然能够放到卡片上;因此:总要将pass设计到正确类型的条形码上,这样你能够得到正确的字段布局。
注意:
如果你要重用任何这部分章节中例子中的代码,不要忘记修改team和passtype的标识–否则,你的pass将不能被导入到Passbook中。
正如你看到的,购物券的文件布局在某些方面和优惠券很像,但是header的样式是不同的。快速的看一下上面这个pass的源代码:
基本的东西,你已经知道并且喜欢的,都在这里,所以我不再赘述了。但是,在backFields字典中,还有一些东西值得讨论。在合同条款里面你有两个日期字段和一个文本字段,所有这三个字段都包含日期。这是一个好机会,可以用来将pass和iPhone上面的日历应用连接起来!按下右下角的“i”按钮,然后看一下:
Passbook自动检测日期,并把他们变成链接。当他们被点击时,会给用户展示一个动作菜单,可以将他们带入日历中的某一天,或者帮助他们在日历中为特定的一天或一个阶段创建一个事件。棒极了!
购物券样式考虑
通常,购物券中包含了客户在这个商店的余额。一个好主意是,将这些信息放到pass的主区域中。
Passbook还可以展示出不同样式的货币格式,所以如果你要显示余额,考虑一下将他们展示成用户自己的货币,像是这样:
Passbook甚至能够自动删除日元小数点之后的数字,因为日元不用小数!(1是可能的最小值)。
为了修改货币余额的样式,你需要一个数字值(不带双引号的数字)并且有另外的键用来定义使用什么货币。对日元来说,代码如下:
{
"key":"amount",
"label":"Currentcreditstore",
"value":45.20,
"currencyCode":"JPY"
}
最后,这里是购物券可以显示的所有字段类型:
回到PassPreview应用,选择ConcertTicket.pkpass。一个漂亮的门票展现出来:
正如你看到的,Santa没有很早的睡觉–它打算享受一下草裙舞表演和海边的夜晚。
当你提前计划好并将所有的门票放到口袋里非常容易–方便的存到你的iPhone里面吧!
活动门票有一些独特的特性。如果你提供了一个背景图片文件,它会拉伸,模糊,并设置成整张卡片的背景。如果你提供了一个预览图(thumbnail.png和thumbnail@2x.png),图片会显示在右边。
注意,因为背景图片会填满整个pass的正面,你不再需要在你的pass.json文件中指定“backgroundColor”属性了。
除了点比较特殊,其他的地方你都已经知道了:
看过pass.json中的一些不同之处以后,非常容易就能理解pass.json的源代码!再说一次,你可以用现在已知的任何方式来将信息包含在pass的正面和背面。
活动门票样式的考虑
如果你提供了一个背景图片,但没提供缩略图,那么Passbook将也会在右边缩略图的区域显示背景图片。
你可以禁用背景上的模糊效果–苹果用这种效果来突出文字信息。
对于像是会议这类的活动门票,pass正面缩略图的位置是放置参会者照片的好地方。
最终,这里是活动门票正面所有可用的字段区域。
最后一种类型的pass是通用pass。它有基本的样式,可以提供多种不同的文本域,可以在正面显示一张图片,并且,你可以用它来实现所有种类的pass,其他四种pass不能很好适应的–优惠券,登机牌,购物券,或者活动门票。
现在,我们发现Santa饮料的选择:它想在海边喝一杯凉的马提尼,享受吧,Santa!
打开PassPreview并点击GenericPass.pkpass:
正如你看到的,其他四种类型的样式都和这个不是很适应。它给持有者提供Maxi’sMartiniBar的VIP休息室和每天一杯的马提尼。它更像是酒吧的会员卡,没有已存在的预定义样式。
但是这个通用的pass看起来非常棒!是呀–你仍然机会去用我们已经讨论过的方式来自定义它!在pass.json中没有什么特别的,除了pass类型的键变成了generic:
等一下。。什么?(如果你没有发现任何问题,那么你可能要重新再看一下这个代码了?)
这个字段是干什么用的?
是的–是时候做一些技巧了!pass正面那些字段的位置是预定义的,所以,它应该看起来是这样的:第一个副标题显示在左边,第二个副标题显示在右边,第一个辅助标题显示,等等。
那么,如果你想在第二个副标题的位置显示一块文本,但是你不想在第一个副标题上显示任何信息呢?
哈哈!定义一个faux类型的副标题,并赋予空值并不带有任何label(像是上面的代码),非常棒!
另一个需要注意的地方是上面代码用到的“textAlignment”键。使用这个键,你可以告诉Passbook如何为一个文本域指定文字的对齐方式。你可以从以下预定义的常量中选择一个:PKTextAlignmentLeft,PKTextAlignmentCenter,PKTextAlignmentRight,PKTextAlignmentJustified,andPKTextAlignmentNatural。
这里是你可以在通用pass中用到的所有可用字段的预览:
好了!你基本完成了,我希望这次学习是有意义的!你知道了关于设计,制作和预览pass的一切信息。OK!你已经学习到所有东西了!
那么你应该知道如何构建一个pass包,如何给他们签名,如何通过邮件发送他们。我确信,你已经迫不及待的想要更深入的了解苹果这个最热门并且最新的技术了。
系好安全带–我们将继续上次没完成的部分!
关于pass更多的信息
pass有两面:在正面你可以在一些预定义的区域中添加文本信息;在背面,你可以尽可能的显示你想显示的信息。让我们先对正面进行一些维护。☺打开pass.json并找到
primaryFields数组的定义。在它的同一级上,在coupon字典中,你将会添加更多的段,来显示更多的信息。
你将添加另外的键到coupon字典上,你首先需要添加一个逗号,然后定义这个新键。当你将要在coupon字典添加另外一个键时,你需要首先添加一个逗号,然后再定义这个新键。在文件最后一个结尾方括号后面添加这个逗号(看看下面这张图片指出的位置)。
在逗号的下一行,将JSON代码粘贴过去:
现在除了primaryFields
字典,你有了secondaryFields和auxiliaryFields–
这些是pass的正面的一些附加字段。他们不像主字段那么重要,但仍然足够重要,所以要留在正面。
auxiliary字段可能会引起你特别的兴趣–它包含了一些你之前没有用到过的属性。这个字段,和你用到它其他字段不同,它是一个日期字段。Passbook会处理将日期/时间值转换成用户所在的本地化时间的工作,并将它格式化为本地化的文本显示。
看一下日期字段的属性:
value–
它是一个W3Cdatatime格式化后的值(关于它的文档,可以看一下这里
dateStyle–
用于格式化日期部分的风格;必须是这些其中之一:PKDateStyleNone,PKDateStyleShort,PKDateStyleMedium,PKDateStyleLongorPKDateStyleFull。
timeStyle–
和date字段的风格一样;使用同样的常量来定义时间的风格。
这就完成了!现在你可以进行另外一次构建,并且看一下pass这时候是什么样子了!你已经觉得很有趣了吧?
要执行的构建步骤:
确保JSON代码看起来没问题(否则,确保用
在终端里,进入你的工作目录,生成pass.json文件的SHA1校验和:
将pass.json的SHA1校验和放入manifest.json文件中。
为pass生成一个分离的签名:
opensslsmime-binary-sign-certfileWWDR.pem-signerpasscertificate.pem-inkeypasskey.pem-inmanifest.json-outsignature-outformDER-passinpass:12345 |
zip-rfreehugcoupon.pkpassmanifest.jsonpass.jsonsignaturelogo.pnglogo@2x.pngicon.pngicon@2x.pngstrip.pngstrip@2x.png |
任务完成了!你的pass应该看起来和下面的图片一样:
正面基本完成了,可以在背面做一些事情了!
打开pass.json并且在最后一个方括号后面添加一个逗号(现在你应该很熟练的能将逗号放在正确的位置上了)。
在逗号后面,为卡片的背面添加一个字段:
{
"key":"extras",
"label":"Extras",
"value":"Yourfriendsreceive50%offprice"
},
{
"key":"phone",
"label":"Formoreinfo",
"value":"800-1234567890"
},
{
"key":"terms",
"label":"TERMSANDCONDITIONS",
"value":"Freehugslast18secondsandmustbeclaimedonyourbirthday.Bringyourpassoranid"
}
]
幸运的是,pass的背面是可以滚动的,所以你可以添加更多你需要的信息。(是的,有时候合同条款会占据很长的空间,所以滚动是很必须的。)
现在–是时候看一下你刚刚添加的字段在pass上看起来是什么样的了。根据前面的说明再次构建,并且通过电子邮件将pass发送到你的设备上。按下“i”按钮,然后背面将会显示出来–它应该看起来和下面的图片一样:
目前还不错!再看看电话号码–它会自动被转换成链接,点击它你就可以直接拨打电话。你可以在背面添加其他一些交互信息–像是地址(将会在地图中打开)和电子邮箱(将会在Mail应用中打开)。
Pass预览应用
你可能已经感觉到了,如果构建和预览pass的过程能够更简单快速一点,那就更棒了。我的意思是,继续,我们一定要在每次想预览pass的时候,必须要用邮件发送给我们自己吗?
当然–好消息!因为我知道在你找到合适的pass之前,你将会尝试多种颜色的组合,图片和文字,在这部分章节中,你将会创建一个iOS应用,它可以让你更快速的在iPhone模拟器中预览你的pass。
注意:OS
X10.8.2现在支持直接在你的MAC上面预览pass。如果你双击.pkpass文件,你将会看到pass的外观。但是,检测pass是否有效的唯一一个方法是,在你的设备和模拟器上面打开它,并试着导入它。
还有一个方法可以将pass安装到Passbook中,我之前没有提到。除了将pass通过email发送,并直接在web服务器上下载它,你还可以使用iOS6中新的PassKitframework,来通过iOS应用来安装pass。
PassKit是一个非常简单的framework,它仅包含了3个类。为了创建一个简单的pass预览应用,你将会用到PKAddPassesViewController。这个类接受一个PKPass并将它显示到屏幕上。
在现实情况中,你的应用很可能从服务端抓取一个pass,或者从iClound中得到它,但在这个例子中,你仅用到在你应用本地包中的pass。
开始吧!
在Xcode的菜单中,选择File/New/Project…,然后选择iOS/Application/SingleViewApplication并且点击Next。将项目命名为“PassesPreview”,并确保它是一个iPhone应用。还要确保UseStoryboards和UseAutomaticReferenceCounting是选中的。将项目保存到你选定一个位置。
在ProjectNavigator中,选择Xcode项目(项目树中的第一个选项),并在右边的条目中,确保“PassesPreview”target是选中的。接下来点击BuildPhases选项卡,然后打开LinkBinaryWithLibraries条目。
点击(+)按钮,在frameworks的列表中双击“PassKit.framework”来将它包含到你的Xcode项目中(或者选择PassKit.framework然后点击(+)按钮)。
现在选择MainStoryboard.storyboard–应用的界面显示出来了。你需要一个全屏的表格,所以将一个TableView拖动到主界面中。
接下来,按住Ctrl并且将控制器对象拖动到下面的调色板中。一个弹出框将会显示出来。点击“dataSource”,然后重复这个操作,并且第二次的时候,选择“delegate”。这个表格现在正确的连接到你的视图控制器中了。
现在,完成一些Objective-C的东西!
打开ViewController.m并将它的内容替换成这样:
#import<PassKit/PassKit.h>//1
@interfaceViewController()//2
<UITableViewDelegate,UITableViewDataSource,
PKAddPassesViewControllerDelegate>
{
NSMutableArray*_passes;//3
}
@end
@implementationViewController
-(void)viewDidLoad
{
[superviewDidLoad];
//4
if(![PKPassLibraryisPassLibraryAvailable]){
[[[UIAlertViewalloc]initWithTitle:@"Error"
message:@"PassKitnotavailable"
delegate:nil
cancelButtonTitle:@"Pitty"
otherButtonTitles:nil]show];
return;
}
}
@end
这个代码非常基础并且只要4处需要解释的:
首先,你导入PassKitframework头文件。
在ViewController的类扩展中,你让它实现UITableView的数据源和代理协议,最后,还有一个PKAddPassesViewControllerDelegate协议。
你声明了一个数组实例变量来保存所有pass文件包的列表。
最终在viewDidLoad里面,如果[PKPassLibraryisPassLibraryAvailable]的结果是NO,那么你将显示一个消息,来让用户知道他们的Passbook不可用。(你不属于这种情况的用户,但这是一个好机会来向你展示如何检测Passbook的可用性,所以我把它放到了这里。)
我们的目标是检测这个app中是否带有pass包,如果有的话,显示他们的一个列表。当用户点击某个pass的文件名时,这个应用也会显示一个漂亮的预览视图。
在viewDidLoad的最后,添加如下代码:
|
首先初始化了一个_passes数组。
将应用所有资源文件的列表添加到passFiles数组中。
检测passFiles数组中所有的文件名,并且将所有扩展名为.pkpass的文件添加到_passes数组中。
非常简单!你有了你应用中所有pass文件名的列表。接下来,将他们显示到表格中!
在ViewController.m中添加三个方法,来让TableView运行起来:
-(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView { return1; } -(NSInteger)tableView:(UITableView*)tableViewnumberOfRowsInSection:(NSInteger)section { return_passes.count; } -(UITableViewCell*)tableView:(UITableView*)tableViewcellForRowAtIndexPath:(NSIndexPath*)indexPath { UITableViewCell*cell=[tableViewdequeueReusableCellWithIdentifier:@"Cell"]; if(!cell)cell=[[UITableViewCellalloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:@"Cell"]; NSString*object=_passes[indexPath.row]; cell.textLabel.text=object; returncell; } [/code] |
注意一下新的改变:你可以通过_passes.count这种形式来访问count方法(不是属性)得到数组中元素的总数。从数组(或字典中)中取出元素非常简单:
NSString*object=_passes[indexPath.row];
这些改变,像是通过.表示法来调用方法,在iOS6之前就有了,但他们仍然是新的。其他关于数组的表示法就是全新的了,你可以在第一章“What’sNewinObjective-C”中了解到。
这就足够了–你可以运行这个项目,并且没有任何警告和错误,并且在屏幕上显示一个空的TableView。
好了,是时候包含一些pass文件到这个应用中了。首先下载我为你准备好的:
将所有的.pkpass文件从Passes目录拷贝到你的Xcode项目根目录中。
注意:
确保这些文件添加到PassesPreviewtarget中。默认情况下,Xcode不会包含它们,因为他们不是代码文件,也不是其他已知的iOS资源文件。
注意:
当你设计你自己的pass时,不要选中“Copyitemsinto…”复选框。将.pkpass文件从Pass目录链接到Xcode项目中更加简单。当你更改代码或者替换图片后,然后重新构建pass并且重启Xcode项目,并且修改后的pass将会显示到屏幕上。
好了,现在你在应用中得到了一些pass,点击Run你将会看到pass的列表:
最终,你需要添加代码来在屏幕上显示选中的pass,将他们添加到ViewController.m中:
{//1 NSString*passName=_passes[indexPath.row]; [selfopenPassWithName:passName]; } -(void)openPassWithName:(NSString*)name { //2 NSString*passFile=[[[NSBundlemainBundle]resourcePath] stringByAppendingPathComponent:name]; //3 NSData*passData=[NSDatadataWithContentsOfFile:passFile]; //4 NSError*error=nil; PKPass*newPass=[[PKPassalloc]initWithData:passData error:&error]; //5 if(error!=nil){ [[[UIAlertViewalloc]initWithTitle:@"Passeserror" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"Ooops" otherButtonTitles:nil]show]; return; } //6 PKAddPassesViewController*addController= [[PKAddPassesViewControlleralloc]initWithPass:newPass]; addController.delegate=self; [selfpresentViewController:addController animated:YES completion:nil]; } [/code] |
首先,当表格的一行被选中后,你调用openPassWithName方法。
在openPassWithName中,你重新创建了.pkpass文件的完整路径。
然后你读取了.pkpass文件的内容,并放到一个NSData实例中。
然后你通过初始化方法initWithData:error:创建一个新的PKPass对象。
你通过error变量来检测一切的加载问题。
最后,你创建一个新的PKAddPassesViewController实例–这是一个特殊的视图控制器,接受一个PKPass对象作为参数,并显示它。将delegate属性赋值为self,并且模态的显示这个控制器到屏幕上。
你还需要一个方法–当用户关闭pass对话框时会被调用。(你在这里不会做太多特别的操作,但为了你以后开发更复杂的功能,你最好知道还有这么一个选择。)
添加PKAddPassesViewController代理协议必须的一个方法:
-(void)addPassesViewControllerDidFinish:(PKAddPassesViewController*)controller { //passadded [selfdismissViewControllerAnimated:YEScompletion:nil]; } [/code] |
这和你在Mail应用中打开一个pass附件时显示的对话框是完全一样的。注意,如果你在Passbook中已经有了一个同样的pass,那么右上角的Add按钮将会被禁用。
成功了!
最后一步–在viewDidLoad的最后,添加如下代码:
|
现在,现在你知道了关于如何创建一个优惠券的所有步骤,并且你知道了怎样简单的测试和预览你的pass。这些技能的组合可以到达我们的下一个主题:熟悉不同种类的pass。
pass的风格详解…
接下来,你将会看到关于不同风格pass的详细讲解。这里有一个预览,当他们导入到Passbook中看起来是怎样的–你可以看到每个类型都有一个小的触摸区域:
怎么创建不同的pass呢?回到FreeHug优惠券的源代码中,并打开pass.json。在顶层的字典中,你添加了一个键叫做
“coupon”–这个键的值是一个包含字段定义的字典。所有的pass都以同样的方式工作–你仅需要做的是将这个key的名称从coupon修改为你想要的风格名称!
Santa应得的假期旅行
为了让这个部分的例子更加有趣,VickiWenderlich计划了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":"ReindeerAirwaysLLC", "description":"TrainBoardingPass", "logoText":"ReindeerAirways", "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":"Ticketisnon-refundable.Pleasespecifywhichtypeofcookieyouwantuponcheck-in:chocolatechip,peanutbutter,orM&Msugarcookie." } ], "transitType":"PKTransitTypeAir" } } [/code] |
transitType,根据你正在创建的boardingPass的类型,你可以用这些预定义的常量之一:PKTransitTypeAir,PKTransitTypeTrain,PKTransitTypeBus,PKTransitTypeBoat,和PKTransitTypeGeneric。
这就是创建coupon和boardingpass的不同之处了!上面的源代码的结果就是这个漂亮的登机牌:
你能在这个登机牌上面找到Santa的饮食偏好吗?这样才能让服务员知道–他打算进行一个轻松的飞行!
登机牌样式的考虑
注意到主字段使用了一个非常大的字体,所以这里只能显示很少的文字。比较长的目的地名称,像是“SanFrancisco”,将会被截断,所以要考虑用目的地的代码来替代名称。最好是将城市的全名用作标签,将代码用作值。
登机牌不显示任何图片,所以只需要icon和logo图片文件。
一个好主意是,将头部字段用作机场登机口,站台或者座位号
确保你为你的登机牌用了正确的transittype!下面是不同类型显示出来的图标样式:
这里还有一个所有你可以用到的字段的预览(当然,你不需要用到所有的字段;这里给了你这些可用字段的样式和位置的预览):
当你设计新的pass的时候,有一个点重要的是你必须注意的:不同样式的条形码占据了pass的正面不同大小的区域。PDF417条形码是横向布局,所以它可以很好的放在卡片的底部–为pass的字段留下更多空间(就像上面的例子)。另外一方面QR条形码是正方形的,它在垂直区域占据更多的空间。看一下同样的pass使用了QR条形码之后,是什么样子:
你可以很明显的看到,字段之间的垂直距离变短了,这样条形码仍然能够放到卡片上;因此:总要将pass设计到正确类型的条形码上,这样你能够得到正确的字段布局。
注意:
如果你要重用任何这部分章节中例子中的代码,不要忘记修改team和passtype的标识–否则,你的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":"TahitiSurf&Snorkel", "description":"DivingLessons", "logoText":"TahitiSurf&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":"Validfrom:", "dateStyle":"PKDateStyleMedium", "timeStyle":"PKDateStyleNone", "value":"2013-01-01T00:00Z" }, { "key":"date", "label":"Validuntil:", "dateStyle":"PKDateStyleMedium", "timeStyle":"PKDateStyleNone", "value":"2013-01-03T00:00Z" }, { "key":"terms", "label":"TERMSANDCONDITIONS", "value":"Lessonsmustbeusedbetween1/1/2013and3/1/2013.Appointmentsforlessonsmustbemadenolessthan48hoursinadvance.Customermustbeabletoswim." } ] } } [/code] |
Passbook自动检测日期,并把他们变成链接。当他们被点击时,会给用户展示一个动作菜单,可以将他们带入日历中的某一天,或者帮助他们在日历中为特定的一天或一个阶段创建一个事件。棒极了!
购物券样式考虑
通常,购物券中包含了客户在这个商店的余额。一个好主意是,将这些信息放到pass的主区域中。
Passbook还可以展示出不同样式的货币格式,所以如果你要显示余额,考虑一下将他们展示成用户自己的货币,像是这样:
Passbook甚至能够自动删除日元小数点之后的数字,因为日元不用小数!(1是可能的最小值)。
为了修改货币余额的样式,你需要一个数字值(不带双引号的数字)并且有另外的键用来定义使用什么货币。对日元来说,代码如下:
"key":"amount",
"label":"Currentcreditstore",
"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":"TahitiBeachHulaShow", "description":"EntrancetickettoTahitiBeachHulaShow", "logoText":"TahitiBeachHulaShow", "foregroundColor":"rgb(255,255,255)", "backgroundColor":"rgb(242,121,55)", "eventTicket":{ "primaryFields":[ { "key":"name", "value":"TahitiBeachHula" } ], "secondaryFields":[ { "key":"location", "label":"Location", "value":"NexttoMaxi'sMartiniBar" } ], "auxiliaryFields":[ { "key":"date", "label":"Eventdate", "dateStyle":"PKDateStyleMedium", "timeStyle":"PKDateStyleMedium", "value":"2012-12-29T19:00Z" } ], "backFields":[ { "key":"terms", "label":"Terms&conditions", "value":"Thisticketmaycausehappinessandgoodcheer!Freeleiwithticket." } ] } } [/code] |
活动门票样式的考虑
如果你提供了一个背景图片,但没提供缩略图,那么Passbook将也会在右边缩略图的区域显示背景图片。
你可以禁用背景上的模糊效果–苹果用这种效果来突出文字信息。
对于像是会议这类的活动门票,pass正面缩略图的位置是放置参会者照片的好地方。
最终,这里是活动门票正面所有可用的字段区域。
你一直都需要的pass!
最后,我们得到了你一直需要的pass,或者说是创建。或者说是创建和得到。最后一种类型的pass是通用pass。它有基本的样式,可以提供多种不同的文本域,可以在正面显示一张图片,并且,你可以用它来实现所有种类的pass,其他四种pass不能很好适应的–优惠券,登机牌,购物券,或者活动门票。
现在,我们发现Santa饮料的选择:它想在海边喝一杯凉的马提尼,享受吧,Santa!
打开PassPreview并点击GenericPass.pkpass:
正如你看到的,其他四种类型的样式都和这个不是很适应。它给持有者提供Maxi’sMartiniBar的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'sMartiniBar", "description":"GenericPassExample", "logoText":"Maxi'sMartiniBar", "foregroundColor":"rgb(33,33,33)", "backgroundColor":"rgb(122,230,88)", "generic":{ "headerFields":[ { "key":"header", "value":"VIP" } ], "primaryFields":[ { "key":"member", "value":"SantaClaus" } ], "secondaryFields":[ { "key":"faux1", "value":"" }, { "key":"secondary1", "label":"RewardsEarned", "value":"FreeSpecialtyMartini", "textAlignment":"PKTextAlignmentRight" } ], "auxiliaryFields":[ { "key":"faux2", "value":"" }, { "key":"status", "value":"Level3", "label":"MembershipStatus", "textAlignment":"PKTextAlignmentRight" } ], "backFields":[ { "label":"terms&conditions", "key":"terms", "value":"MustshowproofofIDtoclaimrewards." } ] } } [/code] |
这个字段是干什么用的?
|
那么,如果你想在第二个副标题的位置显示一块文本,但是你不想在第一个副标题上显示任何信息呢?
哈哈!定义一个faux类型的副标题,并赋予空值并不带有任何label(像是上面的代码),非常棒!
另一个需要注意的地方是上面代码用到的“textAlignment”键。使用这个键,你可以告诉Passbook如何为一个文本域指定文字的对齐方式。你可以从以下预定义的常量中选择一个:PKTextAlignmentLeft,PKTextAlignmentCenter,PKTextAlignmentRight,PKTextAlignmentJustified,andPKTextAlignmentNatural。
这里是你可以在通用pass中用到的所有可用字段的预览:
好了!你基本完成了,我希望这次学习是有意义的!你知道了关于设计,制作和预览pass的一切信息。OK!你已经学习到所有东西了!
相关文章推荐
- 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介绍(续)