I have following APILoader struct in my network layer.
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. But this is working for non combine traditional API calls.
When I use instance variable of URLSession.shared like follows, it's start working.
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.
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:
does return an
AnyCancellablethat needs to be stored. For now you closure just goes out of scope. So where ever this function lives that object needs to store a reference to yourAnyCancellable:But:
as your example code does not include a reproducible example there might be more going on.