Swift 操作檔案的VC - UIDocumentPickerViewController

更新於 2024/10/15閱讀時間約 10 分鐘

一樣先來看官方文件

A view controller that provides access to documents or destinations outside your app’s sandbox.

其實就是讓你去讀取檔案App的東西

iphone裡的檔案App

iphone裡的檔案App

有兩種模式,Don’t copy the document if you can avoid it. 原則上是不需要就不要特別copy一份:

  1. 打開檔案:可以選擇存取原本的檔案或是copy一份來修改,讓你不會動到原本的檔案。
  2. 輸出到指定位置:指定檔案移到目的地,也可以選擇改變原本的檔案,或是copy一份來修改。

Init的方法

也分兩種(四種?)

打開檔案:操作原本/copy的檔案

  • init(forOpeningContentTypes: [UTType])Creates and returns a document picker that can open the types of documents you specify.
  • init(forOpeningContentTypes: [UTType], asCopy: Bool)Creates and returns a document picker that can open or copy the types of documents you specify.
使用這兩個需先 import UniformTypeIdentifiers,不然會有錯誤

輸出到指定位置:操作原本/copy的檔案

  • init(forExporting: [URL])Creates and returns a document picker that can export the types of documents you specify.
  • init(forExporting: [URL], asCopy: Bool)Creates and returns a document picker that can export or copy the types of documents you specify.

下面的範例都是用第一種forOpeningContentTypes來講。

操作原本檔案需要權限

選擇操作原本檔案,開始存取前,需加上 url.startAccessingSecurityScopedResource(),結束操作後url.stopAccessingSecurityScopedResource()

如果操作原本的檔案又沒加上權限,會取不到檔案。

使用init(forOpeningContentTypes: [UTType])瀏覽檔案

// 打開documentPicker 
@IBAction func openFile(_ sender: UIButton) {
let documenPickerVC = UIDocumentPickerViewController(forOpeningContentTypes: [.content])
documenPickerVC.delegate = self
self.present(documenPickerVC, animated: true)
}

❌ 沒有加上權限存取,讀不到檔案。這邊注意一定要用實機測試,模擬器兩種都不需要權限,會讓你以為天下太平= =

extension ViewController: UIDocumentPickerDelegate {
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
do {
for url in urls {
// 直接操作檔案
let filename = url.lastPathComponent
let resourceValue = try url.resourceValues(forKeys: [.fileSizeKey])
filenameLabel.text = "檔案名稱:\(filename)"
fileSizeLabel.text = "檔案大小:\(resourceValue.fileSize ?? 0)"
}
} catch {
print(error.localizedDescription)
}
}
}
取不到檔案內容

取不到檔案內容

The file “ppt檔.pptx” couldn’t be opened because you don’t have permission to view it.

✅正確的寫法

extension ViewController: UIDocumentPickerDelegate {
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
do {
for url in urls {
    let accessing = url.startAccessingSecurityScopedResource()
     defer {
if accessing {
url.stopAccessingSecurityScopedResource( }
}
// ....操作檔案

另外,有打開權限就要關掉,沒關掉的會可能會造成leak,之後app就沒辦法在存取檔案裡的東西,除非重開。所以最佳寫法就是stopAccessingSecurityScopedResource寫在defer {},跑完一定會關掉。

拿到正確的檔案資訊

拿到正確的檔案資訊

copy的不需要額外權限

使用init(forOpeningContentTypes: [UTType], asCopy: Bool)copy一份的方式瀏覽檔案

// 打開documentPicker 
@IBAction func openFile(_ sender: UIButton) {
let documenPickerVC = UIDocumentPickerViewController(forOpeningContentTypes: [.content], asCopy: true)
documenPickerVC.delegate = self
self.present(documenPickerVC, animated: true)
}

✅ 直接操作檔案

extension ViewController: UIDocumentPickerDelegate {
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
do {
for url in urls {
// 直接操作檔案
let filename = url.lastPathComponent
let resourceValue = try url.resourceValues(forKeys: [.fileSizeKey])
filenameLabel.text = "檔案名稱:\(filename)"
fileSizeLabel.text = "檔案大小:\(resourceValue.fileSize ?? 0)"
}
} catch {
print(error.localizedDescription)
}
}
}
拿到正確的資訊

拿到正確的資訊

我個人偏好跟官方講的一樣,如果沒有特殊需求直接操作原本的檔案就好,不會想要再copy一份,雖然copy方式code比較少😂

UTType

forOpeningContentTypes: [UTType]這個參數,可以讓你限制使用者可以選擇的檔案,不能選擇的會泛灰不能點選,但這東西我覺得極為難用。

因為有被他收編的很輕易就可以寫出來,例如:.jpeg, .png,輕鬆優雅的寫在UTType array裡。

let documenPickerVC = UIDocumentPickerViewController(forOpeningContentTypes: [.jpeg, .png])


但沒被他收編的。例如:微軟word檔、ppt檔。需要自己去找對照表id轉成UTType,非常醜且可怕,而且對照表還莫名的很難搜尋到。

let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: [UTType("com.microsoft.powerpoint.ppt")!, UTType("com.microsoft.word.doc")!])


好在iOS14之後他出了一個比較優雅的做法,用fileExtension去判斷type。不過如果使用者亂改副檔名的話,這個判斷結果可能會失準,需自行斟酌。

let acceptTypes = [UTType(filenameExtension: "ppt"), UTType(filenameExtension: "doc")].compactMap{$0}
let documenPickerVC = UIDocumentPickerViewController(forOpeningContentTypes: acceptTypes)



avatar-img
7會員
35內容數
紀錄iOS開發上遇到的問題或是一些流程筆記。主要都是Swift。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
Michelle Chen的沙龍 的其他內容
iCloud+的服務 只有付錢的人才能用,免費仔如我從來沒聽過😗 簡介 通常你在瀏覽網頁時,網路供應商和你所造訪的網站可以看到網頁流量所包含的資訊(例如 DNS 記錄和 IP 位址)。此資訊可用來判斷你的身分,並建立描述檔來記錄你的位置以及往後的瀏覽記錄。 「iCloud 私密轉送」的設計旨
漸層文字 做出像Apple Keynote主題一樣的美美漸層文字 先畫出一大塊美美漸層色,可以選自己喜歡的顏色跟角度去做喔 LinearGradient(colors: [.blue, .purple, .red], startPoint: .bottomLead
先來看官方文件 https://developer.apple.com/documentation/swiftui/spacer Spacer A flexible space that expands along the major axis of its containing stack
swift讀書筆記 https://docs.swift.org/swift-book/documentation/the-swift-programming-language/deinitialization/  class instance deallocated前會call deinitia
swift讀書筆記 Documentation Edit descriptiondocs.swift.org objective-c 的init 會return value,swift 不會。 所有的property都必須在Init()裡面設定初始值,或設定stored property,這種
其實16也會ㄏㄏ 相關討論: https://developer.apple.com/forums/thread/703145 重現步驟: 在iOS15以上,使用UIActivityViewController執行下列步驟會crash 1. 開啟UIActivityViewControlle
iCloud+的服務 只有付錢的人才能用,免費仔如我從來沒聽過😗 簡介 通常你在瀏覽網頁時,網路供應商和你所造訪的網站可以看到網頁流量所包含的資訊(例如 DNS 記錄和 IP 位址)。此資訊可用來判斷你的身分,並建立描述檔來記錄你的位置以及往後的瀏覽記錄。 「iCloud 私密轉送」的設計旨
漸層文字 做出像Apple Keynote主題一樣的美美漸層文字 先畫出一大塊美美漸層色,可以選自己喜歡的顏色跟角度去做喔 LinearGradient(colors: [.blue, .purple, .red], startPoint: .bottomLead
先來看官方文件 https://developer.apple.com/documentation/swiftui/spacer Spacer A flexible space that expands along the major axis of its containing stack
swift讀書筆記 https://docs.swift.org/swift-book/documentation/the-swift-programming-language/deinitialization/  class instance deallocated前會call deinitia
swift讀書筆記 Documentation Edit descriptiondocs.swift.org objective-c 的init 會return value,swift 不會。 所有的property都必須在Init()裡面設定初始值,或設定stored property,這種
其實16也會ㄏㄏ 相關討論: https://developer.apple.com/forums/thread/703145 重現步驟: 在iOS15以上,使用UIActivityViewController執行下列步驟會crash 1. 開啟UIActivityViewControlle
你可能也想看
Google News 追蹤
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
本文介紹了 Swift 語言中的各種數學運算子,包括基本數學運算子、複合賦值運算子、比較運算子、邏輯運算子和範圍運算子。將提供使用這些運算子的方式及其優先順序規則,讓讀者能輕鬆理解如何在程序中實現數值與邏輯運算,並掌握 Swift 中的運算子使用技巧。
本文章介紹 Swift 語言中變數的建立方法,包括變數與常數的宣告、型別推斷、型別註記以及常見資料型別。本文詳細說明瞭可選型別的意義、變數命名的規則和作用域的概念,幫助讀者更有效地使用 Swift 語言進行程式設計。
使用者回報的超級奇怪線上問題,用數字鍵盤(NumberPad)更改欄位時,送出後尾數都會消失。例如:30 ⭢ 3,52 ⭢ 5。 尋尋覓覓了兩天終於被我找到這篇,apple的奇葩的bug 重現條件 iOS17 手機設定是繁體中文語系 前一個用過的鍵盤是Cangjie倉頡 or Suchen
Emergency lockout solutions provide critical assistance when you find yourself locked out of your home, car, or office. These services are designed to
Thumbnail
本文介紹瞭如何在SwiftUI中調整元件的對齊方式,包括置中、向左/向右/向上/向下對齊的方法。透過調整HStack、VStack以及frame的maxWidth、maxHeight和alignment屬性,可以達到想要的對齊效果。
Thumbnail
That we were never really meant to be / 看吧,我們本就不該選擇彼此
Thumbnail
But if it's okay with you, it's okay with me / 但若你早已沒什麼好說的,那也就這樣吧
三元條件運算子(Ternary Conditional Operator)是一種簡潔的寫法,用於在滿足條件時返回一個值,否則返回另一個值。 基本語法 其中,condition是要測試的條件,如果為true,則返回valueIfTrue,否則返回valueIfFalse。
Thumbnail
10月21日午夜,美國歌手Taylor Swift發布其全新錄音室專輯《Midnights》。此張專輯自宣布到發行過程不斷引發大量話題,在發行當下更不斷打破各項紀錄。作品以獨立流行為底,「失眠的13個夜晚」為概念,融合過往音樂風格和特色,打造出別具特色的低迴氛圍,著實是2022年底音樂界的一部佳作。
Thumbnail
泰勒絲(Taylor Swift )當初從藝人開始跨出純演藝圈,明白讓大家知道他,這個玉女,要踏進政治的髒水,來關心政治的時候,寫了這首歌,歌名是《只要還年輕》(Only the young),鼓勵尤其是年輕人更不要灰心喪志,因為這不是終局之戰,一切都才剛開始。 我稍微翻譯了一下歌詞(不是按照音
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
本文介紹了 Swift 語言中的各種數學運算子,包括基本數學運算子、複合賦值運算子、比較運算子、邏輯運算子和範圍運算子。將提供使用這些運算子的方式及其優先順序規則,讓讀者能輕鬆理解如何在程序中實現數值與邏輯運算,並掌握 Swift 中的運算子使用技巧。
本文章介紹 Swift 語言中變數的建立方法,包括變數與常數的宣告、型別推斷、型別註記以及常見資料型別。本文詳細說明瞭可選型別的意義、變數命名的規則和作用域的概念,幫助讀者更有效地使用 Swift 語言進行程式設計。
使用者回報的超級奇怪線上問題,用數字鍵盤(NumberPad)更改欄位時,送出後尾數都會消失。例如:30 ⭢ 3,52 ⭢ 5。 尋尋覓覓了兩天終於被我找到這篇,apple的奇葩的bug 重現條件 iOS17 手機設定是繁體中文語系 前一個用過的鍵盤是Cangjie倉頡 or Suchen
Emergency lockout solutions provide critical assistance when you find yourself locked out of your home, car, or office. These services are designed to
Thumbnail
本文介紹瞭如何在SwiftUI中調整元件的對齊方式,包括置中、向左/向右/向上/向下對齊的方法。透過調整HStack、VStack以及frame的maxWidth、maxHeight和alignment屬性,可以達到想要的對齊效果。
Thumbnail
That we were never really meant to be / 看吧,我們本就不該選擇彼此
Thumbnail
But if it's okay with you, it's okay with me / 但若你早已沒什麼好說的,那也就這樣吧
三元條件運算子(Ternary Conditional Operator)是一種簡潔的寫法,用於在滿足條件時返回一個值,否則返回另一個值。 基本語法 其中,condition是要測試的條件,如果為true,則返回valueIfTrue,否則返回valueIfFalse。
Thumbnail
10月21日午夜,美國歌手Taylor Swift發布其全新錄音室專輯《Midnights》。此張專輯自宣布到發行過程不斷引發大量話題,在發行當下更不斷打破各項紀錄。作品以獨立流行為底,「失眠的13個夜晚」為概念,融合過往音樂風格和特色,打造出別具特色的低迴氛圍,著實是2022年底音樂界的一部佳作。
Thumbnail
泰勒絲(Taylor Swift )當初從藝人開始跨出純演藝圈,明白讓大家知道他,這個玉女,要踏進政治的髒水,來關心政治的時候,寫了這首歌,歌名是《只要還年輕》(Only the young),鼓勵尤其是年輕人更不要灰心喪志,因為這不是終局之戰,一切都才剛開始。 我稍微翻譯了一下歌詞(不是按照音