2017-09-09 37 views
1

我有一个Swift应用程序,我正在转换使用Codable协议(而不是EVReflection,它改变了很多,我可以不再使它工作)。当与应用程序服务器进行交易时,我的代码会生成一个类“ServerResponse”的对象,其中包含许多变量 - 其中一个是“responseObject” - 可以是任意数量的不同对象,从用户到消息,或其他。因为默认情况下Codable不使用“decodeIfPresent”,所以在某些事务中我得到错误,并且必须覆盖init(来自解码器:Decoder)以防止出现这种情况。现在我面临的挑战是如何将原始JSON字符串完整保留,以便稍后通过调用方法解码为正确的对象类型或其他类似的修复。底线:我需要responseObject灵活并允许我的服务器选择发送的任何类型的对象。Swift 4 - Codable - 如何允许在解码时允许不同对象类型的键

如果有人有任何建议,我将不胜感激。如果能够提供帮助,我很乐意分享代码,但我不认为这会是因为这个问题本质上是概念性的。

+0

尝试解码可能是几种类型之一的一般解决方案是尝试将其解码为一种类型,如果由于类型不匹配而失败,请尝试下一种类型。像这样的'responseObject',还是一个完全不受约束的类型?你能举一个JSON有效负载看起来像什么的具体例子吗? –

+0

它不完全没有受到任何限制,但是在我的应用程序中有34种不同的对象可以通过。我真的很喜欢将原始的JSON完全保留,所以我可以从调用方法手动解码它。有没有办法做到这一点? – Joel

+1

目前还没有,没有。这是目前正在考虑的功能。 –

回答

2

你可以做类似的措施: -

struct CustomAttribute: Codable { 
var attributeCode: String? 
var intValue: Int? 
var stringValue: String? 
var stringArrayValue: [String]? 

enum CodingKeys: String, CodingKey { 

    case attributeCode = "attribute_code" 
    case intValue = "value" 
    case stringValue 
    case stringArrayValue 
} 

init(from decoder: Decoder) throws { 
    let values = try decoder.container(keyedBy: CodingKeys.self) 

    attributeCode = try values.decode(String.self, forKey: .attributeCode) 
    if let string = try? values.decode(String.self, forKey: .intValue) { 
     stringValue = string 
    } else if let int = try? values.decode(Int.self, forKey: .intValue) { 
     intValue = int 
    } else if let intArray = try? values.decode([String].self, forKey: .intValue) { 
     stringArrayValue = intArray 
    } 
} 

} 

这里的值可以是三种类型的和我手动确定哪些类型是。