I;m learning SwiftUI and Alamofire. I created a demo APP like this:
import SwiftUI
import Alamofire
struct ContentView: View {
var body: some View {
Text("Hello, world!")
.padding()
.onAppear(perform: load)
}
struct TestResponse: Decodable {
let userId: Int
let id: Int
let title: String
let body: String
}
func load(){
AF.request("https://jsonplaceholder.typicode.com/posts", method: .get, parameters: nil)
.validate()
.publishDecodable(type: [TestResponse].self)
.print()
.sink { print($0) }
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
But I got this output:
receive subscription: (Alamofire.DataResponsePublisher<Swift.Array<Test.ContentView.TestResponse>>.(unknown context at $1080f8314).Inner<Combine.Publishers.Print<Alamofire.DataResponsePublisher<Swift.Array<Test.ContentView.TestResponse>>>.(unknown context at $7ff81332d748).Inner<Combine.Subscribers.Sink<Alamofire.DataResponse<Swift.Array<Test.ContentView.TestResponse>, Alamofire.AFError>, Swift.Never>>>)
request unlimited
receive cancel
receive value: (failure(Alamofire.AFError.explicitlyCancelled))
receive finished
if I use the .response
to receive the data, everything is ok.
Thanks for any help.
CodePudding user response:
You need to store the token returned by sink
(which you're likely getting a compiler warning about). Otherwise the publisher you created is immediately cancelled and the underlying request is cancelled as well. You can use a Set<AnyCancellable>
to and sink {}.store(in: &set)
, or find an alternate solution. For SwiftUI you'll likely want to put your networking in some sort of model object, not the view.