Swift中如何为枚举设置动态可变CodingKeys适配Firestore Codable存储
解决方案
可以通过自定义CodingKeys实现需求,但不能用枚举类型的CodingKeys(枚举的RawValue必须是编译期确定的常量,不支持运行时动态拼接值),你需要换成遵循CodingKey协议的自定义结构体,配合手动实现编解码逻辑即可完成动态编码键的需求。
完整实现代码
struct MyStruct: Codable { let userID: String let userName: String let useCase: String // 自定义支持动态键的CodingKey实现,替代原枚举 private struct DynamicCodingKey: CodingKey { let stringValue: String let intValue: Int? init?(stringValue: String) { self.stringValue = stringValue self.intValue = nil } init?(intValue: Int) { self.intValue = intValue self.stringValue = "\(intValue)" } // 便捷初始化方法,直接传入自定义键名 init(key: String) { self.stringValue = key self.intValue = nil } } // 手动实现编码逻辑 func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: DynamicCodingKey.self) // 编码静态键字段 try container.encode(userID, forKey: DynamicCodingKey(key: "id")) try container.encode(userName, forKey: DynamicCodingKey(key: "name")) // 生成动态键并编码 let dynamicKey = "use_case_\(Int.random(in: 0..<100))" try container.encode(useCase, forKey: DynamicCodingKey(key: dynamicKey)) } // 仅需要存储到Firestore不需要读取的话可以删除下面的解码实现 init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: DynamicCodingKey.self) // 解码静态键字段 userID = try container.decode(String.self, forKey: DynamicCodingKey(key: "id")) userName = try container.decode(String.self, forKey: DynamicCodingKey(key: "name")) // 匹配前缀为use_case_的动态键解码 guard let useCaseKey = container.allKeys.first(where: { $0.stringValue.hasPrefix("use_case_") }) else { throw DecodingError.dataCorrupted(.init( codingPath: decoder.codingPath, debugDescription: "Missing use_case_ prefixed dynamic key" )) } useCase = try container.decode(String.self, forKey: useCaseKey) } // 便捷初始化方法 init(userID: String, userName: String, useCase: String) { self.userID = userID self.userName = userName self.useCase = useCase } }
适配Firestore的使用说明
你可以直接用Firestore自带的Codable扩展将该结构体实例写入数据库,生成的文档会自动携带use_case_前缀加随机数的动态键,符合你的需求。如果不需要从Firestore读取该结构体数据,可以删除init(from:)方法的实现,进一步简化代码。
内容的提问来源于stack exchange,提问作者vishnu venugopal
相关产品推荐
相关产品推荐

