【发布时间】:2020-11-12 19:23:44
【问题描述】:
我是一名新手开发人员,正在编写一个 iOS 应用程序,该应用程序允许用户在一段录制的音乐中定义和重播多个“段落”,每个段落多次播放。
我的类 'Piece' 是一个 Observable 对象,它当前仅包含已发布的 var 'passages'(包含用户希望重播的段落详细信息的记录数组)。虽然 Piece 的唯一成员现在是“通道”数组,但我希望 Piece 最终会有更多成员,而不是数组。
我希望能够将用户定义的每个 Piece 保存为 JSON 文件。因为 'Piece' 是一个可观察对象,所以它不符合 Codable ,除非我编写自定义编码和解码函数。到目前为止,我一直无法找到任何示例代码来说明如何编码一个对象(在我的情况下为“Piece”),而该对象又包含一个自定义对象数组(在我的情况下为“Passage”),这些对象有多个属性。
下面显示了我的“Piece”和“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)
}
当我用几条记录填充“通道”数组然后单击触发此操作的按钮时,控制台输出显示:
Here is the string we are trying to write: {"passages":[]}
在 Passage.encode() 函数中设置断点表明该函数永远不会被调用。
谁能帮我指出正确的方向?
【问题讨论】:
-
据我所知,您不需要 init(from:) 或 encode(to:),编译器会为您正确合成它们。尝试将它们全部注释掉,看看它是否有效。
-
获取“类型'Piece'不符合协议'Decodable'”和“类型'Piece'不符合协议'Encodable'”并将这些注释掉。我认为这是因为这里提出的问题:hackingwithswift.com/books/ios-swiftui/…
-
好的,那我知道了。感谢您的链接。