'How to merge two publishers with Combine?
I have an token publisher. It returns a token value as string. I want to make a request using this token in request publisher. I have no idea how to do it. Maybe these codes will help.
Token Transactions:
// Token Publisher
func getAccessToken() -> AnyPublisher<String, Error> {
let url = "it doesn't matter"
var urlRequest = URLRequest(url: url)
// some url request setups
// ...
return URLSession.shared
.dataTaskPublisher(for: urlRequest)
.map(\.data)
.decode(type: AccessToken.self, decoder: JSONDecoder())
.map({ $0.token ?? "" })
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
Generic Request Transactions:
// Request Publisher (The T is decodable generic type.)
func request<T: Decodable>(ofType: T.Type, apiURL: APIURL, method: HTTPMethods) -> AnyPublisher<T, Error> {
// This flatMap is not invoked. :/
AuthManager.shared.getAccessToken()
.flatMap({ accessToken -> AnyPublisher<T, Error> in
guard let url = URL(string: apiURL.url) else {
return Fail(error: NSError(domain: "Missing API URL", code: -10001, userInfo: nil)).eraseToAnyPublisher()
}
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = method.rawValue
urlRequest.setValue("Authorization", forHTTPHeaderField: "Bearer " + accessToken)
return URLSession.shared
.dataTaskPublisher(for: urlRequest)
.map(\.data)
.decode(type: T.self, decoder: JSONDecoder())
.eraseToAnyPublisher()
}).eraseToAnyPublisher()
}
Example Request Transactions:
// Example Request
private var cancellables = Set<AnyCancellable>()
func getExampleRequest(id: String) {
let url = "it doesn't matter"
APIManager.shared.request(ofType: ExampleModel.self, apiURL: url, method: .get).sink { completion in
switch completion {
case .finished:
break
case .failure(let error):
print(error)
}
} receiveValue: { exampleModelData in
// print(exampleModelData)
}.store(in: &cancellables)
}
Thanks in advance.
Solution 1:[1]
What you have here is a runtime problem that isn't reproducible given the code you presented. I can't give you an answer but I can help you find the problem.
The .print() operator is your friend. put it just before the flatMap and you should see that you aren't getting a next event, but you will likely see that you are getting a canceled or finished event.
If you are getting a finished event, move the print operator up the publisher chain until you figure out where the problem is. If you are getting a cancelled event, check to see why your cancellable is being deinted before completion.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
