IOS打开对应后缀文件
IOS打开对应后缀文件
通过ShareExtension打开
点击文件共享后出现的上方列表,如下图
- 在 info.plist 中添加 Document types
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>RAR Archive</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>LSItemContentTypes</key>
<array>
<string>com.rarlab.rar-archive</string>
</array>
</dict>
</array>
其中 CFBundleTypeName是名字, LSItemContentTypes填对应的UTI
这里如果LSItemContentTypes没填对的话在系统分享列表就不会出现我们的宿主app
UTI也就是统一类型标识符是一个字符串,它唯一地标识被认为具有“类型”的一类实体。是苹果用于识别文件类型的。
这样就可以实现了,在AppDelegate中的
override func application(_: UIApplication, open url: URL, options _: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
//处理逻辑
return true
}
方法中实现对应逻辑处理
通过ActionExtension打开
-
创建ActionExtension
具体过程就不介绍了,有了这个扩展可以在长按文件分享时将自己的app加入分享的列表
-
添加对应的规则
也就是此扩展支持处理哪些种类的文件
在ActionExtension的info.plist中添加**NSExtensionActivationRule **key
如果value为Dictionary,则可以添加苹果自带的规则
-
最多支持多少文件: NSExtensionActivationSupportsFileWithMaxCount
-
支持txt文件: NSExtensionActivationSupportsText
-
支持图片: NSExtensionActivationSupportsImageWithMaxCount
还有很多其他的规则可以自行查看 点我跳转
如果设置为TRUEPREDICATE表示可以分享任意内容
但是这些规则可能都有局限性
所以苹果提供了自定义规则的方法,有一套对应的语法有兴趣可以看看
将NSExtensionActivationRule的value类型改为string
SUBQUERY ( extensionItems, $extensionItem, SUBQUERY ( $extensionItem.attachments, $attachment, ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.text" || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "org.idpf.epub-container" || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.pkware.zip-archive" || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.rarlab.rar-archive" || ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "org.7-zip.7-zip-archive" ).@count >= 1 ).@count > 0
关键代码在于
$attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.text"
这行代码的意思是允许处理UTI 遵循 "public.text"规则的文件,也就是txt文件
不清楚的话去看看UTI的定义
上述代码允许了五种类型txt、epub、zip、rar、7z
这样规则定好之后,在允许处理的文件类型分享列表中就会出现我们的app了,点击我们app的列表项就需要在ActionExtension中处理对应的逻辑
-
-
处理对应文件逻辑
想要在点击分享后跳转到宿主App,必须创建带有UI的ActionExtension
因为在extension中UIApplication是不可用的,所以只能另辟蹊径
通过ASCII码获取到UIApplication
+ (void) openApp:(NSString*)path{ NSURL *destinationURL = [NSURL URLWithString:[NSString stringWithFormat:@"要跳转的URLScheme",path]]; // 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]; } }
然后在
viewDidLoad
方法中添加处理对应文件的逻辑- (void)viewDidLoad { [super viewDidLoad]; BOOL found = NO; for (NSExtensionItem *item in self.extensionContext.inputItems) { for (NSItemProvider *itemProvider in item.attachments) { if ([itemProvider hasItemConformingToTypeIdentifier: type.identifier]) { [itemProvider loadItemForTypeIdentifier: type.identifier options:nil completionHandler:^(NSURL *url, NSError *error) { //处理对应文件的逻辑 }]; found = YES; break; } } if (found) { break; } } if (!found){ [self done]; } }
因为创建的是带UI的ActionExtension,点击分享的列表项会弹出一个底部弹窗,这时我们自己进行一个收起操作,也就是
[self done];
跳转到App后一样的是在AppDelegate中去处理相关的逻辑
override func application(_: UIApplication, open url: URL, options _: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool { //处理逻辑 return true }
PS:有一些UTI是苹果没有的,这时候就需要自己定义或者导入别人定义过的
参考:https://www.itbaoku.cn/post/939003.html
https://www.itbaoku.cn/post/939003.html