使用Codable与有时是INT的值,而其他时间则是字符串
我有一个API,有时会在JSON中返回特定的钥匙值(在这种情况下)作为int,而其他时候它将返回与字符串相同的键值。如何使用Codable解析该JSON?
struct GeneralProduct: Codable {
var price: Double!
var id: String?
var name: String!
private enum CodingKeys: String, CodingKey {
case price = "p"
case id = "i"
case name = "n"
}
init(price: Double? = nil, id: String? = nil, name: String? = nil) {
self.price = price
self.id = id
self.name = name
}
}
我一直收到此错误消息:<代码>预期解码字符串,但找到了一个数字。它返回数字的原因是因为ID字段为空,并且当ID字段为空时,它默认为返回0作为代码标识为数字的ID。我基本上可以忽略ID密钥,但是编码并不能让我选择忽略它。处理此问题的最佳方法是什么?
这是JSON。这是超简单的
工作
{
"p":2.12,
"i":"3k3mkfnk3",
"n":"Blue Shirt"
}
错误 - 由于系统中没有ID,因此它返回0作为默认值,该默认值显然是与字符串相对的数字。
{
"p":2.19,
"i":0,
"n":"Black Shirt"
}
I have an API that will sometimes return a specific key value (in this case id
) in the JSON as an Int and other times it will return that same key value as a String. How do I use codable to parse that JSON?
struct GeneralProduct: Codable {
var price: Double!
var id: String?
var name: String!
private enum CodingKeys: String, CodingKey {
case price = "p"
case id = "i"
case name = "n"
}
init(price: Double? = nil, id: String? = nil, name: String? = nil) {
self.price = price
self.id = id
self.name = name
}
}
I keep getting this error message: Expected to decode String but found a number instead
. The reason that it returns a number is because the id field is empty and when the id field is empty it defaults to returning 0 as an ID which codable identifies as a number. I can basically ignore the ID key but codable does not give me the option to ignore it to my knowledge. What would be the best way to handle this?
Here is the JSON. It is super simple
Working
{
"p":2.12,
"i":"3k3mkfnk3",
"n":"Blue Shirt"
}
Error - because there is no id in the system, it returns 0 as a default which codable obviously sees as a number opposed to string.
{
"p":2.19,
"i":0,
"n":"Black Shirt"
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
编辑/更新:
您也可以简单地将
nil
分配给id
当API返回时 0 :edit/update:
You can also simply assign
nil
to yourid
when your api returns0
:这是
MetadataType
的一个可能的解决方案,好处是它可以是一个通用解决方案,不仅适用于GeneralProduct
,而且适用于所有具有以下功能的struct
同样的歧义:这是测试:
This is a possible solution with
MetadataType
, the nice thing is that can be a general solution not forGeneralProduct
only, but for all thestruct
having the same ambiguity:this is the test:
从
Int
或String
无缝解码为同一属性需要编写一些代码。但是,由于语言中添加了(某种程度上)新的属性(属性包装器),您可以在需要的地方轻松重用此逻辑:
属性包装器及其支持代码可以像这样实现:
原始答案
您可以对字符串使用包装器,该包装器知道如何从任何基本 JSON 数据类型进行解码:字符串、数字、布尔值:
然后您可以在结构中使用此新类型。一个小缺点是该结构的使用者将需要进行另一个间接访问来访问包装的字符串。但是,可以通过将解码后的RelaxedString属性声明为私有属性并使用计算出的属性作为公共接口来避免这种情况:
上述方法的优点:
RelaxedString
可以在其他结构中无缝使用,GeneralProduct
的消费者不知道/关心 id 可以来自字符串或 intSeamlessly decoding from either
Int
orString
into the same property requires writing some code.However, thanks to a (somewhat) new addition to the language,(property wrappers), you can make it quite easy to reuse this logic wherever you need it:
The property wrapper and its supporting code can be implemented like this:
Original answer
You can use a wrapper over a string that knows how to decode from any of the basic JSON data types: string, number, boolean:
You can then use this new type in your struct. One minor disadvantage would be that consumer of the struct will need to make another indirection to access the wrapped string. However that can be avoided by declaring the decoded
RelaxedString
property as private, and use a computed one for the public interface:Advantages of the above approach:
init(from decoder: Decoder)
code, which can become tedious if the number of properties to be decoded increaseRelaxedString
can be seamlessly used in other structsGeneralProduct
don't know/care that the id can come from a string or an int我创建了这个 Gist,它有一个 ValueWrapper 结构可以处理
以下类型
https://gist.github.com/amrangry/89097b86514b3477cae79dd28bba3f23
I created this Gist which has a ValueWrapper struct that can handle
the following types
https://gist.github.com/amrangry/89097b86514b3477cae79dd28bba3f23
根据@cristik的答案,我使用
@propertywrapper
提供了另一种解决方案。用法也
像-i认为 -
Based on @Cristik 's answer, I come with another solution using
@propertyWrapper
.And usage is
Also works like -I think-
您可以使用此 pod https://github.com/muhammadali2012/Model
只需将这些属性包装器添加到您的可编码属性的类型不确定。即,
即使您从 JSON 中获取 int 或什至 nill 或即使 key 不存在,您也会获得 String 形式的 id。
you can use this pod https://github.com/muhammadali2012/Model
Simply add these property wrappers on your codable properties which type is not sure. ie
you will get id as String even if you get int from JSON or even nill or even if key doesn't exist.