通过 Swift 在 iPhone (iOS) dev 中 store/retrieve 用户数据(read/write 文件)的正确方法是什么?

What is correct way to store/retrieve user data (read/write files) in iPhone (iOS) dev via Swift?

背景

我已经通过 Windows Forms (C#)、Android(Java 和 Kotlin)、HTML5 Web App、ElectronJS(运行于Linux、Mac 和 Win10),甚至作为 UWP(通用 Windows 平台)应用。

全部使用 JSON 文件作为数据

所有这些应用都使用完全相同的 JSON 格式数据进行用户设置。 这意味着我可以通过相同的文件和文件格式在所有平台上共享数据。 在 Android 上,将文件保存在 UserPrefs 中还有一个额外的好处(为用户提供安全和备份)。

问题 我还将该应用程序编写为 iPhone/iPad 应用程序 (Swift),但是我找不到处理 JSON 文件存储的正确方法。
问题 与将 JSON 反序列化到我的业务对象中无关 。一切正常。但是,我不确定:

  1. 文件应存储在 iPhone/iPad 系统中的什么位置?
  2. 你能以某种用户偏好或应用程序数据保存文件吗 位置?
  3. 如何打开 read/write 和 read/write 数据的文件? (Swift)
  4. 如何更好地理解可读写路径 文件?

我到处寻找这个答案。你能给我指点官方文档、一本书、一个 Whosebug 项目或其他能清楚解释这一点的东西吗? (希望有 Swift 个例子。)

参见 iOS Storage Best Practices video and the File System Basics 文档。那应该让你继续。

简而言之,应用程序数据一般存储在“应用程序支持目录”中,暴露给用户的文档(例如文件应用程序)存储在“文档”文件夹中,可以轻松重新检索的下载存储在“缓存”文件夹。从技术上讲,您可以使用 UserDefaults 来存储此类应用程序数据,但它实际上并非用于此目的。

为“read/write”重新打开文件,在处理JSON时,一般不会这样做。您将文件读入 Data 并将 JSON 反序列化为您的模型对象。

do {
    let fileURL = try FileManager.default
        .url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
        .appendingPathComponent("appdata.json")

    let data = try Data(contentsOf: fileURL)
    let appData = try JSONDecoder().decode(AppData.self, from: data)
    // do something with appData
} catch { 
    print(error)
}

当您想要更新时,您将模型对象序列化为包含您的 JSON 的 Data,然后将其写入文件,替换文件。

do {
    let fileURL = try FileManager.default
        .url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
        .appendingPathComponent("appdata.json")

    let data = try JSONEncoder().encode(appData)
    try data.write(to: fileURL)
} catch { 
    print(error)
}

显然,这假定 AppData 类型(或任何你称之为的类型)符合 Codable,但你说你熟悉 JSON 的序列化。有关详细信息,请参阅 Encoding and Decoding Custom Types