Hey,
I want to request https://swift.org
. If I do not assign the result of the publisher/subject sink(receiveCompletion:receiveValue:)
of type AnyCancellable
, the request will not executed.
Do you know if this behaviour is correct? Or does the compiler removes this code?
import SwiftUI
import Combine
struct ContentView: View {
@ObservedObject private var viewModel = ViewModel()
var body: some View {
Form {
Text(self.viewModel.content)
Text(self.viewModel.output)
Button("noVar") {
self.viewModel.noVar()
}
Button("variable") {
self.viewModel.variable()
}
}
}
}
final class ViewModel: ObservableObject {
@Published var content = "Loading swift.org"
@Published var output = "no output"
private var cancellable: AnyCancellable! = nil
func noVar() {
self.output = "noVar start"
_ = URLSession.shared.dataTaskPublisher(for: URL(string: "https://swift.org")!) //never called
.receive(on: RunLoop.main)
.tryMap { (data, response) in
self.output = "_gotRespond"
let result = String(data: data, encoding: .utf8)!
print(result) // no print
self.output = "_isOnline \(result)"
return result
}
.mapError { error -> Error in
self.output = error.localizedDescription
return error
}
.sink { completion in
switch completion {
case .failure(let error):
self.output = error.localizedDescription
case .finished:
self.output = "noVar ends"
}
} receiveValue: {
self.content = $0
}
}
func variable() {
self.output = "variable"
self.cancellable = URLSession.shared.dataTaskPublisher(for: URL(string: "https://swift.org")!)
.receive(on: RunLoop.main)
.tryMap { (data, response) in
self.output = "v_gotRespond"
let result = String(data: data, encoding: .utf8)!
print(result)
self.output = "v_isOnline \(result)"
return result
}
.mapError { error -> Error in
self.output = error.localizedDescription
return error
}
.replaceError(with: "v_Error printed")
.assign(to: \.content, on: self)
}
deinit {
print("canceling")
self.cancellable.cancel()
}
}