Search code examples
swiftcombine

Swift: Swift combine with sync


import UIKit
import Combine

public func example(of: String, execute: () -> Void) {
    print("------ \(of) ------")
    execute()
}

example(of: "URLSession+Publisher") {
    guard let url = URL(string: "https://jsonplaceholder.typicode.com/todos/1") else { return }
    
    let _ = URLSession.shared
    .dataTaskPublisher(for: url)
    .sink(receiveCompletion: { completion in
        if case .failure(let error) = completion {
            print("Failed with error \(error)")
        } else {
           print("Success") 
        }
    }, receiveValue: { data, response in
        print("Data retrieved with size \(data.count), response = \(response)")
    })
}

This code does not print anything inside sync . I am trying to run it through playground and my xcode version is 12.5.1


Solution

  • Try this:

    import Combine
    import PlaygroundSupport
    import UIKit
    
    public func example(of: String, execute: () -> Void) {
        print("------ \(of) ------")
        execute()
    }
    
    var cancellable: Cancellable?
    
    example(of: "URLSession+Publisher") {
        guard let url = URL(string: "https://jsonplaceholder.typicode.com/todos/1") else { return }
    
        cancellable = URLSession.shared
            .dataTaskPublisher(for: url)
            .sink(receiveCompletion: { completion in
                if case .failure(let error) = completion {
                    print("Failed with error \(error)")
                } else {
                    print("Success")
                }
            }, receiveValue: { data, response in
                print("Data retrieved with size \(data.count), response = \(response)")
            })
    }
    
    PlaygroundPage.current.needsIndefiniteExecution = true
    

    You need to tell the playground page to keep running after the last line of code so it can wait for the server response and you need to store the cancellable.