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

  • 添加对应的规则

    也就是此扩展支持处理哪些种类的文件

    在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

posted @ 2023-02-04 20:10  R1cardo  阅读(271)  评论(0编辑  收藏  举报