通过文档类型声明给iOS应用争取亮相的机会

iOS是一个监狱,每个第三方 应用都是一个囚徒,其行为完全受到监狱的限制:能做什么,不能做什么,什么时候可以放风,什么时候必须睡觉,甚至生杀予夺,都由监狱说了算。

在这种情况下,多给应用创造点被拜访的机会,无疑对于提高应用的活跃度延长其生命有着重要的意义。

之前我写过一篇iOS开发之Core Spotlight实战。让应用支持 spotlight搜索,当然是让应用放风。让引用支持文档类型以接受其他应用的分享,无疑也是一个机会。

今天稍微花了一点功夫给MarkNote 加上了文件类型支持。其他应用比如mail可以将后缀名为.txt后者.md的文件共享给Marknote。
效果如下:


整个过程不是太复杂。大体分为两步:

  • 声明应用所支持的文件类型
  • 实现处理的相关代码
    下面分开来说。

声明所支持的文件类型

标准文件扩展名

苹果对常用的标准扩展名有一个列表。在这个列表中的文件类型,可以直接根据引用其Identifier。
比如,我的应用需要支持导入txt文件,根据上面提到的列表,找到.txt文件的Identifier为public.plain-text,直接创建一个types为public.plain-text的Document type即可。
Document type在Project ->Target -> Info栏中创建。


上图中图标,Name都随意。

非标准扩展名

对于不在上面列表中的文件类型,在进行上面的步骤之前,首先要定义UTI。
比如我要支持的.md后缀就不在上面的列表中,需要定义 UTI。好在定义UTI并不太复杂。
在Project ->Target -> Info栏中找到Imported UTI,添加一个,定义如下:



声明完UTI后就可以直接在Document Type中直接用了:


以上操作也可以直接在App的info.plist文件中直接用写。比如我的UTI声明部分:

<key>UTImportedTypeDeclarations</key>
    <array>
        <dict>
            <key>UTTypeConformsTo</key>
            <array>
                <string>public.text</string>
            </array>
            <key>UTTypeDescription</key>
            <string>markdown document</string>
            <key>UTTypeIdentifier</key>
            <string>public.markdown</string>
            <key>UTTypeSize320IconFile</key>
            <string>IconLite</string>
            <key>UTTypeSize64IconFile</key>
            <string>IconLite</string>
            <key>UTTypeTagSpecification</key>
            <dict>
                <key>public.filename-extension</key>
                <array>
                    <string>md</string>
                    <string>MD</string>
                    <string>markdown</string>
                </array>
            </dict>
        </dict>
    </array>

文档类型部分:

<key>CFBundleDocumentTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeIconFiles</key>
            <array>
                <string>IconLite</string>
            </array>
            <key>CFBundleTypeName</key>
            <string>Plain text</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.plain-text</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeIconFiles</key>
            <array>
                <string>IconLite</string>
            </array>
            <key>CFBundleTypeName</key>
            <string>Markdown document</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.markdown</string>
            </array>
        </dict>
    </array>

代码处理

当用户选择我的应用后,iOS会将该文件拷贝到应用的Documents/Inbox目录中,并传给应用该文件路径对应的URL,此URL的scheme是file://。
读取该URL即可得到文件内容。
处理逻辑应该在appdelegate的openURL方法中:

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    NSString *surl = [url absoluteString];
     if ([surl hasPrefix:@"file://"]){
        // 读到文件内容
        NSString* content = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error: nil];
       // 处理逻辑略...
       // 处理完毕后清理inbox
        [self cleanInbox];
        
    } 
    return YES;
}

处理完文件后,该共享的文件亦然存在Inbox中,应用有义务清理之。清理代码如下:

-(void) cleanInbox{
    // 获取应用的Document目录
    NSString *documentsDirectory = [FileUtil documentPath];
    // 分享过来的文件都在Inbox子目录下
    NSString *path = [NSString stringWithFormat:@"%@/Inbox", documentsDirectory ];
    NSArray *directoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
    for (NSString *file in directoryContents) {
        NSString* fullPath = [NSString stringWithFormat:@"%@/%@", path,file ];
        [FileUtil removeFile:fullPath];
    }
}

至此文件类型支持功能开发完毕。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容