我有这两个Codable对象:
struct Parent: Codable {
let name: String
let children: [Child]
}
struct Child: Codable {
let name: String
}
我为匹配此json而创建的
{
name: "test"
children: (
{
name: "test2"
},
{
name: "test3"
}
)
}
我使用以下方法检索json并将其解码为Parent对象:
func parent(_ url: String) -> AnyPublisher<Parent, Error> {
return dataFromURL(url)
.map(\.value)
.eraseToAnyPublisher()
}
struct Result<T> {
let value: T
let response: URLResponse
}
func dataFromURL<T: Decodable>(_ url: String, _ decoder: JSONDecoder = JSONDecoder()) -> AnyPublisher<Result<T>, Error> {
let request = URLRequest(url: URL(string:url)!)
return URLSession.shared
.dataTaskPublisher(for: request)
.tryMap { result -> Result<T> in
let value = try decoder.decode(T.self, from: result.data)
return Result(value: value, response: result.response)
}
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
它可以工作,但是我想要一种方法来检索子级数组,而不是像这样的Parent对象:
func children(_ url: String) -> AnyPublisher<[Child], Error>
但是我不知道我需要改变什么。任何帮助,我们都会感激的,谢谢!
答案 0 :(得分:4)
您只需要调用parent
函数并在其map
上调用Publisher
即可恢复其children
属性。
func children(from url: String) -> AnyPublisher<[Child], Error> {
return parent(url)
.map(\.children)
.eraseToAnyPublisher()
}
与您的问题无关,但我建议您摆脱您的Result
类型。首先,它与Swift的内置Result
类型冲突。其次,在成功的网络请求的情况下存储URLResponse
,返回有效数据并不会真正增加任何值。 URLResponse
主要在失败或请求未返回值的情况下保留值,而是成功响应代码(200、206等)。
更新:如果要摆脱parent(_:)
方法,只需将map(\.children)
调用链接到原始parent(_:)
方法的内容即可。为了让编译器推断dataFromURL(_:)
方法的通用返回类型,您只需要在第二个KeyPath
调用中将\Parent.children
指定为map
。
func children(from url: String) -> AnyPublisher<[Child], Error> {
return dataFromURL(url)
.map(\.value)
.map(\Parent.children)
.eraseToAnyPublisher()
}