swift - 如何使用枚举和关联的自定义对象读取和写入对象?
问题描述
我正试图围绕如何为 Firestore 创建一个可编码对象,该对象可以在其中保存一组自定义对象类型。我已经设法为我想要存储的每种对象类型创建了一个带有枚举的可编码对象,但是我正在努力如何读取或写入它,我开始怀疑我错了完全路径。
下面是我正在尝试做的一个例子。
struct myView:View {
@Binding var entry:JournalEntry
var body: some View {
VStack {
Text("Title: \(entry.title)")
Text("Content: \(/* WHAT TO PUT HERE? */)")
TextField("RecordA text", text: /* WHAT TO PUT HERE? */)
}
}
}
struct Journal:Codable, Identifiable {
var id = UUID().uuidString
var entries:[JournalEntry]
}
struct JournalEntry:Codable, Identifiable {
var id:String
var title: String
var date:Date
var entryContent:EntryType
}
struct RecordA: Codable {
var text:String = ""
var image:String = ""
}
struct RecordB: Codable {
var laps:Int = 0
var jumps:Int = 0
}
enum EntryType: Codable {
case recordTypeA(RecordA)
case recordTypeB(RecordB)
}
extension EntryType {
private enum CodingKeys: String, CodingKey {
case base, recordTypeAObject, recordTypeBObject
}
private enum Base: String, Codable {
case recordTypeA, recordTypeB
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case .recordTypeA:
try container.encode(RecordA(), forKey: .recordTypeAObject)
case .recordTypeB:
try container.encode(RecordB(), forKey: .recordTypeBObject)
}
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let base = try container.decode(Base.self, forKey: .base)
switch base {
case .recordTypeA:
if let content = try? decoder.singleValueContainer().decode(RecordA.self) {
self = .recordTypeA(content)
return
}
case .recordTypeB:
if let content = try? decoder.singleValueContainer().decode(RecordB.self) {
self = . recordTypeB(content)
return
}
}
throw ContentError.missingValue
}
enum ContentError:Error {
case missingValue
}
}
解决方案
为了查看内容,我将为每个结构创建一个视图
struct RecordAView: View {
var record: RecordA
var body: some View {
VStack {
Image(record.image)
Text(record.text)
}
}
}
struct RecordBView: View {
var record: RecordB
var body: some View {
HStack {
Text("\(record.jumps)")
Text("\(record.laps)")
}
}
}
然后修改myView
以显示正确的数据
struct myView:View {
@Binding var entry:JournalEntry
var body: some View {
VStack {
Text("Title: \(entry.title)")
viewForContent(entry.entryContent)
}
}
func viewForContent(_ content: EntryType) -> some View {
switch content {
case .recordTypeA(let record):
return AnyView(RecordAView(record: record))
case .recordTypeB(let record):
return AnyView(RecordBView(record: record))
}
}
}
}
推荐阅读
- python - .exe 没有通过 winrm 执行
- algorithm - 计算机如何计算对数?
- spring-cloud-loadbalancer - Spring Cloud Load Balancer - 通过 Java 自定义负载均衡器客户端配置
- javascript - 这是什么“�”以及如何删除它
- linux - 用于多核 cpu 的 Autodock Vina 脚本的多个实例
- pandas - 将一列数据框拆分为熊猫中的新列
- java - 具有更改活动的布局动画
- stata - Stata:双重日期比较
- c# - 命名空间“Aspose.Cells”中不存在类型或命名空间名称“Utility”(您是否缺少程序集引用?)
- python - _driver.cpython-36m-x86_64-linux-gnu.so:未定义符号:_ZN5boost6detail12set_tss_dataEPKvPFvPFvPvES3_ES5_S3_b