I'm wondering if there is a way to implement reconnection mechanism with new Apple framework Combine and use of URLSession publisher
- tried to find some examples in WWDC 2019
- tried to play with
waitsForConnectivitywith no luck (it even not calling delegate on custom session) - tried
URLSession.backgroundbut it crashed during publishing.
I'm also not understanding how do we track progress in this way
Does anyone already tried to do smth like this?
upd:
It seems like waitsForConnectivity is not working in Xcode 11 Beta
upd2:
Xcode 11 GM - waitsForConnectivity is working but ONLY on device. Use default session, set the flag and implement session delegate. Method task is waiting for connectivity will be invoked no matter if u r using init task with callback or without.
public class DriverService: NSObject, ObservableObject { public var decoder = JSONDecoder() public private(set) var isOnline = CurrentValueSubject<Bool, Never>(true) private var subs = Set<AnyCancellable>() private var base: URLComponents private lazy var session: URLSession = { let config = URLSessionConfiguration.default config.waitsForConnectivity = true return URLSession(configuration: config, delegate: self, delegateQueue: nil) }() public init(host: String, port: Int) { base = URLComponents() base.scheme = "http" base.host = host base.port = port super.init() // Simulate online/offline state // // let pub = Timer.publish(every: 3.0, on: .current, in: .default) // pub.sink { _ in // let rnd = Int.random(in: 0...1) // self.isOnline.send(rnd == 1) // }.store(in: &subs) // pub.connect() } public func publisher<T>(for driverRequest: Request<T>) -> AnyPublisher<T, Error> { var components = base components.path = driverRequest.path var request = URLRequest(url: components.url!) request.httpMethod = driverRequest.method return Future<(data: Data, response: URLResponse), Error> { (complete) in let task = self.session.dataTask(with: request) { (data, response, error) in if let err = error { complete(.failure(err)) } else { complete(.success((data!, response!))) } self.isOnline.send(true) } task.resume() } .map({ $0.data }) .decode(type: T.self, decoder: decoder) .eraseToAnyPublisher() } } extension DriverService: URLSessionTaskDelegate { public func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) { self.isOnline.send(false) } }