iOS 分享数据到其它app(open in other app)

时间:2022-09-10 20:29:23

限于iOS的沙盒机制(sandbox),不能跨app访问数据。所以想分享App A的数据到App B中使用,需要借助Open In来操作。
本文介绍如何实现通过“Open In”方式来分享数据到其它App当中,以及在实现时,踩到的坑(前车之鉴)。

1. 涉及的类

Cocoa框架为我们提供了类UIDocumentInteractionController来实现Open In分享。

2. 实现步骤

简单说来,我们需要准备数据,弹出Open In窗口,调用UIDocumentInteractionController分享数据。
2.1 准备数据
推荐将要分享的数据拷贝到一个目录文件夹做备用。当然如果将分享的数据体积较大,也可省略这一步,但必须保证数据在分享过程中可用;

NSString *fromPath = @"demoFromPath";
NSString *toPath = @"demoToPath";
NSError *err = nil;
NSFileManager*fileManager =[NSFileManager defaultManager];
[fileManager copyItemAtPath:fromPath toPath:toPath error:&err];

另外还需初始化一个分享类实例对象,并声明类遵循UIDocumentInteractionControllerDelegate协议。
首先声明一个UIDocumentInteractionController属性实例:

@property (nonatomic, strong) UIDocumentInteractionController *documentViewController;
@synthesize documentController;

在分享前确保初始化该属性实例:

NSString *demoFilePath = @"./demo.jpg";

NSURL *demoFileUrl = [NSURL fileURLWithPath:demoFilePath];

if (!self.documentViewController) {
    //init an instance with method:interactionControllerWithURL 
    self.documentViewController = [UIDocumentInteractionController interactionControllerWithURL:demoFileUrl];
    self.documentViewController.UTI = demoFileUrl.lastPathComponent;
    self.documentViewController.delegate = self;
}

2.2 弹出Open In窗口
Cocoa框架的 UIDocumentInteractionController 类里面提供了5个相关的函数来展示Open In窗口。当Open In窗口弹出时,会列出支持该数据类型(通常是文件类型)的App列表,所以若需要测试分享到微信,微博等真实的App时,必须在真机中测试。

// This is the default method you should call to give your users the option to quick look, open, or copy the document. // Presents a menu allowing the user to Quick Look, open, or copy the item specified by URL. // This automatically determines the correct application or applications that can open the item at URL. // Returns NO if the options menu contained no options and was not opened. // Note that you must implement the delegate method documentInteractionControllerViewControllerForPreview: to get the Quick Look menu item.
- (BOOL)presentOptionsMenuFromRect:(CGRect)rect inView:(UIView *)view animated:(BOOL)animated; - (BOOL)presentOptionsMenuFromBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated;
// Bypasses the menu and opens the full screen preview window for the item at URL.  Returns NO if the item could not be previewed.
// Note that you must implement the delegate method documentInteractionControllerViewControllerForPreview: to preview the document.
- (BOOL)presentPreviewAnimated:(BOOL)animated;
// Presents a menu allowing the user to open the document in another application. The menu
// will contain all applications that can open the item at URL.
// Returns NO if there are no applications that can open the item at URL.
- (BOOL)presentOpenInMenuFromRect:(CGRect)rect inView:(UIView *)view animated:(BOOL)animated;
- (BOOL)presentOpenInMenuFromBarButtonItem:(UIBarButtonItem *)item animated:(BOOL)animated;

在项目当中我用的较多的方法是:

- (BOOL)presentOpenInMenuFromRect:(CGRect)rect inView:(UIView *)view animated:(BOOL)animated;

比较灵活使用。
2.3 实现delegate:UIDocumentInteractionControllerDelegate中的方法:
展示将要分享的信息:

- (void)documentInteractionController:(UIDocumentInteractionController *)controller willBeginSendingToApplication:(NSString *)application

在分享完成时给提示或进行其它操作:

- (void)documentInteractionController:(UIDocumentInteractionController *)controller didEndSendingToApplication:(NSString *)application

3. 注意的问题

在分享时,UIDocumentInteractionController必须作为一个非栈空间对象来操作,否则弹不出Open In窗口,这涉及到iOS的内存管理机制了,在栈上所申请的内存空间,当我们出了变量所在的作用域后,系统会自动我们回收这些空间。建议声明为类的属性来实现。