configure session to wait for connectivity

I was asked something about this but unfortunaitly I did not achieve any thing with answers.

I want to configure session to wait for connectivity, If I turn wifi off, the function when waiting is implemented..


func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) {
        // waiting for connectivity, update UI, etc.
    }


This function is implemented successfully when wifi is off, but when I turn back wifi on , task with this session doesn't implemented.

why?


this is my all code:


class AddReserve: UIViewController, URLSessionDelegate,URLSessionTaskDelegate {

private lazy var session: URLSession = {
        let configuration = URLSessionConfiguration.default
        configuration.waitsForConnectivity = true
        return URLSession(configuration: configuration,
                          delegate: self, delegateQueue: nil)
    }()
  
    @IBAction func done(_ sender: Any) 
   { 
        let task = session.dataTask(with: URL(string: "https://www.google.com")!)
        { data, response, error in
            guard let data = data else
            {
                return
            }
               self.postReserve()
         }
        task.resume()
    }

    func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) {
        // waiting for connectivity, update UI, etc.
    }
}

Accepted Reply

This is working for me. I’m out of the office, so I can’t test with Wi-Fi, so I tested with WWAN instead. Here’s what I did:

  1. I built a small app based on the code you posted. The full source code for my main view controller is pasted in below.

  2. I ran it on a device with Wi-Fi disabled and WWAN active.

  3. I start a request. It ran immediately.

    2019-02-19 09:33:37.382805+0000 xxsi[1903:1263622] task will start
    2019-02-19 09:33:38.151233+0000 xxsi[1903:1263622] task finished with status 200, bytes 1270

    .

  4. I disabled WWAN.

  5. I started a request. It waiting for connectivity.

    2019-02-19 09:34:05.804564+0000 xxsi[1903:1263622] task will start
    2019-02-19 09:34:05.812003+0000 xxsi[1903:1263622] task is waiting

    .

  6. I re-enabled WWAN. The waiting request ran to completion.

    2019-02-19 09:34:10.111516+0000 xxsi[1903:1263622] task finished with status 200, bytes 1270

    .

There’s a few places where my code is different from yours:

  • I disabled HTTP caching on the session, because that just confuses tests like this.

  • I configured the session to run callbacks on the main thread, just to avoid any confusion.

  • I handled the completion handler parameters correctly, looking at

    error
    first, before looking at
    response
    or
    data
    .

This is testing with the latest GM tools (Xcode 10.1) on the latest GM iOS (12.1.4).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
import UIKit

class MainViewController : UIViewController, URLSessionTaskDelegate {

    private lazy var session: URLSession = {
        let configuration = URLSessionConfiguration.default
        configuration.requestCachePolicy = .reloadIgnoringLocalCacheData
        configuration.waitsForConnectivity = true
        return URLSession(configuration: configuration, delegate: self, delegateQueue: .main)
    }()

    private func start() {
        NSLog("task will start")
        let url = URL(string: "https://example.com")!
        let task = session.dataTask(with: url) { data, response, error in
            if let error = error as NSError? {
                NSLog("task transport error %@ / %d", error.domain, error.code)
                return
            }
            let response = response as! HTTPURLResponse
            let data = data!
            NSLog("task finished with status %d, bytes %d", response.statusCode, data.count)
        }
        task.resume()
    }

    func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) {
        NSLog("task is waiting")
    }

    … an @IBAction that calls `start` …
}

Replies

sessions doens't implemented


What do you mean ?

I suppose you mean something is not called. What ?

I mean the task doesn't working when turn back wifi on.

Please, I need help for this issue

This is working for me. I’m out of the office, so I can’t test with Wi-Fi, so I tested with WWAN instead. Here’s what I did:

  1. I built a small app based on the code you posted. The full source code for my main view controller is pasted in below.

  2. I ran it on a device with Wi-Fi disabled and WWAN active.

  3. I start a request. It ran immediately.

    2019-02-19 09:33:37.382805+0000 xxsi[1903:1263622] task will start
    2019-02-19 09:33:38.151233+0000 xxsi[1903:1263622] task finished with status 200, bytes 1270

    .

  4. I disabled WWAN.

  5. I started a request. It waiting for connectivity.

    2019-02-19 09:34:05.804564+0000 xxsi[1903:1263622] task will start
    2019-02-19 09:34:05.812003+0000 xxsi[1903:1263622] task is waiting

    .

  6. I re-enabled WWAN. The waiting request ran to completion.

    2019-02-19 09:34:10.111516+0000 xxsi[1903:1263622] task finished with status 200, bytes 1270

    .

There’s a few places where my code is different from yours:

  • I disabled HTTP caching on the session, because that just confuses tests like this.

  • I configured the session to run callbacks on the main thread, just to avoid any confusion.

  • I handled the completion handler parameters correctly, looking at

    error
    first, before looking at
    response
    or
    data
    .

This is testing with the latest GM tools (Xcode 10.1) on the latest GM iOS (12.1.4).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
import UIKit

class MainViewController : UIViewController, URLSessionTaskDelegate {

    private lazy var session: URLSession = {
        let configuration = URLSessionConfiguration.default
        configuration.requestCachePolicy = .reloadIgnoringLocalCacheData
        configuration.waitsForConnectivity = true
        return URLSession(configuration: configuration, delegate: self, delegateQueue: .main)
    }()

    private func start() {
        NSLog("task will start")
        let url = URL(string: "https://example.com")!
        let task = session.dataTask(with: url) { data, response, error in
            if let error = error as NSError? {
                NSLog("task transport error %@ / %d", error.domain, error.code)
                return
            }
            let response = response as! HTTPURLResponse
            let data = data!
            NSLog("task finished with status %d, bytes %d", response.statusCode, data.count)
        }
        task.resume()
    }

    func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) {
        NSLog("task is waiting")
    }

    … an @IBAction that calls `start` …
}

you saved my day.

I am very grateful.

thanx bro.