How does iOS obtain the document data shared by the app

When previewing files in PDF or other formats, we can share the file or print it through the built-in UIDocumentInteractionControllersoftware . as the picture shows:QLPreviewControllerUIActivityViewController


The first line AirDropis a shortcut for users to share files between Apple devices after iOS7, which is similar to Bluetooth wireless transfer files on Android.

The second line is a list of Apps identified by the document type association technique.

The third line is a list identified by document association technology Action, indicating some operations that can be performed on the file, such as copying, printing, saving, etc.

We know that there is a security system under the iOS system -- 沙盒机制each iOS application is an independent file system, and can only be operated in its own file system, so the iOS system cannot easily access other files like Android. files under the application.

Since we can share files to other apps when previewing files in our own apps, how can we allow other apps to share files to our app?

info.plist registration file type

We need to info.plistadd a new attribute CFBundleDocumentTypes(actually entered Document type) in the file, which is an array type attribute, which means that we can register multiple types at the same time. For each element in the array, there are many attributes that can be specified. We can find the detailed attribute list from the official document:  Core Foundation Keys ---- CFBundleDocumentTypes . Here are the attributes we commonly use when doing iOS development:

  • CFBundleTypeName

    The string type specifies an alias of a certain type, that is, an alias used to refer to the type we specify. Generally, in order to maintain uniqueness, we use UTI to identify it.

  • CFBundleTypeIconFiles

Array type, containing the file name of the specified png icon, specifying an icon representing a certain type, and the icon has a specific size identification:

Device Sizes
iPad 64 x 64 pixels, 320 x 320 pixels
iPhone and iPod touch 22 x 29 pixels, 44 x 58 pixels (high resolution)
  • LSItemContentTypes

Array type, containing UTI strings, specifying a collection of all file types that our application can recognize

  • LSHandlerRank
    string type, including Owner, Default, Alternate, Nonefour optional values, specifies the priority level for a certain type, and Launcher Servicethe order of the displayed App will be arranged according to this priority level. The order of priority from high to low is Owner, Alternate, Default. NoneIndicates that this type is not accepted.

We choose Source codethe way to open info.plistthe file and add the following code:

<key>CFBundleDocumentTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeName</key>
            <string>PDF</string>
            <key>LSHandlerRank</key>
            <string>Owner</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>com.adobe.pdf</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeName</key>
            <string>Microsoft Word</string>
            <key>LSHandlerRank</key>
            <string>Alternate</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>com.microsoft.word.doc</string>
                <string>com.microsoft.word.wordml</string>
                <string>org.openxmlformats.wordprocessingml.document</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeName</key>
            <string>Microsoft Excel</string>
            <key>LSHandlerRank</key>
            <string>Alternate</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>com.microsoft.excel.xls</string>
                <string>org.openxmlformats.spreadsheetml.sheet</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeIconFiles</key>
            <array/>
            <key>CFBundleTypeName</key>
            <string>Microsoft PowerPoint</string>
            <key>LSHandlerRank</key>
            <string>Alternate</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>com.microsoft.powerpoint.​ppt</string>
                <string>org.openxmlformats.presentationml.presentation</string>
                <string>public.presentation</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeName</key>
            <string>Text</string>
            <key>LSHandlerRank</key>
            <string>Alternate</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.text</string>
                <string>public.plain-text</string>
                <string>public.utf8-plain-text</string>
                <string>public.utf16-external-plain-​text</string>
                <string>public.utf16-plain-text</string>
                <string>com.apple.traditional-mac-​plain-text</string>
                <string>public.source-code</string>
                <string>public.c-source</string>
                <string>public.objective-c-source</string>
                <string>public.c-plus-plus-source</string>
                <string>public.objective-c-plus-​plus-source</string>
                <string>public.c-header</string>
                <string>public.c-plus-plus-header</string>
                <string>com.sun.java-source</string>
                <string>public.script</string>
                <string>public.shell-script</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeName</key>
            <string>Rich Text</string>
            <key>LSHandlerRank</key>
            <string>Alternate</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.rtf</string>
                <string>com.apple.rtfd</string>
                <string>com.apple.flat-rtfd</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeName</key>
            <string>HTML</string>
            <key>LSHandlerRank</key>
            <string>Alternate</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.html</string>
                <string>public.xhtml</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeName</key>
            <string>Web Archive</string>
            <key>LSHandlerRank</key>
            <string>Alternate</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>com.apple.webarchive</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeName</key>
            <string>Image</string>
            <key>LSHandlerRank</key>
            <string>Alternate</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.image</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeName</key>
            <string>iWork Pages</string>
            <key>LSHandlerRank</key>
            <string>Alternate</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>com.apple.page.pages</string>
                <string>com.apple.iwork.pages.pages</string>
                <string>com.apple.iwork.pages.template</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeName</key>
            <string>iWork Numbers</string>
            <key>LSHandlerRank</key>
            <string>Alternate</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>com.apple.numbers.numbers</string>
                <string>com.apple.iwork.numbers.numbers</string>
                <string>com.apple.iwork.numbers.template</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeName</key>
            <string>iWork Keynote</string>
            <key>LSHandlerRank</key>
            <string>Alternate</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>com.apple.keynote.key</string>
                <string>com.apple.iwork.keynote.key</string>
                <string>com.apple.iwork.keynote.kth</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeName</key>
            <string>Audio</string>
            <key>LSHandlerRank</key>
            <string>Alternate</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.audio</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeName</key>
            <string>Movie</string>
            <key>LSHandlerRank</key>
            <string>Alternate</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.movie</string>
            </array>
        </dict>
        <dict>
            <key>CFBundleTypeName</key>
            <string>Archive</string>
            <key>LSHandlerRank</key>
            <string>Alternate</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>public.archive</string>
            </array>
        </dict>
    </array>

Add these codes, and your app can support most file types. You can add related types of codes according to your own project needs. My own project only needs to support PDF and word format files. After adding these codes, we choose Property listto open the info.plist file:

Or infoopen Document typesthe list on the page:

At this time, it means that we have successfully registered the file types supported by the app. At this time, we are compiling and running, and then go to other apps (QQ I use here) to open the downloaded file. The page that comes out at this time is like this of:

We can see that our App icon has appeared in the list in the second column. At this time, we can click the icon button to share the file to our App.

What to do with shared files

When the icon button is clicked, it will jump to our own application, and this callback method AppDelegate.mwill be used at this time.- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options

But the callback is before iOS9 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation, so we need to make changes for different device versions.

We can perform file processing operations in the callback method, such as uploading files, previewing files, and saving files. When doing file preview, we must jump to the corresponding controller. At this time, we must first obtain the current view controller

//获取当前屏幕显示的viewcontroller
- (UIViewController *)getCurrentVC
{
    UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
    
    UIViewController *currentVC = [self getCurrentVCFrom:rootViewController];
    
    return currentVC;
}

- (UIViewController *)getCurrentVCFrom:(UIViewController *)rootVC
{
    UIViewController *currentVC;
    
    if ([rootVC presentedViewController]) {
        // 视图是被presented出来的
        
        rootVC = [rootVC presentedViewController];
    }
    
    if ([rootVC isKindOfClass:[UITabBarController class]]) {
        // 根视图为UITabBarController
        
        currentVC = [self getCurrentVCFrom:[(UITabBarController *)rootVC selectedViewController]];
        
    } else if ([rootVC isKindOfClass:[UINavigationController class]]){
        // 根视图为UINavigationController
        
        currentVC = [self getCurrentVCFrom:[(UINavigationController *)rootVC visibleViewController]];
        
    } else {
        // 根视图为非导航类
        
        currentVC = rootVC;
    }
    
    return currentVC;
}

After getting the controller, we can go back to the callback method to perform the jump work. I still use it UIDocumentInteractionControllerfor file preview

#if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_9_0
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation{
    // 判断传过来的url是否为文件类型
    if ([url.scheme isEqualToString:@"file"]) {
        _docVc = [UIDocumentInteractionController interactionControllerWithURL:url];
        _docVc.delegate = self;
        [_docVc presentPreviewAnimated:YES];
        
    }
    
}

#else
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
    // 判断传过来的url是否为文件类型
    if ([url.scheme isEqualToString:@"file"]) {
        _docVc = [UIDocumentInteractionController interactionControllerWithURL:url];
        _docVc.delegate = self;
        [_docVc presentPreviewAnimated:YES];
    }
    return YES;
}
#endif

#pragma mark -- UIDocumentInteractionControllerDelegate
- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller
{
    // 返回当前控制器
    return [self getCurrentVC];
}



 

Guess you like

Origin blog.csdn.net/ForeverMyheart/article/details/119933472
Recommended