本地端儲存以及讀取資料, Swift 是透過FileManager來做存取以及讀取的動作,本機端資料因為iOS 採用 Sandbox架構的緣故, 可使用來作為讀/存檔案的資料夾為Document。 所以第一步
找到 Document資料夾的 URL
機器設定 : Swift4 + iOS11 + Xcode9
import Foundation
public extension FileManager {
static var documentDirectoryURL: URL {
return try! FileManager.default.url(
for: .documentDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: false
)
}
}
將 documentDirectoryURL用extension包住, 之後便可以使用 FileManager.documentDirectoryURL 來取得該URL路徑
針對Byte格式的本地端儲存&讀取
let mBytes: [UInt8] = [
240, 159, 152, 184,
240, 159, 152, 185,
0b1111_0000, 0b1001_1111, 0b1001_1000, 186,
0xF0, 0x9F, 0x98, 187
]
//mBytes = 😸😹😺😻
let mDataURL = URL(
fileURLWithPath: "mByte",
relativeTo: FileManager.documentDirectoryURL
)
let mData = Data(bytes: mBytes)
// 將資料mData 寫入對應的檔案mDataURL
try mData.write(to: mDataURL)
// 將資料mData 寫入對應的檔案mDataURL, 並給予副檔名
try mData.write(to: mDataURL.appendingPathExtension("txt"))
// 從檔案中取得對應所儲存的資料
let savedMData = try Data(contentsOf: mDataURL)
let savedMBytes = Array(savedMData)
String的本地端儲存&讀取
let string = String(data: savedMData, encoding: .utf8)!
let stringURL =
FileManager.documentDirectoryURL
.appendingPathComponent("string")
.appendingPathExtension("txt")
// 將字串中的資料寫入string.txt儲存
try string.write(to: stringURL, atomically: true, encoding: .utf8)
// 直接透過URL將儲存的檔案讀取出來
try String(contentsOf: stringURL)
圖片 Image 的本地端儲存&讀取
有些時候需要將圖片從網路上讀取下來後儲存, 或者資料庫型態的檔案, 無法直接在Bundle.main 底下使用, 這時需要將檔案轉存在 Document中後使用。 如果需要將如下圖 Resources 中的 png 圖檔轉存進Document的話, 可以使用下面的函式。
// 在FileManager extension 底下新增函式
static func copyPNGSubdirectoriesToDocumentDirectory(subdirectoryNames: String...) throws {
for subdirectoryName in subdirectoryNames {
let documentSubdirectoryURL = URL(
fileURLWithPath: subdirectoryName,
relativeTo: FileManager.documentDirectoryURL
)
//在本地端 Document 底下建立與Resource 相同的資料夾
try? FileManager.default.createDirectory(
at: documentSubdirectoryURL,
withIntermediateDirectories: false
)
// 將 Resources 底下的 PNG 取得對應的 URL
guard let pngURLs = Bundle.main.urls(
forResourcesWithExtension: "png",
subdirectory: subdirectoryName
)
else {continue}
for pngURL in pngURLs {
let data = try Data(contentsOf: pngURL)
try data.write(
to: documentSubdirectoryURL.appendingPathComponent(pngURL.lastPathComponent),
options: .atomic
)
}
}
}
如果需要取得 Document 中底下的 PNG 圖檔可以使用下面的函式
// 在FileManager extension 底下新增函式
static func getPNGFromDocumentDirectory(subdirectoryName: String, imageName: String) -> UIImage? {
return UIImage(contentsOfFile: FileManager.documentDirectoryURL.appendingPathComponent(subdirectoryName).appendingPathComponent(imageName).appendingPathExtension("png").path)
}
之後便可以用下面的方式直接取得 UIImage 來使用
FileManager.getPNGFromDocumentDirectory(subdirectoryName: "Scenes", imageName: "Forest")
Swift 在本地端儲存以及讀取資料, 大多使用 URL的形式後透過 FileManager來使用, 每次做取得動作時, 會有回傳 nil 的情形或者找不到檔案的例外情況, 用 try 以及 ? 來作為檔案格式, 需要特別注意 。