-- iOS8与OS X v1010应用扩展编程指南.pdf

上传人:asd****56 文档编号:70332439 上传时间:2023-01-19 格式:PDF 页数:8 大小:582.95KB
返回 下载 相关 举报
-- iOS8与OS X v1010应用扩展编程指南.pdf_第1页
第1页 / 共8页
-- iOS8与OS X v1010应用扩展编程指南.pdf_第2页
第2页 / 共8页
点击查看更多>>
资源描述

《-- iOS8与OS X v1010应用扩展编程指南.pdf》由会员分享,可在线阅读,更多相关《-- iOS8与OS X v1010应用扩展编程指南.pdf(8页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、常见问题的处理方案-iOS8/OS X v10.10应用扩展编程指南当你在开发一个应用扩展,让其执行某个任务时,你可能会遇到一些常见的,或者说在多种扩展中都会出现的通用的问题,并且必须要处理这些问题。在这一章节中,我们将帮助你如何应对和处理这些常见的问题。使用内嵌框架共享代码你可以创建一个内嵌框架,用于在应用扩展和它的载体应用之间共享代码。比如,你开发了一个图片滤镜的照片编辑扩展,同时该扩展的载体应用也有这个功能,那么你就可以将实现该功能的代码封装成一个框架,让扩展t a r g e t和载体应用t a r g e t都使用这个框架。你要确保你创建的内嵌框架不包含应用扩展不能使用的API。这类

2、API一般使用u n a v a i l a b i l i t y宏来标记,比如像N S _ E X T E N S I O N _ U N A V A I L A B L E。如果你创建的内嵌框架中包含应用扩展不能使用的API,那么你将其Link到载体应用没关系,载体应用可以正常使用框架中的API,但是不能与应用扩展共享代码,也就是应用扩展不能使用该框架提供的所有API,继而无法做到代码共享。如果你上传App Store的应用扩展中有这种框架,或者应用扩展中使用了不允许使用的API,那么审核时会被拒绝。如果我们要想应用扩展使用内嵌框架,那么首先要配置一下。将t a r g e t的R e

3、q u i r e O n l y A p p-E x t e n s i o n-S a f e A P I选项设置为Y e s。如果你不这样设置,那么Xcode会向你提示警告:l i n k i n g a g a i n s t d y l i b n o t s a f e f o r u s e i n a p p l i c a t i o n e x t e n s i o n s。重要提示:如果载体应用要使用内嵌框架,那么必须要支持a r m 6 4架构,否则在上传App Store时会被拒绝。(如“创建应用扩展”章节中介绍的,所有应用扩展都要支持a r m 6 4架构。)在配

4、置你的Xcode项目时,在B u i l d P h a s e s选项卡的C o p y F i l e s项中一定要将D e s t i n a t i o n设置为F r a m e w o r k s。重要提示:我们要始终将D e s t i n a t i o n设置为F r a m e w o r k s,如果你将其设置为S h a r e d F r a m e w o r k,那么上传App Store时会被拒绝的。你可以让载体应用支持iOS7或更早的版本,但当在iOS8或更新的版本中运行时,要特别注意内嵌框架的安全性。详细内容可以参阅Deploying a Containin

5、g App to Older Versions of iOS。有关创建和使用内嵌框架的更多内容,请观看WWDC 2014的视频“Building Modern Frameworks”。与载体应用共享数据虽然应用扩展的包内嵌在载体应用中,但是应用扩展和载体应用的安全域还是不一样的。默认情况下,应用扩展和载体应用是不能直接访问对方内容的。不过你可以通过数据共享来实现这个愿望。比如,你希望应用扩展和它的载体应用共享一个单一的大数据集。比如p r e r e n d e r e d a s s e t s。要实现数据共享,我们要使用Xcode或者开发者门户网站允许应用扩展和它的载体应用成为一个应用组,

6、然后在开发者门户网站中注册应用组,并指明在载体应用中使用该应用组。关于应用组的知识请查阅Entitlement Key Reference文档的Adding an App to an App Group章节。当你设置好应用组后,应用扩展和它的载体应用就可以通过NSUserDefaultsAPI共享访问用户的信息。我们可以使用initWithSuiteName:方法实例化一个N S U s e r D e f a u l t s对象,然后传入共享组的标示符。比如一个共享扩展,它或许会更新用户最近经常使用的共享账号,那么我们可以这样来写:%highlight swift%/Create and s

7、hare access to an NSUserDefaults object.NSUserDefaults*mySharedDefaults=NSUserDefaults alloc initWithSuiteName:com.example.domain.MyShareExtension;/Use the shared user defaults object to update the users account.mySharedDefaultssetObject:theAccountName forKey:lastAccountName;%endhighlight%下图向我们展示了应用

8、扩展和它的载体应用是如何通过共享容器实现数据共享的:重要提示:如果你的应用扩展使用NSURLSession类执行后台的上传下载任务时,你必须要设置一个共享容器。这样扩展和载体应用就可以访问到转换传输的数据。后台上传下载的更多知识请参阅 Performing Uploads and Downloads。如果你设置了共享容器,那么载体应用和它包含的扩展就可以对共享容器里的内容进行读写操作了。同时你还必须要对数据的操作进行同步,以避免数据损坏或出错。使用UIDocument类、Core Data或者SQLite可以帮助定位、协调操作共享容器中的内容。访问网页在分享扩展(iOS与OS X平台)和Act

9、ion扩展(iOS平台)中,一般都允许用户使用Safari浏览器执访问网页并通过执行JavaScript脚本将结果返回到扩展中。你也可以在你的扩展运行之前或执行完任务之后通过JavaScript文件修改网页内容。比如分享扩展,它可以帮助用户将网页上的内容分享到用户的社交网站上,或者iOS上的Action扩展可能会显示当前网页的指定翻译内容。如果要通过应用扩展访问网页并操作网页内容,那么需要遵循下面几个步骤:创建一个JavaScript文件,并申明一个全局对象,名为E x t e n s i o n P r e p r o c e s s i n g J S并将其实例化。在应用扩展的属性列表文件

10、中添加关键字N S E x t e n s i o n J a v a S c r i p t P r e p r o c e s s i n g F i l e,给Safari浏览器指明使用哪个JavaScript文件。在N S E x t e n s i o n A c t i v a t i o n R u l e字典中,将N S E x t e n s i o n A c t i v a t i o n S u p p o r t s W e b U R L W i t h M a x C o u n t赋值一个非零的值。(更多关于N S E x t e n s i o n A c t

11、 i v a t i o n R u l e字典的知识请参阅DeclaringSupported Data Types for a Share or Action Extension。)当你的应用扩展开始运行时,使用NSItemProvider类从JavaScript文件的返回值中获取结果。在iOS系统的应用扩展中,如果你希望当应用扩展执行完任务后实时更新网页内容,那么你要向JavaScript文件中传入内容。(在这一步中也使用N S I t e m P r o v i d e r类。)为了告知Safari你的应用扩展中包含一个JavaScript文件,你需要在应用扩展的I n f o.p l

12、 i s t文件中,向N S E x t e n s i o n A t t r i b u t e s字典添加N S E x t e n s i o n J a v a S c r i p t P r e p r o c e s s i n g F i l e关键字来指明你的JavaScript文件。这个关键字的值就是你希望当你的应用扩展运行前,Safari要加载的JavaScript文件的名称。比如:N S E x t e n s i o n A t t r i b u t e s N S E x t e n s i o n J a v a S c r i p t P r e p r o

13、c e s s i n g F i l e M y J a v a S c r i p t F i l e 在iOS和OS X平台中,在你自定义的JavaScript类中可以定义一个r u n()函数,该函数就是Safari加载JavaScript文件的入口。在r u n()函数中,Safari提供了一个名为c o m p l e t i o n F u n c t i o n的参数,你可以使用键值对象的形式将结果传给应用扩展。在iOS平台中,你还可以定义一个f i n a l i z e()函数,当应用扩展在任务结束阶段调用c o m p l e t e R e q u e s t R e

14、t u r n i n g I t e m s:e x p i r a t i o n H a n d l e r:c o m p l e t i o n:方法时Safari会调用f i n a l i z e()函数。在该函数中,可以通过向c o m p l e t e R e q u e s t R e t u r n i n g I t e m s:e x p i r a t i o n H a n d l e r:c o m p l e t i o n:方法传值,来改变网页内容。比如,你的iOS应用扩展需要基于一个网页URI启动,并且当它结束运行时改变网页的背景色,那么你需要这样写Ja

15、vaScript代码:%highlight javascript%var MyExtensionJavaScriptClass=function();MyExtensionJavaScriptClass.prototype=run:function(arguments)/Pass the baseURI of thewebpage to the pletionFunction(baseURI:document.baseURI);,/N o t e t h a t t h e f i n a l i z e f u n c t i o n i s o n l y a v a i l a b l

16、e i n i O S.f i n a l i z e:f u n c t i o n(a r g u m e n t s)/a r g u m e n t s c o n t a i n s t h e v a l u e t h e e x t e n s i o n p r o v i d e s i n N S E x t e n s i o n C o n t e x t c o m p l e t e R e q u e s t R e t u r n i n g I t e m s:e x p i r a t i o n H a n d l e r:c o m p l e t i

17、 o n:./I n t h i s e x a m p l e,t h e e x t e n s i o n p r o v i d e s a c o l o r a s a r e t u r n i n g i t e m.d o c u m e n t.b o d y.s t y l e.b a c k g r o u n d C o l o r =a r g u m e n t s b g C o l o r ;/The JavaScript file must contain a global object named ExtensionPreprocessingJS.varE

18、xtensionPreprocessingJS=new MyExtensionJavaScriptClass;%endhighlight%在iOS和OS X平台中,你需要编写代码来处理f u n()函数返回的值,为获取到字典中的值,我们需要指定k U T T y p e P r o p e r t y L i s t类型作为标示符传入N S I t e m P r o v i d e r类的loadItemForTypeIdentifier:options:completionHandler:方法。在该字典中使用N S E x t e n s i o n J a v a S c r i p t

19、 P r e p r o c e s s i n g R e s u l t s K e y作为k e y来取值。比如下面例子中我们想要获取将URI传入r u n()的返回值:%highlight swift%imageProvider loadItemForTypeIdentifier:kUTTypePropertyList options:nilcompletionHandler:(NSDictionary*item,NSError*error)NSDictionary*results=(NSDictionary*)item;NSString*baseURI=results objectF

20、orKey:NSExtensionJavaScriptPreprocessingResultsKeyobjectForKey:baseURI;%endhighlight%f i n a l i z e()函数是在当应用扩展执行完任务后传参并调用的,创建一个含有我们需要处理的值的字典,然后用N S I t e m P r o v i d e r的i n i t W i t h I t e m:t y p e I d e n t i f i e r:方法来封装该字典。比如当扩展执行完任务后我们想让网页变为红色,我们可以这样写:%highlight swift%NSExtensionItem*ext

21、ensionItem=NSExtensionItem alloc init;extensionItem.attachments=NSItemProvider alloc initWithItem:NSExtensionJavaScriptFinalizeArgumentKey:bgColor:red typeIdentifier:(NSString*)kUTTypePropertyList;self extensionContextcompleteRequestReturningItems:extensionItem expirationHandler:nil completion:nil;%

22、endhighlight%执行上传下载任务用户一般的操作习惯都倾向于当使用你的应用扩展完成某个任务后,可以将结果立即反馈在使用扩展的应用中。如果一个扩展要处理的任务包含较长时间的上传下载操作时,你要确保当你的应用扩展关闭后能继续完成该任务。为实现这个功能,我们需要使用NSURLSession类创建一个URL会话并创建后台的上传下载任务。提示:你可以回想一下其他类型的后台任务,比如后台支持VoIP、后台播放音乐,这些是不能用应用扩展去实现的。更多信息请参阅Respond to the Host Apps Request。当你的应用扩展准备好上传下载任务后,扩展会完成调用它的应用发出的请求,并在不

23、影响上传下载任务的前提下终止扩展。更多关于扩展处理主叫应用请求的知识请参阅Respond to the Host AppsRequest。在iOS系统中,如果你的应用扩展在执行完后台任务时并没有在运行,那么系统会自动在后台运行扩展的载体应用,并调用application:handleEventsForBackgroundURLSession:completionHandler:代理方法。重要提示:如果你的应用扩展在后台创建了NSURLSession任务,那么你必须要设置一个共享容器,以确保扩展和载体应用实现数据共享。我们可以在N S U R L S e s s i o n C o n f i

24、g u r a t i o n类中使用sharedContainerIdentifier属性来指定一个共享容器的标示符,然后我们就可以通过该标示符获取到共享容器。请参阅Sharing Data with Your Containing App文档来设置共享容器。下面的例子展示了如何配置一个URL会话,并创建一个下载任务:%highlight swift%NSURLSession*mySession=self configureMySession;NSURL*url=NSURLURLWithString:http:/ downloadTaskWithURL:url;myTask resume;(

25、NSURLSession)configureMySession if(!mySession)NSURLSessionConfiguration config=NSURLSessionConfigurationbackgroundSessionConfigurationWithIdentifier:“com.mycompany.myapp.backgroundsession”;/To access the shared container you set up,use the sharedContainerIdentifier property onyour configuration obje

26、ct.config.sharedContainerIdentifier=“com.mycompany.myappgroupidentifier”;mySession=NSURLSessionsessionWithConfiguration:config delegate:self delegateQueue:nil;return mySession;%endhighlight%因为在单位时间内只能由一个进程使用后台会话,所以你需要为载体应用中的所有扩展创建不同的后台会话(每个后台会话都要有一个唯一的标示符)。在这里我们建议当载体应用在后台处理扩展的任务时,只使用一个该扩展创建的后台会话。如果你

27、要执行其他的网络相关的任务,那么就要创建相应的URL会话。如果你需要在后台创建URL会话之前完成主叫应用的请求,那么要确保创建和使用会话的代码是有效可执行的。当你的扩展调用completeRequestReturningItems:completionHandler:方法告知主叫应用已经完成相关请求后,系统就可以随时终止你的应用扩展。为分享和Action扩展申明支持的数据类型在你的分享或Action扩展中,在它们的工作中可能会使用到一些数据,并且这些数据的类型各不相同。为了确保只有当用户在主叫应用中选择了你的扩展支持的数据类型时,才会展示你的扩展功能。你需要在扩展的属性列表文件中添加N S E

28、 x t e n s i o n A c t i v a t i o n R u l e关键字。你也可以使用该关键字指定扩展处理每种类型的最大数目。当你的应用扩展运行时,系统会用改关键字的值与扩展数据项的attachments属性值作比较。关于N S E x t e n s i o n A c t i v a t i o n R u l e关键字的详细信息可以参阅Action Extension Keys文档中的Information Property List Key Reference章节。比如,你可以申明你的分享扩展支持最大处理10张图片,一部影片和一个网站URL。你可以参考下面的写法:

29、N S E x t e n s i o n A t t r i b u t e s N S E x t e n s i o n A c t i v a t i o n R u l e N S E x t e n s i o n A c t i v a t i o n S u p p o r t s I m a g e W i t h M a x C o u n t 1 0 N S E x t e n s i o n A c t i v a t i o n S u p p o r t s M o v i e W i t h M a x C o u n t 1 N S E x t e n s i

30、o n A c t i v a t i o n S u p p o r t s W e b U R L W i t h M a x C o u n t 1 如果你想指定不支持的数据类型,那么你可以将该类型的值设置为0,或者在N S E x t e n s i o n A c t i v a t i o n R u l e中不添加该类型即可。提示:如果你的分享扩展或iOS中的Action扩展需要访问网页,那你必须要确保N S E x t e n s i o n A c t i v a t i o n S u p p o r t s W e b U R L W i t h M a x C o u

31、n t关键字的值不为0(更多关于在应用扩展中通过JavaScript访问网页的内容请参阅Accessing a Webpage)。你也可以使用NSExtensionItem定义的UTI子类型以便数据检测器检测文本信息,比如电话号码或通讯地址。N S E x t e n s i o n A c t i v a t i o n R u l e字典中的关键字足以满足大多数应用的过滤需求。如果你需要做更复杂的过滤,比如像p u b l i c.u r l和p u b l i c.i m a g e之间的区别,那么你就得在文本中创建断言语句。如果你要创建一个断言,那么就将N S E x t e n s

32、i o n A c t i v a t i o n R u l e关键字的值设置为你指定的断言字符串。(在运行时,系统会自动将该字符串编译为NSPredicate对象)比如,一个应用扩展的附件属性可以指定为PDF文件,可以这样写:e x t e n s i o n I t e m s =(a t t a c h m e n t s =(r e g i s t e r e d T y p e I d e n t i f i e r s =(c o m.a d o b e.p d f ,p u b l i c.f i l e-u r l ););)为了指定你的应用扩展可以处理PDF文件,你可以像这

33、样创建断言字符串:S U B Q U E R Y(e x t e n s i o n I t e m s,$e x t e n s i o n I t e m,S U B Q U E R Y($e x t e n s i o n I t e m.a t t a c h m e n t s,$a t t a c h m e n t,A N Y$a t t a c h m e n t.r e g i s t e r e d T y p e I d e n t i f i e r s U T I-C O N F O R M S-T O c o m.a d o b e.p d f ).c o u n

34、t =1).c o u n t =1开发过程中,在你创建断言语句之前你可以使用T R U E P R E D I C A T E常量(结果为t r u e)测试你的代码路径。更多断言语句的语法知识请参阅Predicate Format String Syntax。重要提示:在将你的载体应用上传App Store之前,要确保所有的T R U E P R E D I C A T E常量已经替换为指定的断言语句或N S E x t e n s i o n A c t i v a t i o n R u l e关键字,不然载体应用会被App Store拒绝。配置载体应用以适用于老版本的iOS系统如果你

35、在载体应用中使用了内嵌框架,那么它就可以在iOS8.0之后的版本中使用,即便内嵌框架不支持老版本的系统也没关系。使载体应用能做到上述这一点的是dlopen命令,它可以使你使用条件链接和加载框架包的机制。你可以使用这个命令来代替编译时链接,你可以在Xcode的General 选项或Build Phases选项中对该命令进行编辑。其原理就是只有当载体应用在iOS8.0或更高的版本中运行时,才会链接使用内嵌框架。重要提示:如果你的载体应用使用了内嵌框架,那么就必须要支持a r m 6 4架构,否则会被AppStore拒绝。设置Xcode项目中应用扩展的条件链接1.将每一个应用扩展的运行系统版本设置为

36、iOS8.0或更高,通常选中Xcode中的t a r g e t,在G e n e r a l选项中设置D e p l o y m e n t i n f o。2.将你载体应用的运行系统版本设置为你想支持的最低iOS版本。3.在你的载体应用中,通过systemVersion方法,在运行时检查判断iOS的版本,并判断是否执行d l o p e n命令。只有你的载体应用在iOS8.0或更高的版本中运行时才会指定d l o p e n命令。特定的iOS API通过d l o p e n命令使用内嵌框架。你必须选择性的使用这些API,就像使用d l o p e n命令时那样。这些API都是CFBundleRef的封装类型:CFBundleGetFunctionPointerForNameCFBundleGetFunctionPointersforNames还有来自NSBundle类的方法:loadloadAndReturnError:classNamed:因为你一般会将载体应用的运行系统版本配置为较低的版本,所以这些API通常都是在运行时检查,只有确保载体应用在iOS8.0或更高版本中运行时才会使用这些API。更多内容请关注微信号:DevTalking或访问Dev Talking 程序员说()了解更多IT咨询

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁