iOS 接收airDrop文件

今天工作中遇到一个需求,需要app支持接收airDrop文件处理,遂百度了一番,发现挺挺简单的,在工程文件中添加几个参数就可以了(坑的开始)

  1. 在工程target中选择info,在Document Types那一栏中添加自己需要处理的文件类型
    添加处理文件类型

    这个Document Types就是代表告诉系统自己的app能处理哪种类型的文件
    具体的类型可以参考苹果文档
    Uniform Type Identifiers (UTI)
  2. AppDelegate-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options方法中根据自己的需求来处理文件
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options {
    if ([url.absoluteString hasPrefix:@"file://"]) {
        //根据自己的需求来处理文件
        //处理文件的逻辑写在这里
        return YES;
    }
     return YES;
}

在处理完成文件之后,app就可以处理airDrop投送过来的文件了


IMG_0192.jpg
IMG_0193.jpg

本来以为这样简单的就结束了,然后坑就来了
因为我们添加了能处理的文件类型,所以在别的app选择一个文件长按选择共享,在共享列表中会多出一个拷贝到我们app的选项(iOS 13.6系统中出现,iOS 14,iOS 15目前无此按钮),点击这个按钮,也会走-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options这个回调,但是通过url拿不到数据

IMG_0049.PNG

IMG_0050.PNG
IMG_0052.PNG

同时options数组中的UIApplicationOpenURLOptionsOpenInPlaceKey值为1

UIApplicationOpenURLOptionsOpenInPlaceKey = 0 代表该文件已经拷贝到本地沙盒
UIApplicationOpenURLOptionsOpenInPlaceKey = 1 代表该文件没有拷贝到本地沙盒

这时就需要我们自己手动去将文件拷贝一次

- (NSURL *)copyFileToLocalWithUrl:(NSURL *)url {
    NSError *error;
    NSString *docsFolder = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    NSString *newPath = [docsFolder stringByAppendingPathComponent:(NSString *)url.lastPathComponent];
    NSURL *newURL = [NSURL fileURLWithPath:newPath];
    // 拷贝原App内的文件到本App沙盒
    [NSFileManager.defaultManager copyItemAtURL:url toURL:newURL error:&error];
    return newURL;
}

这时又有另外一个坑了,用这个方法会报operation not permitted这个错,大概意思就是你没权限
所以你还得去请求权限,最后拷贝代码如下

- (NSURL *)copyFileToLocalWithUrl:(NSURL *)url {
    //请求获取文件权限
    [url startAccessingSecurityScopedResource];
    NSError *error;
    NSString *docsFolder = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    NSString *newPath = [docsFolder stringByAppendingPathComponent:(NSString *)url.lastPathComponent];
    NSURL *newURL = [NSURL fileURLWithPath:newPath];
    // 拷贝原App内的文件到本App沙盒
    [NSFileManager.defaultManager copyItemAtURL:url toURL:newURL error:&error];
    [url stopAccessingSecurityScopedResource]; //结束权限请求
    return newURL;
}

然后在AppDelegate-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options中增加判定

-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options {
    if ([url.absoluteString hasPrefix:@"file://"]) {
        //根据自己的需求来处理文件
        //处理文件的逻辑写在这里
        if ([options[UIApplicationOpenURLOptionsOpenInPlaceKey] integerValue]== 1) {
                //代表文件没有复制到本地沙盒,需要自己手动复制
                url = [self copyFileToLocalWithUrl:url];
            }
        return YES;
    }
     return YES;
}

这样就能通过新生成的url拿到数据了,最后再依据需求做好数据处理,功能就大功告成!


5月17日更新,经过上述操作后,上架到appStore可能会遭遇一些黄色警报,需要在info.plist文件中添加两个键值对
Supports opening documents in placeSupports Document Browser ,两个都设置为NO就OK了
这两个值为YES,代表文件APP可以看到自己应用的沙盒
为NO,代表文件APP不能看到自己应用的沙盒
大家根据自己应用的需求来设定

你可能感兴趣的:(iOS 接收airDrop文件)