弄清楚如何在 Swift 中用 Disk 替换数据

Figuring out how to replace data with Disk in Swift

提问人:Luke Nelson 提问时间:7/9/2023 更新时间:7/9/2023 访问量:57

问:

我正在尝试使用 XCode 制作一个排序应用程序,并且正在努力弄清楚如何在预先存在的 json 文件中存储数据。

示例 JSON:

[
    {
        "id":1001,
        "trackName":"Rain of Amethyst",
        "intensity":0,
        "album":"crystallized"
    },
    {
        "id":1002,
        "trackName":"Artificial Snow",
        "intensity":0,
        "album":"crystallized"
    },
    ...
]

.swift文件:

import SwiftUI
import Disk

struct TrackRow: View {
    var track: Track
    
    var body: some View {
        HStack {
            Image(track.album)
                .resizable()
                .frame(width: 50, height: 50)
            VStack(alignment: .leading) {
                Text(track.trackName)
                Text(track.album)
                    .foregroundColor(Color.gray)
            }
            Spacer()
            Text(String(track.intensity))
                .padding(.trailing)
                .onTapGesture {
                    //Block of code here that somehow edits JSON data
                }
        }
    }
}
...

如何将该值替换为其他整数?intensity

我搜索了不同的文档和实现,它们似乎都不起作用,尽管我承认作为一个新手,我可能在寻找错误的东西。

iOS JSON Swift Xcode SwiftUI

评论

0赞 jnpdx 7/9/2023
您无法写入捆绑包中的文件。但是,您可以写入文件系统中其他位置的 JSON 文件,例如文档目录。例如,请参见 hackingwithswift.com/books/ios-swiftui/...
0赞 Luke Nelson 7/9/2023
@jnpdx 所以,我根本没有办法永久存储数据?我从 Apple 的 SwiftUI 教程中知道我能够更改数据,但它因版本而异。从技术上讲,这是存储数据吗?
0赞 jnpdx 7/9/2023
我没有说任何关于无法永久存储数据的事情。我刚才说过你不能写入捆绑包中的文件。在永久性方面,您无法阻止用户删除文件、应用程序或清除手机内容。
0赞 Luke Nelson 7/9/2023
我现在明白了。现在我已经弄清楚了,我仍然需要找出如何替换该值。intensity
0赞 jnpdx 7/9/2023
要获得可变数据,您可能需要了解@State

答:

0赞 KerryDong 7/9/2023 #1

正如 jnpdx 所提到的,你不能直接在 bundle 中编写 JSON。

但是,CoreData 可以帮助您根据需要永久保存数据。如果您不熟悉,此解决方案有点复杂,但它为您提供了结构化的数据结构。CoreData

  1. 解析 JSON 文件并将结果保存到 .CoreData
    let decoder = JSONDecoder()
    do {
        let result = try decoder.decode([Track].self, from: data)
        // CoreData insert
    } catch {
        print(error)
    }
       
    struct Track: Codable {
        var id: Int
        var trackName: String
        var intensity: Int
        var album: String
    }
  1. 将应用程序中的 .sqlite 文件复制到项目目录。
    (仅当更新 JSON 文件内容时才执行步骤 1、2) 首先下载容器。.sqlite 可能存在于文件夹中。
    AppData/Documentsenter image description here

  2. 获取所需的记录,然后更新 中的值。
    一些参考:CoreData fetch(_:)、CoreData insert(_:) with NSMergeByPropertyObjectTrumpMergePolicy
    intensity'sCoreData


或者,您可以尝试 B 计划:

将 JSON 文件复制到用户首次启动应用时。始终读取/写入“Documents”目录中的文件。Documents directory

  1. 检查 JSON 是否存在于 中。如果步骤 2 已存在,请跳过该步骤。AppDelegate didFinishLaunchingWithOptions()Documents directory
  2. 用于将文件复制到 。FileManager.default.copyItem()Documents directory
  3. 解析 JSON 文件。Documents directory
  4. 根据您定义的模型进行修改。intensityTrack
  5. 将其保存回 JSON 文件中。Documents directory

结论

CoreData当您需要处理大型 JSON 文件时,强烈建议使用。作为一款优秀的应用程序,我们经常使用 CoreData 来帮助我们管理移动设备中的数据库。它具有更好的性能。

另一方面,仅当您的 JSON 大小非常小时才适用,因为它每次都需要读取/写入整个 JSON 文件。Plan B

[注意]要解释清楚有点挑战性。如果您有任何问题,请随时提问。