在使用Swift4和Codable协议时,我遇到了以下问题-似乎没有办法允许JSONDecoder
跳过数组中的元素。例如,我有以下JSON:
[
{
"name": "Banana",
"points": 200,
"description": "A banana grown in Ecuador."
},
{
"name": "Orange"
}
]
和一个可 编码的 结构:
struct GroceryProduct: Codable {
var name: String
var points: Int
var description: String?
}
解码此json时
let decoder = JSONDecoder()
let products = try decoder.decode([GroceryProduct].self, from: json)
结果products
为空。这是可以预期的,因为JSON中的第二个对象没有"points"
键,而points
在GroceryProduct
struct中不是可选的。
问题是如何允许JSONDecoder
“跳过”无效对象?
一种选择是使用包装器类型,尝试对给定值进行解码。nil
如果不成功,则存储:
struct FailableDecodable<Base : Decodable> : Decodable {
let base: Base?
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
self.base = try? container.decode(Base.self)
}
}
然后,我们可以解码这些数组,并GroceryProduct
在Base
占位符中填写以下内容:
import Foundation
let json = """
[
{
"name": "Banana",
"points": 200,
"description": "A banana grown in Ecuador."
},
{
"name": "Orange"
}
]
""".data(using: .utf8)!
struct GroceryProduct : Codable {
var name: String
var points: Int
var description: String?
}
let products = try JSONDecoder()
.decode([FailableDecodable<GroceryProduct>].self, from: json)
.compactMap { $0.base } // .flatMap in Swift 4.0
print(products)
// [
// GroceryProduct(
// name: "Banana", points: 200,
// description: Optional("A banana grown in Ecuador.")
// )
// ]
然后,我们.compactMap { $0.base }
用于过滤掉nil
元素(那些在解码时引发错误的元素)。
这将创建的中间数组[FailableDecodable<GroceryProduct>]
,这不应该成为问题;但是,如果您希望避免这种情况,可以始终创建另一个包装器类型,该类型将解码和解包来自无键容器的每个元素:
struct FailableCodableArray<Element : Codable> : Codable {
var elements: [Element]
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
var elements = [Element]()
if let count = container.count {
elements.reserveCapacity(count)
}
while !container.isAtEnd {
if let element = try container
.decode(FailableDecodable<Element>.self).base {
elements.append(element)
}
}
self.elements = elements
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(elements)
}
}
然后,您将解码为:
let products = try JSONDecoder()
.decode(FailableCodableArray<GroceryProduct>.self, from: json)
.elements
print(products)
// [
// GroceryProduct(
// name: "Banana", points: 200,
// description: Optional("A banana grown in Ecuador.")
// )
// ]
我正在尝试与RESTful API接口,该API在post中接受应用程序/x-protobuf对象。 .原型示例对象: 使用请求,我可以将此消息发布到服务器并收到200。 例如 当我以SerializeToString()格式查看此有效负载时,它显示类似于 b'\n\t\n\x03foo\x10\x01' 作为健全性检查,然后我可以创建一个新的消息对象和。将其上的ParseFromString()
我正在编写一个解组器,我正在努力与jaxb进行斗争,以获得一个有效的解决方案。 我想解组从生成的MessageDescription。wsdl文件。wsdl文件中的java类是: 由于没有@XmlRootElement,我用包装器扩展了类,并自己添加了注释 我使用我的“包装器”MessageDescription类来解组 解组过程正在工作,但有一个子项始终设置为null。我不知道在哪里可以修复这个
我收到一个作为当前href的一部分。它是用base64编码的。我尝试使用对其进行解码,但得到以下错误: 在“window”上执行“atob”失败:要解码的字符串编码不正确 当我在代码中复制并粘贴提取的并转到一个在线解码站点时,它会正确解码。你有什么建议吗?
这篇文章是关于前一个问题的解决方案: OptaPlanner-两个规划实体类的求解器配置问题 这是错误:
我试图将我的网页连接到我的Lex机器人使用来自AWS SDK for PHP的postContent。 ‘在“https://runtime.lex.us-east-1.amazonaws.com/bot/xxxx/alias/xxx/user/xxxxxxxx/content”上执行“postContent”时出错; AWS HTTP错误:客户端错误:导致响应:{“消息”:“无效请求:未能解码会
早上好,我试图在我们的代码中找到一个错误,关于当xml没有被格式化时使用JAXB解组XML。我已经做了很多调试和测试,但仍然找不到错误。 xml的解释部分如下所示: 列表最多可包含50.000<代码> 为此,我们有以下代码。解组器的创建被移动到一个接口,以区别我们希望通过jaxb解组的元素,包括子元素(如元素)和那些(如