[英]URLSession.shared struct property isn't working for Combine API call
I have following APILoader struct in my network layer.我的网络层中有以下 APILoader 结构。
struct APILoader<T: APIHandler> {
var apiHandler: T
var urlSession: URLSession
init(apiHandler: T, urlSession: URLSession = .shared) {
self.apiHandler = apiHandler
self.urlSession = urlSession
}
func loadAPIRequest(requestData: T.RequestDataType) -> AnyPublisher<T.ResponseDataType, Error> {
guard let urlRequest = apiHandler.makeRequest(from: requestData) else {
return Result<T.ResponseDataType, Error>.failure(NSError(domain: "", code: -1, userInfo: ["dte":1])).publisher.eraseToAnyPublisher()
}
return urlSession.dataTaskPublisher(for: urlRequest)
.map() {
$0.data
}
.decode(type: T.ResponseDataType.self, decoder: JSONDecoder())
.receive(on: RunLoop.main)
.eraseToAnyPublisher()
}
}
When I use urlSession
struct property to call dataTaskPublisher(for: urlRequest)
method, it's not working.当我使用
urlSession
结构属性调用dataTaskPublisher(for: urlRequest)
方法时,它不起作用。 But this is working for non combine traditional API calls.但这适用于非结合传统的 API 调用。 When I use instance variable of
URLSession.shared
like follows, it's start working.当我如下使用
URLSession.shared
的实例变量时,它开始工作。
return URLSession.shared.dataTaskPublisher(for: urlRequest)
.map() {
$0.data
}
.decode(type: T.ResponseDataType.self, decoder: JSONDecoder())
.receive(on: RunLoop.main)
.eraseToAnyPublisher()
Following code shows how I init the APILoader and call the web service.以下代码显示了我如何初始化 APILoader 并调用 web 服务。
func getData() {
let request = TopStoriesService()
let params = [Params.kApiKey.rawValue : CommonUtil.shared.NytApiKey()]
let apiLoader = APILoader(apiHandler: request)
apiLoader.loadAPIRequest(requestData: params)
.sink(receiveCompletion: { _ in },
receiveValue: { res in
print("\(res)")
})
}
Can anyone explain what I'm missing here?谁能解释我在这里缺少什么?
You are not holding on to your publisher.你没有坚持你的出版商。 This code:
这段代码:
apiLoader.loadAPIRequest(requestData: params)
.sink(receiveCompletion: { _ in },
receiveValue: { res in
print("\(res)")
})
does return an AnyCancellable
that needs to be stored.确实返回需要存储的
AnyCancellable
。 For now you closure just goes out of scope.现在你的关闭刚刚超出 scope。 So where ever this function lives that object needs to store a reference to your
AnyCancellable
:所以这个 function 生活在哪里, object 需要存储对
AnyCancellable
的引用:
// in class or struct scope
var cancellable: AnyCancellable?
// in your function
cancellable = apiLoader.loadAPIRequest(requestData: params)
.sink(receiveCompletion: { _ in },
receiveValue: { res in
print("\(res)")
})
as your example code does not include a reproducible example there might be more going on.由于您的示例代码不包含可重现的示例,因此可能会发生更多情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.