最近用到了获取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()
}
}
网友评论