iOS - 合并 - 将发布商类型更改为子类型
iOS - Combine - Change Publisher type to child type
我有这两个 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 并使用这些方法将其解码为父对象:
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()
}
它有效,但我想要一种方法来检索子数组,而不是父对象,如下所示:
func children(_ url: String) -> AnyPublisher<[Child], Error>
但我不知道我需要更改什么.. 任何帮助将不胜感激,谢谢!
您只需调用 parent
函数并在其 Publisher
上调用 map
即可取回其 children
属性.
func children(from url: String) -> AnyPublisher<[Child], Error> {
return parent(url)
.map(\.children)
.eraseToAnyPublisher()
}
与您的问题无关,但我建议摆脱您的 Result
类型。首先,它与Swift的内置Result
类型冲突。其次,存储 URLResponse
以防网络请求成功,returned 有效数据并没有真正增加任何价值。 URLResponse
主要在失败或请求没有 return 值但成功响应代码(200、206 等)时保留值。
更新:如果您想摆脱 parent(_:)
方法,只需将 map(\.children)
调用链接到原始 parent(_:)
方法的内容即可。为了让编译器推断 dataFromURL(_:)
方法的泛型 return 类型,您只需在第二个 map
调用中将 KeyPath
指定为 \Parent.children
.
func children(from url: String) -> AnyPublisher<[Child], Error> {
return dataFromURL(url)
.map(\.value)
.map(\Parent.children)
.eraseToAnyPublisher()
}
我有这两个 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 并使用这些方法将其解码为父对象:
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()
}
它有效,但我想要一种方法来检索子数组,而不是父对象,如下所示:
func children(_ url: String) -> AnyPublisher<[Child], Error>
但我不知道我需要更改什么.. 任何帮助将不胜感激,谢谢!
您只需调用 parent
函数并在其 Publisher
上调用 map
即可取回其 children
属性.
func children(from url: String) -> AnyPublisher<[Child], Error> {
return parent(url)
.map(\.children)
.eraseToAnyPublisher()
}
与您的问题无关,但我建议摆脱您的 Result
类型。首先,它与Swift的内置Result
类型冲突。其次,存储 URLResponse
以防网络请求成功,returned 有效数据并没有真正增加任何价值。 URLResponse
主要在失败或请求没有 return 值但成功响应代码(200、206 等)时保留值。
更新:如果您想摆脱 parent(_:)
方法,只需将 map(\.children)
调用链接到原始 parent(_:)
方法的内容即可。为了让编译器推断 dataFromURL(_:)
方法的泛型 return 类型,您只需在第二个 map
调用中将 KeyPath
指定为 \Parent.children
.
func children(from url: String) -> AnyPublisher<[Child], Error> {
return dataFromURL(url)
.map(\.value)
.map(\Parent.children)
.eraseToAnyPublisher()
}