1.创建action extension和相关参数设置

2.创建出ActionExtension工程后,Xcode目录下会生成对应ActionViewController文件。

3.客户端对其他APP跳转过来的解析,都在ActionViewController内操作。
if ([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage]) { }
示例代码中的内容,可用改成自己使用的数据类型。

4.设置action的Bundle ID
将这个target的General > Bundle identifier 名称改为:com.XXXX.XXXXAction, 其中com.XXXX为App的bundle ID.
5.配置Action Extension
默认Action Extension中的布局使用StoryBoard,如果不想使用StoryBoard布局将Info.plist中的如下配置:
<key>NSExtensionMainStoryboard</key> <string>MainInterface</string>
改为:
<key>NSExtensionPrincipalClass</key>
<string>ActionViewController</string>
NSExtensionActivationRule定义了当前的扩展支持的数据类型及数据项个数,例如设置只支持图片格式和视频格式的数据,并且最多不超过10张图片和1个视频。
<key>NSExtensionActivationSupportsWebPageWithMaxCount</key>
<string>1</string>
NSExtensionJavaScriptPreprocessingFile用于配置与脚本交互的JS脚本文件的名字。为了告知Safari你的应用扩展中包含一个JavaScript文件,你需要在应用扩展的Info.plist文件中,向NSExtensionAttributes字典添加NSExtensionJavaScriptPreprocessingFile关键字来指明你的JavaScript文件。这个关键字的值就是你希望当你的应用扩展运行前,Safari要加载的JavaScript文件的名称。
<key>NSExtensionJavaScriptPreprocessingFile</key>
<string>ScreenShotJavaScript</string>
NSExtensionPointIdentifier用于表示扩展点,每一个扩展点拥有一个唯一的名字。
<key>NSExtensionPointIdentifier</key>
<string>com.apple.ui-services</string>
若提示下面的错误:
connection failed with error : Error Domain=NSURLErrorDomain
Code=-1022 “The resource could not be loaded because the App Transport
Security policy requires the use of a secure connection.”
UserInfo={NSUnderlyingError=0x7ffa0e0103c0 {Error
Domain=kCFErrorDomainCFNetwork Code=-1022 “The resource could not be
loaded because the App Transport Security policy requires the use of a
secure connection.”
原因是iOS9引入了新特性 App Transport Security (ATS)
官方的说明是:
App Transport Security (ATS) enforces best practices in the secure
connections between an app and its back end. ATS prevents accidental
disclosure, provides secure default behavior, and is easy to adopt; it
is also on by default in iOS 9 and OS X v10.11. You should adopt ATS
as soon as possible, regardless of whether you’re creating a new app
or updating an existing one.
新特性要求App内访问的网络必须使用HTTPS协议。但是现在公司的项目使用的是HTTP协议,使用私有加密方式保证数据安全。现在也不能马上改成HTTPS协议传输。
解决方法是:
在Info.plist中添加NSAppTransportSecurity类型Dictionary。
在NSAppTransportSecurity下添加NSAllowsArbitraryLoads类型Boolean,值设为YES。
此方法虽然解决了网络访问的问题,但是苹果提供的安全保障也被关闭了。
还有一种方法是设置部分访问的域为HTTP,其余HTTPS:
1) 左键Info.plist选择open with source code
2) 然后添加类似如下的配置:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>qq.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
<key>sina.com.cn</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
5.跳转containing APP
苹果虽然在App Extension Programming Guide 中提到可以用openURL:completionHandle:方法跳转containing app,但在iOS9(or 更早?)发现用这个方法跳转只有today widget能成功:
[[self extensionContext]openURL:[NSURL URLWithString:urlString] completionHandler:^(BOOL success) {}];
然而苹果说不希望actions变成app的入口:
Each extension point determines whether to support this method, or under which conditions to support this method. In iOS 8.0, only the Today extension point supports this method。
于是Action和Share extension都无法用openURL打开containing app。
解决方法:
NSURL *destinationURL = [NSURL URLWithString:urlString];
// Get "UIApplication" class name through ASCII Character codes.
NSString *className = [[NSString alloc] initWithData:[NSData dataWithBytes:(unsigned char []){0x55, 0x49, 0x41, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E} length:13] encoding:NSASCIIStringEncoding];
if (NSClassFromString(className))
{
id object = [NSClassFromString(className) performSelector:@selector(sharedApplication)];
[object performSelector:@selector(openURL:) withObject:destinationURL];
}
6.限定使用场景
在你的分享或Action扩展中,在它们的工作中可能会使用到一些数据,并且这些数据的类型各不相同。为了确保只有当用户在主叫应用中选择了你的扩展支持的数据类型时,才会展示你的扩展功能。你需要在扩展的属性列表文件中添加 NSExtensionActivationRule 关键字。你也可以使用该关键字指定扩展处理每种类型的最大数目。当你的应用扩展运行时,系统会用改关键字的值与扩展数据项的attachments属性值作比较。关于 NSExtensionActivationRule 关键字的详细信息可以参阅 Action Extension Keys 文档中的 Information Property List Key Reference 章节。
在调试阶段,设置NSExtensionActivationRule类型为string,值为TRUEPREDICATE ,使本extension在任何条件都会出现。
但在提交App store前要确保所有的 TRUEPREDICATE 常量已经替换为指定的断言语句或 NSExtensionActivationRule 关键字,.否则会被拒绝。
常见的设置,请见Apple.
网友评论