基础应用iOS开发你需要知道的Swift好文收藏

UIDocumentPickerViewController 用

2021-08-20  本文已影响0人  再好一点点

最近用到了获取icloud里面的音频文件的功能。简单记录一下。

这里面有几点需要注意的:

1,startAccessingSecurityScopedResource(),stopAccessingSecurityScopedResource()这两个方法非常重要,如果不打开安全访问是无法读取DocumentPicker内的文件数据的。

2,通过DocumentPicker选择的文件只能在当前app生命周期内使用,当关掉app再次打开的时候即使在本地保存的有同样的路径,也是无法访问到文件的。但是apple提供了一种书签的机制,可以保证每次打开app都可以访问先前保存的文件。用法如下:

保存:


 getFileUrl(url) { newUrl in
    if let bookmarkUrl = newUrl, let bookmark = try? bookmarkUrl.bookmarkData(options: [], includingResourceValuesForKeys: nil, relativeTo: nil) {
          UserDefaults.standard.setValue(bookmark, forKey: kBSForumSaveAudioUrlKey)
                  }
         }

  func getFileUrl(_ url: URL, success:((URL?) -> ())) {
            //获取文件安全访问权限
            let authozied = url.startAccessingSecurityScopedResource()
            if authozied {
                //通过文件协调器读取文件地址
                let fileCoordinator = NSFileCoordinator()
                fileCoordinator.coordinate(readingItemAt: url, options: [.withoutChanges], error: nil) { (newUrl) in
                    success(newUrl)
                }
            } else {
                success(nil)
            }
            //停止安全访问权限
            url.stopAccessingSecurityScopedResource()
        }

获取:

   if let data = UserDefaults.standard.value(forKey: kBSForumSaveAudioUrlKey) as? Data  {
            if let url = try? URL.init(resolvingBookmarkData: data, options: URL.BookmarkResolutionOptions.withoutMounting, relativeTo: nil, bookmarkDataIsStale: &res)  {
                //这里可以获取访问权限(startAccessingSecurityScopedResource),然后使用
            }
        }

types是需要访问的文件类型,如果类型不包含在types数组里边,选择的时候是灰色的不允许选择。

types类型如下:

苹果官方地址

"com.microsoft.powerpoint.ppt",
"com.microsoft.word.doc",
"com.microsoft.excel.xls",
"com.microsoft.powerpoint.pptx",
"com.microsoft.word.docx",
"com.microsoft.excel.xlsx",
"public.avi",
"public.3gpp",
"public.mpeg-4",
"com.compuserve.gif",
"public.jpeg",
"public.png",
"public.plain-text",
"com.adobe.pdf"

具体代码如下:

有些格式在文档中如果找不到可以使用这种方式查找,let types = [String(kUTTypeWaveformAudio), String(kUTTypeMP3)]。然后进入kUTTypeWaveformAudio定义的地方查找

  if let vc = parentViewController {
            let types = ["public.audio"]
            let documentPicker = UIDocumentPickerViewController.init(documentTypes: types, in: .open)
            documentPicker.delegate = self
            vc.present(documentPicker, animated: true, completion: nil)
        }

实现UIDocumentPickerDelegate

extension ViewController: UIDocumentPickerDelegate, UINavigationControllerDelegate {
     // iOS8-10
    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
        processData(url)
    }
     // iOS11   
    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
        if let url = urls.first {
            processData(url)
        }
    }

    func processData(_ url: URL) {
        var fileData: Data?
        //获取文件安全访问权限
        let authozied = url.startAccessingSecurityScopedResource()
        if authozied {
            //通过文件协调器读取文件地址
            let fileCoordinator = NSFileCoordinator()
            fileCoordinator.coordinate(readingItemAt: url, options: [.withoutChanges], error: nil) { (newUrl) in
                let fileName = newUrl.lastPathComponent
                printf("fileName \(fileName)")
                //读取文件协调器提供的新地址里的数据
                fileData = try? Data.init(contentsOf: newUrl, options: [.mappedIfSafe])
                if let data = fileData {
                    //获取到数据
                }
            }
        }
        //停止安全访问权限
        url.stopAccessingSecurityScopedResource()
    }
}

本人原文博客地址

上一篇下一篇

猜你喜欢

热点阅读