UIDocumentPickerViewController操作系统自带“文件”app中文件

通过UIDocumentPickerViewController 访问iPhone自带应用“Files(文件) APP”。

前提条件:
1:iOS 系统为11.0及以上
2:Xcode中开启iCloud配置
在这里插入图片描述

导入文件功能

NSArray *documentTypes = @[@"com.adobe.pdf",@"public.content", @"public.text", @"public.source-code ", @"public.image", @"public.audiovisual-content",  @"com.apple.keynote.key", @"com.microsoft.word.doc",@"com.microsoft.excel.xls", @"com.microsoft.powerpoint.ppt"];

UIDocumentPickerViewController *documentPickerViewController = [[UIDocumentPickerViewController alloc]initWithDocumentTypes:documentTypes inMode:UIDocumentPickerModeImport];

documentPickerViewController.delegate = self;

[self presentViewController:documentPickerViewController animated:YES completion:nil];

#pragma mark - UIDocumentPickerDelegate
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url {
    NSArray *array = [[url absoluteString] componentsSeparatedByString:@"/"];
    NSString *fileName = [array lastObject];
    fileName = [fileName stringByRemovingPercentEncoding];
    NSLog(@"文件路径%@",[url absoluteString]);
}

- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls {
    //获取授权
    BOOL fileUrlAuthozied = [urls.firstObject startAccessingSecurityScopedResource];
    if (fileUrlAuthozied) {
        //通过文件协调工具来得到新的文件地址,以此得到文件保护功能
        NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init];
        NSError *error;
        
        [fileCoordinator coordinateReadingItemAtURL:urls.firstObject options:0 error:&error byAccessor:^(NSURL *newURL) {
            //读取文件
            NSString *fileName = [newURL lastPathComponent];
            NSError *error = nil;
            NSData *fileData = [NSData dataWithContentsOfURL:newURL options:NSDataReadingMappedIfSafe error:&error];
            if (error) {
                //读取出错
            } else {
                NSLog(@"上传===%@",fileName);
                //上传
//                [self uploadingWithFileData:fileData fileName:fileName fileURL:newURL];
            }
            
            [self dismissViewControllerAnimated:YES completion:NULL];
        }];
        [urls.firstObject stopAccessingSecurityScopedResource];
    } else {
        //授权失败
    }
}

初始化方法

-(instancetype)initWithDocumentTypes:(NSArray <NSString >)allowedUTIs inMode:(UIDocumentPickerMode)mode

mode :确定目标导入模式

	UIDocumentPickerModeImport,导入(将外部文档复制到您的应用中,使原始文档保持不变)
    UIDocumentPickerModeOpen,打开(提供对文档的访问权限,可以在适当位置进行编辑)
    UIDocumentPickerModeExportToService,导出(将应用内的文档导出到所选的外部目标位置)
    UIDocumentPickerModeMoveToService 移动(在应用程序中定位文档的外部目标)

allowedUTIs 老版本写法 新的写法:告诉文档选择器我想要的文件类型

[String(kUTTypePDF),String(kUTTypePNG),String(kUTTypeJPEG),]

directoryURL
设置此属性可以为文档选择器指定起始目录

页面结构为 TabBarController 》 ``` //A 方法的作用是调用icloud选取文件 func A(){ let picker = UIDocumentPickerViewController.init(documentTypes: ["public.data"], in: .import) pickerd.delegate = self self.present(picker, animated: true, completion: nil) } // documentPicker方法是pickerd.delegate回调的方法 func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) { // 这里用通知是我原认为这个地方已经是处于present的模态窗口中,不能继续present,因为这个UIDocumentPickerViewController选取文件后会自己自动关闭,所以想着通知在另外一个地方中处理 NotificationCenter.default.post(name: NSNotification.Name("selected"), object: self, userInfo:["urls": urls]) } //selected方法是为了选取到icloud中文件后,想继续打开另外一个viewcontroller进行处理 @objc func selected(notification:NSNotification) { let userInfo = notification.userInfo guard let url = userInfo?["urls"] as? [URL] else { return } controllerB.url = url self.present(controllerB,animated: true, completion: nil)) } ``` 现在的问题是,回调selected方法后, self.present 会提示Application tried to present modally an active controller,我想会不会是因为seleted方法也在TabBarController文件中,才会报错,但是事实上好像也不是这样,我也试过在A方法中再加一层navigationController,在seleted中用这个navigationController实例再做push,试验证明push是没报错,但是页面也并不会发生跳转,实在无解,求教。难道不能在UIDocumentPickerViewController拾取文件后再处理 ?
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页