Alex Li
Alex Li

Reputation: 55

How can I stop URLSessionTask when the Internet is disconnected?

I am using URLSessionTask to get the source code of url. When the internet is connected, it works well.

However, when the Internet is disconnected, I try building. And in simulator it is blank and the cpu is 0%. What affects is that My Tab Bar Controller is also missing and blank (It is my initial view controller). It seems that this task is under connecting?

I want the data received from dataTask, so I use semaphore to make it synchronous. Otherwise, as dataTask is an asynchronous action, what I get is an empty string.

How can I fix this problem?

Thanks!

    let urlString:String="http://www.career.fudan.edu.cn/jsp/career_talk_list.jsp?count=50&list=true"
    let url = URL(string:urlString)

    let request = URLRequest(url: url!)
    let session = URLSession.shared
    let semaphore = DispatchSemaphore(value: 0)
    let dataTask = session.dataTask(with: request,
                                    completionHandler: {(data, response, error) -> Void in
                                        if error != nil{
                                            errorString = "Error!"
                                        }else{
                                            htmlStr = String(data: data!, encoding: String.Encoding.utf8)!
                                            //print(htmlStr)
                                        }

                                        semaphore.signal()
    }) as URLSessionTask

    //start task
    dataTask.resume()
    _ = semaphore.wait(timeout: DispatchTime.distantFuture)

Upvotes: 1

Views: 496

Answers (1)

Alex Li
Alex Li

Reputation: 55

Update: As @Moritz mentioned, I finally use completion handler (callback).

func getforData(completion:  @escaping (String) -> ()) {
    if let url = URL(string: "http://XXXXX") {
        let request = URLRequest(url: url)
        let task = URLSession.shared.dataTask(with: request) {
            data, response, error in
            if let data = data, let getString = String(data: data, encoding: String.Encoding.utf8), error == nil {
                completion(getString)
            } else {
                print("error=\(error!.localizedDescription)")
            }
        }
        task.resume()
    }
}

And in viewdidload

override func viewDidLoad() {
    super.viewDidLoad()

    getforData { getString in
        // and here we get the "returned" value from the asynchronous task
        print(getString) //works well

        //tableview should work in main thread            
        DispatchQueue.main.async {
            self.newsTableView.dataSource = self
            self.newsTableView.delegate = self
            self.newsTableView.reloadData()
        }
}

Upvotes: 1

Related Questions