bruno
bruno

Reputation: 2169

Unable to do a urlSession request with Combine

Unable to get Data using Combine, nothing is printed on the console.

struct RepositoryElement: Codable {}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let url = URL(string: "https://api.github.com/users/brunosilva808/repos")!

        let repos = URLSession.shared.dataTaskPublisher(for: url)
            .map { $0.data }
            .decode(type: [Repository].self, decoder: JSONDecoder())
            .sink(receiveCompletion: { completion in // 5
                print(completion)
            }, receiveValue: { repositories in
                print("brunosilva808 has \(repositories.count) repositories")
            })
    }
}

Upvotes: 0

Views: 53

Answers (1)

Andrew
Andrew

Reputation: 28539

It's not working because your repo variable is going out of scope and thus your network request is being cancelled. You need to hold on to your request so make a variable in your ViewController to keep hold of it.

If you do something like this then it should work. You'll need to import Combine because AnyCancellable is part of Combine.

import Combine

class ViewController: UIViewController {

    var cancellable: AnyCancellable?

    override func viewDidLoad() {
        super.viewDidLoad()

        let url = URL(string: "https://api.github.com/users/brunosilva808/repos")!

        cancellable = URLSession.shared.dataTaskPublisher(for: url)
            .map { $0.data }
            .decode(type: [Repository].self, decoder: JSONDecoder())
            .sink(receiveCompletion: { completion in // 5
                print(completion)
            }, receiveValue: { repositories in
                print("brunosilva808 has \(repositories.count) repositories")
            })

    }
}

I couldn't check if it decodes properly because you didn't include the Repository struct.

Upvotes: 1

Related Questions