Swift 操作檔案的VC - UIDocumentPickerViewController

更新於 發佈於 閱讀時間約 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
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
我自己是希望可以製作iOS app來更好存放我的文章, 更進階一點,可以變成直接錄音後, 照我設定的方式轉換成文檔,讓iPhone變成我更強的助手。 感覺有很多可以探索,用時間慢慢累積經驗。
Thumbnail
本文檔介紹了在Swift中使用套件的詳細方法,包括如何引用第三方套件和自定義模組,如何創建自定義套件,以及一些常見的Swift套件。這些套件可以幫助開發者快速添加功能到項目中,提高開發效率和程式碼品質。
Thumbnail
這個章節主要介紹了Swift程式語言中物件導向程式設計的基本概念,包括類別、建構子、公開、私有、受保護等等的概念。同時,也介紹了繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型和反射等進階特性。
Thumbnail
此章節旨在介紹Swift程式語言中的基本資料型別,包括整數、浮點數、布林型別、字串、字符、選擇型、型別轉換、自訂型別(包括類、結構和枚舉)、元組型別、集合型別、陣列型別和字典型別。每種型別的說明都包含了程式碼範例,以便讀者更好地理解其應用和使用方式。
Thumbnail
本章節介紹了如何建立並設置Swift項目以及如何選擇和設置Swift代碼編輯器。這包括在Xcode和命令行中建立Swift項目,選擇Xcode、Visual Studio Code或AppCode作為編輯器,以及如何使用SPM安裝插件。
Thumbnail
本章節旨在為讀者提供Swift程式語言的基礎知識,包括其基本語法、註解方法和變數使用方式,並通過具體的程式碼示例來說明這些概念。這將幫助讀者理解Swift的基本結構,並學會如何在Swift中定義變數並使用註解。
Thumbnail
這份文件的目的是介紹Swift語言,包括它的特性、應用範疇,以及誰在使用它。它也提供了一些學習Swift的資源和工具,以及一些常見的Swift庫和框架。
Thumbnail
需求情境: 在設計畫面時,資料來源是後台的 api,每一次畫面細節的修修改改,都會觸發 Xcode Preview 程序,導致不斷呼叫後台。此時若資料結構和大小都具有一定規模,就會導致效率低落,不斷等待,且消耗伺服器資源甚鉅。 解決方案: 將後台傳回的資料以檔案形式暫存在本地端,每次 pr
Thumbnail
Part.1 搞定基本的 UI 開始開發 iOS App。 首先準備一台 Mac,然後安裝 Xcode,新增專案,系統即刻生成基本的專案結構。coding 的起點在檔案 ContentView.swift: import SwiftUI struct ContentView: View {  
Thumbnail
在APP中打開外部瀏覽器是一個常見的需求,特別是當你需要在APP中顯示外部網頁或處理特定的網絡操作時。本文介紹了三種常見的方法來解決內部瀏覽器操作問題並在APP中打開外部瀏覽器:使用系統預設瀏覽器、使用WebView控件和使用自定義瀏覽器控件。
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
我自己是希望可以製作iOS app來更好存放我的文章, 更進階一點,可以變成直接錄音後, 照我設定的方式轉換成文檔,讓iPhone變成我更強的助手。 感覺有很多可以探索,用時間慢慢累積經驗。
Thumbnail
本文檔介紹了在Swift中使用套件的詳細方法,包括如何引用第三方套件和自定義模組,如何創建自定義套件,以及一些常見的Swift套件。這些套件可以幫助開發者快速添加功能到項目中,提高開發效率和程式碼品質。
Thumbnail
這個章節主要介紹了Swift程式語言中物件導向程式設計的基本概念,包括類別、建構子、公開、私有、受保護等等的概念。同時,也介紹了繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型和反射等進階特性。
Thumbnail
此章節旨在介紹Swift程式語言中的基本資料型別,包括整數、浮點數、布林型別、字串、字符、選擇型、型別轉換、自訂型別(包括類、結構和枚舉)、元組型別、集合型別、陣列型別和字典型別。每種型別的說明都包含了程式碼範例,以便讀者更好地理解其應用和使用方式。
Thumbnail
本章節介紹了如何建立並設置Swift項目以及如何選擇和設置Swift代碼編輯器。這包括在Xcode和命令行中建立Swift項目,選擇Xcode、Visual Studio Code或AppCode作為編輯器,以及如何使用SPM安裝插件。
Thumbnail
本章節旨在為讀者提供Swift程式語言的基礎知識,包括其基本語法、註解方法和變數使用方式,並通過具體的程式碼示例來說明這些概念。這將幫助讀者理解Swift的基本結構,並學會如何在Swift中定義變數並使用註解。
Thumbnail
這份文件的目的是介紹Swift語言,包括它的特性、應用範疇,以及誰在使用它。它也提供了一些學習Swift的資源和工具,以及一些常見的Swift庫和框架。
Thumbnail
需求情境: 在設計畫面時,資料來源是後台的 api,每一次畫面細節的修修改改,都會觸發 Xcode Preview 程序,導致不斷呼叫後台。此時若資料結構和大小都具有一定規模,就會導致效率低落,不斷等待,且消耗伺服器資源甚鉅。 解決方案: 將後台傳回的資料以檔案形式暫存在本地端,每次 pr
Thumbnail
Part.1 搞定基本的 UI 開始開發 iOS App。 首先準備一台 Mac,然後安裝 Xcode,新增專案,系統即刻生成基本的專案結構。coding 的起點在檔案 ContentView.swift: import SwiftUI struct ContentView: View {  
Thumbnail
在APP中打開外部瀏覽器是一個常見的需求,特別是當你需要在APP中顯示外部網頁或處理特定的網絡操作時。本文介紹了三種常見的方法來解決內部瀏覽器操作問題並在APP中打開外部瀏覽器:使用系統預設瀏覽器、使用WebView控件和使用自定義瀏覽器控件。