Combine JSON 解码管道,当响应在运行时可以是数组或对象
Combine JSON decoding pipeline, when response can be an array or an object at runtime
我有一个 API 可以 return 一个 JSON 数组 JSON 对象或单个 JSON 对象。
如何编写处理这种情况的合并发布者管道?
当我将组合解码运算符添加到我的管道时,我通常硬编码 JSON 响应的类型:
.decode(type: [MyArrayType].self, decoder: JSONDecoder())
.decode(type: MyObjectType.self, decoder: JSONDecoder())
绝对有可能更新发布者链并尝试解码 [SomeDecodable]
的数组,如果失败,则退回到解码 SomeDecodable
本身。
模式是将其包装在 FlatMap
中,并处理其中的故障。
所以,假设您有一些 upstream
发布者,其输出为 Data
,失败为 Error
,并且您正在尝试解码一些通用类型 T: Decodable
,这可能是一种方法:
upstream
.flatMap { data in
Just(data)
// attempt to decode as [T]
.decode(type: [T].self, decoder: JSONDecoder())
// if successful, publish each element one-by-one
.flatMap { arr -> AnyPublisher<T, Error> in
Publishers.Sequence(sequence: arr).eraseToAnyPublisher()
}
// if error, attempt to decode as T, possibly failing
.tryCatch { _ in Just(data).decode(type: T.self, decoder: JSONDecoder()) }
}
// this will be an AnyPublisher<T, Error>
.eraseToAnyPublisher()
我有一个 API 可以 return 一个 JSON 数组 JSON 对象或单个 JSON 对象。
如何编写处理这种情况的合并发布者管道?
当我将组合解码运算符添加到我的管道时,我通常硬编码 JSON 响应的类型:
.decode(type: [MyArrayType].self, decoder: JSONDecoder())
.decode(type: MyObjectType.self, decoder: JSONDecoder())
绝对有可能更新发布者链并尝试解码 [SomeDecodable]
的数组,如果失败,则退回到解码 SomeDecodable
本身。
模式是将其包装在 FlatMap
中,并处理其中的故障。
所以,假设您有一些 upstream
发布者,其输出为 Data
,失败为 Error
,并且您正在尝试解码一些通用类型 T: Decodable
,这可能是一种方法:
upstream
.flatMap { data in
Just(data)
// attempt to decode as [T]
.decode(type: [T].self, decoder: JSONDecoder())
// if successful, publish each element one-by-one
.flatMap { arr -> AnyPublisher<T, Error> in
Publishers.Sequence(sequence: arr).eraseToAnyPublisher()
}
// if error, attempt to decode as T, possibly failing
.tryCatch { _ in Just(data).decode(type: T.self, decoder: JSONDecoder()) }
}
// this will be an AnyPublisher<T, Error>
.eraseToAnyPublisher()