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

2017-01-18  本文已影响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];

上一篇下一篇

猜你喜欢

热点阅读