今天工作中遇到一个需求,需要app支持接收airDrop文件处理,遂百度了一番,发现挺挺简单的,在工程文件中添加几个参数就可以了(坑的开始)
- 在工程
target
中选择info
,在Document Types
那一栏中添加自己需要处理的文件类型
添加处理文件类型
这个Document Types
就是代表告诉系统自己的app能处理哪种类型的文件
具体的类型可以参考苹果文档
Uniform Type Identifiers (UTI) - 在
AppDelegate
的-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
方法中根据自己的需求来处理文件
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)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<UIApplicationOpenURLOptionsKey,id> *)options
这个回调,但是通过url拿不到数据
同时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<UIApplicationOpenURLOptionsKey,id> *)options
中增加判定
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)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 place
和 Supports Document Browser
,两个都设置为NO就OK了
这两个值为YES,代表文件APP可以看到自己应用的沙盒
为NO,代表文件APP不能看到自己应用的沙盒
大家根据自己应用的需求来设定
网友评论