如何将包含数组的Swift对象自定义编码为JSON



我是一名新手开发人员,正在编写一款iOS应用程序,允许用户在录制的音乐中定义和回放多个"段落",每个段落多次。

我的类"Piece"是一个Observable对象,目前只包含已发布的var"passages"(一组记录,其中包含用户希望回放的段落的详细信息(。虽然Piece的唯一成员现在是"passages"数组,但我预计Piece最终会有更多的成员,而不是数组。

我希望能够将用户定义的每个Piece保存为JSON文件。因为"Piece"是一个可观察的对象,所以除非我编写自定义编码和解码函数,否则它不符合Codable。到目前为止,我还找不到任何示例代码来说明如何对一个对象(在我的例子中是"Piece"(进行编码,而这个对象又包含一个具有多个属性的自定义对象数组(在我这里是"Passage"(。

下面显示了我的"Piece"one_answers"Passage"代码的相关部分。

class Piece: ObservableObject, Codable {
    @Published var passages = [Passage]()
    
    enum CodingKeys: CodingKey {
        case passages
    }
  
    init() { }
    
    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
    passages = try container.decode([Passage].self, forKey: .passages)
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode([Passage](), forKey: .passages)
        
    }
}
 
struct Passage: Codable, Equatable, Identifiable, Hashable {
    var id = UUID()
    var startTime: Double
    var endTime: Double
    var extraPause: Double
    var numIterations: Int
    var skipMe: Bool = false
    
    enum PassageKeys: CodingKey {
        case id, startTime, endTime, extraPause, numIterations, skipMe
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: PassageKeys.self)
        try container.encode(id, forKey: .id)
        try container.encode(startTime, forKey: .startTime)
        try container.encode(endTime, forKey: .endTime)
        try container.encode(extraPause, forKey: .extraPause)
        try container.encode(numIterations, forKey: .numIterations)
        try container.encode(skipMe, forKey: .skipMe)
    }
}

在我的应用程序界面中,我对以下按钮操作进行了编码。

let url = self.getDocumentsDirectory().appendingPathComponent("X.json")
let encoder = JSONEncoder()
do {
    let data = try encoder.encode(self.piece)
        let string = String(data: data, encoding: .utf8)!
        print("Here is the string we are trying to write: (string)")
        try string.write(to: url, atomically: true, encoding: .utf8)
   } catch {
        print(error.localizedDescription)
}

当我用几个记录填充"passages"数组,然后单击触发此操作的按钮时,控制台输出为:

Here is the string we are trying to write: {"passages":[]}

在Passage.encode((函数中设置断点表明该函数从未被调用。

有人能帮我指明正确的方向吗?

您应该更改

try container.encode([Passage](), forKey: .passages)

try container.encode(passages, forKey: .passages)

在您的代码中。否则,您总是试图对刚刚创建的新的空数组[Passage]()进行编码。