本文的文案由GPT4生成
在 iOS 開發(fā)中,我們有時需要讓用戶選擇一個文件夾路徑,用于保存或讀取文件。但是選擇過的文件夾路徑在下次使用時,我們希望用戶不需要再次選擇。這篇博客將帶你了解如何使用 UIDocumentPickerViewController 界面來獲取文件的路徑,包含 iCloud 中的文件夾路徑,以及將這些路徑存儲為 bookmark,方便根據(jù)這些路徑直接進行文件的讀寫,而無需讓用戶再次進行選擇。
使用 UIDocumentPickerViewController 獲取選擇的文件夾路徑
首先,創(chuàng)建并彈出 UIDocumentPickerViewController,設(shè)置 documentTypes 為 ["public.folder"] 以只選擇文件夾:
let documentPicker = UIDocumentPickerViewController(documentTypes: ["public.folder"], in: .open)
documentPicker.delegate = self
let rootViewController = UIApplication.shared.delegate?.window??.rootViewController
rootViewController?.present(documentPicker, animated: true, completion: nil)
然后,實現(xiàn) UIDocumentPickerDelegate 協(xié)議,通過 documentPicker(_:didPickDocumentsAt:) 方法來獲取用戶選擇的文件夾路徑:
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
guard let pickedURL = urls.first else {
return
}
// 處理 pickedURL
}
將選擇的文件夾路徑存儲為 Bookmark
通過 UIDocumentPickerViewController 獲取到文件夾路徑后,我們需要將其存儲為 bookmark。整個過程需要在 startAccessingSecurityScopedResource 和 stopAccessingSecurityScopedResource 之間進行:
let isAccessing = pickedURL.startAccessingSecurityScopedResource()
if !isAccessing {
// 無法訪問文件夾
return
}
let bookmarkData = try pickedURL.bookmarkData(options: NSURL.BookmarkCreationOptions.minimalBookmark, includingResourceValuesForKeys: nil, relativeTo: nil)
pickedURL.stopAccessingSecurityScopedResource()
將生成的 bookmarkData 轉(zhuǎn)換為 base64 編碼的字符串,方便存儲:
let bookmarkDataString = bookmarkData.base64EncodedString(options: [])
將 bookmarkDataString 保存到本地(如:UserDefaults)即可。
使用 Bookmark 寫入文件
當(dāng)我們需要將文件寫入到之前選擇的文件夾路徑時,首先需要將存儲的 bookmarkDataString 轉(zhuǎn)換為 URL:
guard let bookmarkData = Data(base64Encoded: bookmarkDataString, options: []) else {
// 處理無效的 bookmarkDataString
return
}
var isStale = false
let directoryURL = try? URL(resolvingBookmarkData: bookmarkData, options: .withoutUI, relativeTo: nil, bookmarkDataIsStale: &isStale)
然后使用 directoryURL 來訪問文件夾,并寫入文件,這個過程也需要在 startAccessingSecurityScopedResource 和 stopAccessingSecurityScopedResource 之間進行:
let isAccessing = directoryURL?.startAccessingSecurityScopedResource() ?? false
if !isAccessing {
// 無法訪問文件夾
return
}
let fileURL = directoryURL?.appendingPathComponent(fileName)
do {
try content.write(to: fileURL!, atomically: true, encoding: .utf8)
directoryURL?.stopAccessingSecurityScopedResource()
// 寫入成功
} catch {
directoryURL?.stopAccessingSecurityScopedResource()
// 寫入失敗
}
注意:在info.plist中應(yīng)該增加下列配置
<key>NSUbiquitousContainers</key>
<dict>
<key>iCloud.appBundleId</key>
<dict>
<key>NSUbiquitousContainerIsDocumentScopePublic</key>
<true/>
<key>NSUbiquitousContainerSupportedFolderLevels</key>
<string>Any</string>
<key>NSUbiquitousContainerName</key>
<string>appName</string>
</dict>
</dict>
至此,我們已經(jīng)實現(xiàn)了使用 UIDocumentPickerViewController 獲取文件夾路徑,并將路徑存儲為 Bookmark,以便在后續(xù)寫入文件時無需讓用戶再次選擇的功能。希望對你的開發(fā)工作可以帶來幫助。
參考文獻:
https://developer.apple.com/documentation/uikit/view_controllers/providing_access_to_directories