UIDocumentPickerViewController選擇文件夾并在將來寫入文件到該文件夾

本文的文案由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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容