ios 跨软件传输数据之Share Extension容器程序数
2019-05-06 本文已影响0人
大大的西瓜灬
容器程序获取分享数据
插件的工作基本上已经全部开发完成了,接下来就是容器程序获取数据并进行操作。下面是容器程序的处理代码:
- (void)applicationDidBecomeActive:(UIApplication *)application
{ //获取共享的UserDefaults
NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.cn.vimfung.ShareExtensionDemo"]; if ([userDefaults boolForKey:@"has-new-share"])
{
NSLog(@"新的分享 : %@", [userDefaults valueForKey:@"share-url"]); //重置分享标识
[userDefaults setBool:NO forKey:@"has-new-share"];
}
}
为了方便演示,这里直接在AppDelegate中的applicationDidBecomeActive:方法中检测是否有新的分享,如果有则通过Log打印链接出来。
至此,整个Share Extension开发的过程已经完成。
提审AppStore的注意事项
- 扩展中的处理不能太长时间阻塞主线程(建议放入线程中处处理),否则可能导致苹果拒绝你的应用。
- 扩展不能单独提审,必须要跟容器程序一起提交AppStore进行审核。
- 提审的扩展和容器程序的Build Version要保持一致,否则在上传审核包的时候会提示警告,导致程序无法正常提审。(Info.plist : 里面的版本号必须要和主工程的版本号一致,否则审核可能被拒。)
PS:如果想让Share Extension跳转、打开宿主APP
其实苹果官方除了Today Extension外,其他Extension是不提供跳转接口的。所以这里总结的是两种非正常的方式。
- 如果只需要在点击分享框的时候处理:
- (void)didSelectPost {
// This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments.
// Inform the host that we're done, so it un-blocks its UI. Note: Alternatively you could call super's -didSelectPost, which will similarly complete the extension context.
NSString *str = [NSString stringWithFormat:@"%@%@", @"comcihaicihaiyun://jump/Search?searchStr=", self.contentText];
[self goConnationWithUrlSTr:[str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];
[self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];
}
- 如果需要在控制器内处理,需要在自定义的控制器内:
- (void)viewDidLoad
{
[super viewDidLoad];
//获取分享内容
__block BOOL hasGetUrl = NO;
[self.extensionContext.inputItems enumerateObjectsUsingBlock:^(NSExtensionItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
[obj.attachments enumerateObjectsUsingBlock:^(NSItemProvider * _Nonnull itemProvider, NSUInteger idx, BOOL * _Nonnull stop) {
if ([itemProvider hasItemConformingToTypeIdentifier:@"public.plain-text"])
{
[itemProvider loadItemForTypeIdentifier:@"public.plain-text" options:nil completionHandler:^(id<NSSecureCoding> _Nullable item, NSError * _Null_unspecified error) {
if ([(NSObject *)item isKindOfClass:[NSString class]])
{
dispatch_async(dispatch_get_main_queue(), ^{
[self goConnationWithUrlSTr:[str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];
[self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];
});
}
}];
hasGetUrl = YES;
*stop = YES;
}
*stop = hasGetUrl;
}];
}];
}
- 第一种方法在Share Extension中无法获取到UIApplication对象,则通过拼接字符串获取。
- (void)goConnationWithUrlSTr:(NSString *)urlStr
{
NSURL *destinationURL = [NSURL URLWithString:[NSString stringWithFormat:@"sharefile://%@",saveFilePath]];
// 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];
}
}
- 第二种方法通过响应链找到Host App的UIApplication对象,通过该对象调用openURL方法返回自己的应用。
- (void)goConnationWithUrlSTr:(NSString *)urlStr
{
UIResponder *responder = self;
while (responder) {
SEL openSelector = NSSelectorFromString(@"openURL:");
if([responder respondsToSelector:openSelector]) {
[responder performSelector:openSelector withObject:[NSURL URLWithString:urlStr] afterDelay:1.0];
break;
}
responder = [responder nextResponder];
}
}
第二种方法最后记得添加URL Scheme
配置对应的URL Scheme