使用 Combine 在应用程序激活时触发下载而不是编译
Using Combine to trigger download on app activation not compiling
我正尝试在我的应用程序激活时触发下载,但我不知道该怎么做。
这是我的代码
NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification).map{ _ in
return self.urlSession.dataTaskPublisher(for: url)
}
.tryMap{ element in
guard let httpResponse = element.response as? HTTPURLResponse,
httpResponse.statusCode == 200 else {
throw URLError(.badServerResponse)
}
.....
我不知道如何让它工作。我经常收到编译错误:
Value of type 'URLSession.DataTaskPublisher' has no member 'response'
为什么我的 return 语句 return 是完整的发布者而不是其结果?
如果我删除 NotificationCenter
部分并直接在 dataTaskPublisher
上调用 tryMap
,如下所示:
self.urlSession.dataTaskPublisher(for: url)
.tryMap{ element in
编译器没有抱怨。
这里很困惑 :)
Why does my return statement return the complete publisher and not its result?
它 return 是完整的发布者,因为,嗯,你告诉它 return 完整的发布者。 map
的 Output
是 map
转换 return 的任何内容。您的 map
将 return 转换为 DataTaskPublisher
,因此 map
的 Output
为 DataTaskPublisher
。因此 Input
到 tryMap
——element
变量的类型——是一个 DataTaskPublisher
。粗略地说,map
之后(tryMap
之前)的类型是
Publisher<Publisher<(data: Data, response: URLResponse), URLError>, Never>
(这不是真正的类型,因为 Publisher
不是真正的类型构造函数。)
你想要的是将其扁平化为
Publisher<(data: Data, response: URLResponse), Error>
您需要使用 setFailureType(to:)
将通知发布者的失败类型从 Never
转换为 Error
。并且您需要使用 mapError
将 DataTaskPublisher
的故障类型从 URLError
转换为 Error
。
匹配失败类型后,有几个运算符可以展平嵌套的发布者。您要找的可能是 switchToLatest
:
func data(for url: URL) -> AnyPublisher<Data, Error> {
NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)
.setFailureType(to: Error.self)
.map({ _ in
self.urlSession.dataTaskPublisher(for: url)
.mapError { [=12=] as Error }
})
.switchToLatest()
.tryMap({ element in
guard let httpResponse = element.response as? HTTPURLResponse,
httpResponse.statusCode == 200 else {
throw URLError(.badServerResponse)
}
return element.data
})
.eraseToAnyPublisher()
}
我正尝试在我的应用程序激活时触发下载,但我不知道该怎么做。
这是我的代码
NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification).map{ _ in
return self.urlSession.dataTaskPublisher(for: url)
}
.tryMap{ element in
guard let httpResponse = element.response as? HTTPURLResponse,
httpResponse.statusCode == 200 else {
throw URLError(.badServerResponse)
}
.....
我不知道如何让它工作。我经常收到编译错误:
Value of type 'URLSession.DataTaskPublisher' has no member 'response'
为什么我的 return 语句 return 是完整的发布者而不是其结果?
如果我删除 NotificationCenter
部分并直接在 dataTaskPublisher
上调用 tryMap
,如下所示:
self.urlSession.dataTaskPublisher(for: url)
.tryMap{ element in
编译器没有抱怨。
这里很困惑 :)
Why does my return statement return the complete publisher and not its result?
它 return 是完整的发布者,因为,嗯,你告诉它 return 完整的发布者。 map
的 Output
是 map
转换 return 的任何内容。您的 map
将 return 转换为 DataTaskPublisher
,因此 map
的 Output
为 DataTaskPublisher
。因此 Input
到 tryMap
——element
变量的类型——是一个 DataTaskPublisher
。粗略地说,map
之后(tryMap
之前)的类型是
Publisher<Publisher<(data: Data, response: URLResponse), URLError>, Never>
(这不是真正的类型,因为 Publisher
不是真正的类型构造函数。)
你想要的是将其扁平化为
Publisher<(data: Data, response: URLResponse), Error>
您需要使用 setFailureType(to:)
将通知发布者的失败类型从 Never
转换为 Error
。并且您需要使用 mapError
将 DataTaskPublisher
的故障类型从 URLError
转换为 Error
。
匹配失败类型后,有几个运算符可以展平嵌套的发布者。您要找的可能是 switchToLatest
:
func data(for url: URL) -> AnyPublisher<Data, Error> {
NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)
.setFailureType(to: Error.self)
.map({ _ in
self.urlSession.dataTaskPublisher(for: url)
.mapError { [=12=] as Error }
})
.switchToLatest()
.tryMap({ element in
guard let httpResponse = element.response as? HTTPURLResponse,
httpResponse.statusCode == 200 else {
throw URLError(.badServerResponse)
}
return element.data
})
.eraseToAnyPublisher()
}