美文网首页
iOS App接收其它应用数据机制实现

iOS App接收其它应用数据机制实现

作者: 蓝点工坊 | 来源:发表于2017-01-18 16:31 被阅读108次

    在不同应用中共享数据,这是很有实际意义的,比如果我现在做的iPad打印程序,想从PC机传输一个打印脚本通过App ,控制打印机打印,自己写一套传输机制工程量相当大.

    早期类似功能,我使用App打开文件共享功能. 即PC机上iTunes软件通过USB联入iPad,然后拖入相应App的文件窗来实现.这个操作对于用户相当麻烦.对于App也好不到哪去,因为App产知道你什么时候拖入,拖入是哪一个文件.

    因此我们现在采用iOS 内置App 分享机制. UIDocumentInteractionController 来实现类似需求. 比如用QQ传输文件后,在iPad QQ上文件上直接选其它应用打开. 这样操作简单方便.用户体验很好.

    以下就是完整实现这一机制的整个流程

    一. info.plist 定义支持文档

    这个文章写得很详细.
    http://www.jianshu.com/p/88a08d66894f

    苹果支持内置分享各种文件类型.
    https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html

    二.加入自定义后缀文件支持

    对于通用文件,如txt,图片文件,大部分应用会自己直接打开,如QQ/微信均是如此,并没有用其它应用打开的选项.因此必须采用一个特定的后缀,QQ才能显示这个选项.

    http://blog.csdn.net/chengyingzhilian/article/details/8517193

    三.App接收文件处理

    会集中在AppDelegate 中处理,

    - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(nonnull NSDictionary<NSString *,id> *)options{
    
       NSData * recvData =  [NSData dataWithContentsOfURL:url];
    }
    

    其中文件名称在 url中,options则记录一些选项,比如来源的App

    这是我实测一个QQ分享给App结果 URL中,test-1.tscbas就是我分享文件名.如果支持多种后缀,可以通过这个文件名来区分.

    file:///private/var/mobile/Containers/Data/Application/B64401CE-7279-4337-837A-1A78BD0B60BA/Documents/Inbox/test-1.tscbas

    options的值,可以看到QQ的包名.

    {
    UIApplicationOpenURLOptionsAnnotationKey = {
    };
    UIApplicationOpenURLOptionsOpenInPlaceKey = 0;
    UIApplicationOpenURLOptionsSourceApplicationKey = "com.tencent.mipadqq";
    }

    文件本身内容可以接调用 [NSData dataWithContentsOfURL:url] 即可

    注意在iOS9.0后,过去一些老的处理接口 handleOpenURL,以及另一个openURL 已经废掉,只采用上述接口

    - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url NS_DEPRECATED_IOS(2_0, 9_0, "Please use application:openURL:options:") __TVOS_PROHIBITED;
    
    - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation NS_DEPRECATED_IOS(4_2, 9_0, "Please use application:openURL:options:") __TVOS_PROHIBITED;
    
    - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options NS_AVAILABLE_IOS(9_0); // no equiv. notification. return NO if the application can't open for some reason
    
    

    四.App界面处理

    在QQ分享文件,App可能已经打开,并处在任意一个界面上.这个时间我处理分享文件的界面要如何创建呢? 这个好象没看太多例子,因此通过一些实验,找到办法.

    象微信,百度网盘均是在当前界面弹出一个新界面来处理.处理完后,关闭或后退,又会回到原来界面上.因此这可能是大多数App的做法.

    因此第一步需要在AppDelegate中找到当前的ViewController,中,可以用这个扩展类
    http://stackoverflow.com/questions/11637709/get-the-current-displaying-uiviewcontroller-on-the-screen-in-appdelegate-m

    UIWindow+PazLabs.h (header file)

    #import <UIKit/UIKit.h>
    
    @interface UIWindow (PazLabs)
    
    - (UIViewController *) visibleViewController;
    
    @end
    

    UIWindow+PazLabs.m (implementation file)

    #import "UIWindow+PazLabs.h"
    
    @implementation UIWindow (PazLabs)
    
    - (UIViewController *)visibleViewController {
        UIViewController *rootViewController = self.rootViewController;
        return [UIWindow getVisibleViewControllerFrom:rootViewController];
    }
    
    + (UIViewController *) getVisibleViewControllerFrom:(UIViewController *) vc {
        if ([vc isKindOfClass:[UINavigationController class]]) {
            return [UIWindow getVisibleViewControllerFrom:[((UINavigationController *) vc) visibleViewController]];
        } else if ([vc isKindOfClass:[UITabBarController class]]) {
            return [UIWindow getVisibleViewControllerFrom:[((UITabBarController *) vc) selectedViewController]];
        } else {
            if (vc.presentedViewController) {
                return [UIWindow getVisibleViewControllerFrom:vc.presentedViewController];
            } else {
                return vc;
            }
        }
    }
    
    @end
    

    找到当前ViewController后直接在上面push一个新的viewController即可.以下是我测试通过代码

     UIViewController * vc = [application.keyWindow visibleViewController]; //找到当前窗口
        
    
    //创建一个新的ViewController
        UIStoryboard *secondStoryBoard = [UIStoryboard storyboardWithName:@"PrinterSetting" bundle:[NSBundle mainBundle]];
            
        PrinterSettingViewController* settingController = [secondStoryBoard instantiateViewControllerWithIdentifier:@"SettingView"];
     
    //显示新建界面   
        [vc.navigationController pushViewController:settingController animated:YES];
    
    

    相关文章

      网友评论

          本文标题:iOS App接收其它应用数据机制实现

          本文链接:https://www.haomeiwen.com/subject/nsqbbttx.html