Swift 如何在请求同一链中的dataTaskPublisher时使用来自一个发布者的值?
我是一个新的组合,并试图找出如何连锁出版商。我有一个发布服务器,它返回一个字符串值,我想用这个字符串值来构建一个URLRequest,而URLRequest又被传递给DataTaskPublisher。如果您有任何关于正确语法的帮助,我们将不胜感激 示例代码:Swift 如何在请求同一链中的dataTaskPublisher时使用来自一个发布者的值?,swift,combine,Swift,Combine,我是一个新的组合,并试图找出如何连锁出版商。我有一个发布服务器,它返回一个字符串值,我想用这个字符串值来构建一个URLRequest,而URLRequest又被传递给DataTaskPublisher。如果您有任何关于正确语法的帮助,我们将不胜感激 示例代码: struct ResultObject: Decodable {} func getValueKey() -> AnyPublisher<String, Error> { return Just("T
struct ResultObject: Decodable {}
func getValueKey() -> AnyPublisher<String, Error> {
return Just("Test")
.setFailureType(to: Error.self)
.eraseToAnyPublisher()
}
func performSearch(_ searchTerm: String) -> AnyPublisher<[ResultObject], Error> {
return getValueKey().flatMap { valueKey in
let request: URLRequest = URLRequest(url: URL(string: "http://www.test.com/\(valueKey)")!)
return URLSession.shared.dataTaskPublisher(for: request)
.map { $0.data }
.decode(type: [ResultObject].self, decoder: JSONDecoder())
}
.eraseToAnyPublisher() /* Error: Type of expression is ambiguous without more context */
}
struct ResultObject:Decodable{}
func getValueKey()->AnyPublisher{
仅返回(“测试”)
.setFailureType(收件人:Error.self)
.删除任何发布者()
}
func performSearch(searchTerm:String)->AnyPublisher{
返回getValueKey().flatMap{valueKey in
let request:URLRequest=URLRequest(url:url(字符串):http://www.test.com/\(valueKey)“)!)
返回URLSession.shared.dataTaskPublisher(用于:请求)
.map{$0.data}
.decode(类型:[ResultObject].self,解码器:JSONDecoder())
}
.橡皮擦AnyPublisher()/*错误:表达式类型不明确,没有更多上下文*/
}
注意:我非常不确定最后一个橡皮擦到任何出版商的位置
您有两个问题
首先,您给了flatMap
的形式参数名称valueKey
,但后来您尝试使用名称值
引用它。这些需要匹配
其次,Swift无法推断多语句函数的返回类型,比如传递给flatMap
的闭包。(它可以将参数类型推断为getValueKey
返回的发布服务器的Output
类型)
解决此问题的一般方法有两种:
- 更改代码,使闭包只包含一条语句,或
- 显式地给出返回类型
map
运算符将传入的String
转换为URLRequest
,如下所示:
func performSearch(_ searchTerm: String) -> AnyPublisher<[ResultObject], Error> {
return getValueKey()
.map { URLRequest(url: URL(string: "http://www.test.com/\($0)")!) }
.flatMap {
return URLSession.shared.dataTaskPublisher(for: $0)
.map { $0.data }
.decode(type: [ResultObject].self, decoder: JSONDecoder())
}
.eraseToAnyPublisher()
}
我提到的另一种方法是使闭包的返回类型显式。这很棘手,因为返回类型很复杂。您需要向右滚动才能看到整个内容:
func performSearch0(_ searchTerm: String) -> AnyPublisher<[ResultObject], Error> {
return getValueKey().flatMap { value -> Publishers.Decode<Publishers.Map<URLSession.DataTaskPublisher, Data>, [ResultObject], JSONDecoder> in
let request: URLRequest = URLRequest(url: URL(string: "http://www.test.com/\(value)")!)
return URLSession.shared.dataTaskPublisher(for: request)
.map { $0.data }
.decode(type: [ResultObject].self, decoder: JSONDecoder())
}
.eraseToAnyPublisher()
}
你有两个问题
首先,您给了flatMap
的形式参数名称valueKey
,但后来您尝试使用名称值
引用它。这些需要匹配
其次,Swift无法推断多语句函数的返回类型,比如传递给flatMap
的闭包。(它可以将参数类型推断为getValueKey
返回的发布服务器的Output
类型)
解决此问题的一般方法有两种:
- 更改代码,使闭包只包含一条语句,或
- 显式地给出返回类型
map
运算符将传入的String
转换为URLRequest
,如下所示:
func performSearch(_ searchTerm: String) -> AnyPublisher<[ResultObject], Error> {
return getValueKey()
.map { URLRequest(url: URL(string: "http://www.test.com/\($0)")!) }
.flatMap {
return URLSession.shared.dataTaskPublisher(for: $0)
.map { $0.data }
.decode(type: [ResultObject].self, decoder: JSONDecoder())
}
.eraseToAnyPublisher()
}
我提到的另一种方法是使闭包的返回类型显式。这很棘手,因为返回类型很复杂。您需要向右滚动才能看到整个内容:
func performSearch0(_ searchTerm: String) -> AnyPublisher<[ResultObject], Error> {
return getValueKey().flatMap { value -> Publishers.Decode<Publishers.Map<URLSession.DataTaskPublisher, Data>, [ResultObject], JSONDecoder> in
let request: URLRequest = URLRequest(url: URL(string: "http://www.test.com/\(value)")!)
return URLSession.shared.dataTaskPublisher(for: request)
.map { $0.data }
.decode(type: [ResultObject].self, decoder: JSONDecoder())
}
.eraseToAnyPublisher()
}
非常感谢您给出如此完整的答案!非常感谢您给出如此完整的答案!