I am trying to use Combine to perform a POST request. When doing my http request that I used before, my Credentials object comes back with status code 200, so all good. But when I am trying to use the Combine framework, it just returns an error.
finished with error [-999] Error Domain=NSURLErrorDomain Code=-999 "cancelled"
How to solve this issue to make my Combine POST request works as expected?
My Combine request that doesn't work and need to be fixed:
func demoLogin() -> AnyPublisher<Credentials, Error> {
let url = URL(string: "https://web-api/auth/create-demo-account")!
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = "POST"
return URLSession.shared
.dataTaskPublisher(for: urlRequest)
.receive(on: DispatchQueue.main)
.map(\.data)
.decode(
type: Credentials.self,
decoder: JSONDecoder())
.eraseToAnyPublisher()
}
So this is where I sink the value:
final class OnboardingViewModel: ObservableObject {
private var subscriptions = Set<AnyCancellable>()
func demoLogin() {
AuthRequest.shared.demoLogin()
.sink(
receiveCompletion: { print($0) },
receiveValue: {
print("Receive value:\nLogin: \($0.login)\nToken: \($0.token)") })
.store(in: &subscriptions)
}
}
This is the SwiftUI view where the button asks for the call:
struct CredentialsButtons: View {
@ObservedObject var viewModel = OnboardingViewModel()
var body: some View {
VStack {
Button(action: { self.viewModel.demoLogin() }) {
Text("Try demo")
.font(.subheadline)
.fontWeight(.medium)
.foregroundColor(.blue)
}
}
}
}
My request that works normally:
func demoLogin(completion: @escaping (NetworkResult<Credentials>) -> Void) {
let url = URL(string: "https://web-api/auth/create-demo-account")!
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = "POST"
let dataTask = authSession.dataTask(with: urlRequest) { data, response, error in
guard let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode == 200,
let jsonData = data else {
completion(.failure)
return
}
do {
let credentials = try JSONDecoder().decode(Credentials.self, from: jsonData)
completion(.success(credentials))
}
catch {
completion(.failure)
}
}
dataTask.resume()
}