How to update UI inside URLSession?

Hello
I am try hide check if website is available use URLSession then, get info about availability and hide activity indicator and use "performSegue", but it don't work when I am was obtain data from URLSession, I am use:
Code Block
DispatchQueue.global
DispatchQueue.main.async
OperationQueue.main.addOperation

but it don't help what I am doing wrong?

This is example of my code:
URLSession.

Code Block
class ServiceWebSiteAvailability: NSObject {
  static let shared = ServiceWebSiteAvailability()
  var state: Bool?
   
  func available(LinkOfWebsite link: String, completion: @escaping (Error?) -> ()) {
     
    if let url = URL(string: link) {
     var request = URLRequest(url: url)
     request.httpMethod = "HEAD"
      DispatchQueue.main.async {
       
       
     URLSession(configuration: .default)
      .dataTask(with: request) { (_, response, error) -> Void in
          
        guard error == nil else {
          print("Error:", error ?? "")
          self.state = false
          return completion(nil)
        }
        guard (response as? HTTPURLResponse)?
          .statusCode == 200 else {
           
          print("down")
          self.state = false
          return completion(nil)
        }
         
        self.state = true
        print("up")
        completion(nil)
      }
      .resume()
      }
    }
         
  }
}

Check site url:

Code Block
   func openLinkInsideWKWebKit(url: String) {
    createSpinnerView()
    ServiceWebSiteAvailability.shared.available(LinkOfWebsite: url) { (error) in
      guard let state = ServiceWebSiteAvailability.shared.state else { return }
      if (error != nil) {
        print("Site accesibility is - \(state)")
/* This code block below don't work
        if (state == true || state == false) {
          self.performSegue(withIdentifier: "main", sender: nil)
          self.child.willMove(toParent: nil)
      self.child.view.removeFromSuperview()
      self.child.removeFromParent()
        }
         
      } else {
        print("Site accesibility is - \(state)")
      }
*/
    }
  }

What I am doing wrong?
Answered by DTS Engineer in 641201022

what I am doing wrong?

There’s a couple of problems that immediately jump out. The first relates to line 13. You are creating a session and then using it for a single request. This is deeply inefficient and, as things currently stand, leaks. The two recommended approaches here:
  • Create a session and use if for all your requests.

  • Use the shared session, which you can access via URLSession.shared.

The other problem relates to your completion handler. As things stand, your available(…) method is calling its completion handler on a secondary thread. Then, inside openLinkInsideWKWebKit(…), you modify your view hierarchy directly from the completion handler. This isn’t safe because UIKit is a main-thread only framework. Someone needs to bounce to the main thread here. You can either define that available(…) always calls its completion handler on the main thread, or you can update each of its clients (like openLinkInsideWKWebKit(…)) to bounce to the main thread when they want to do UI work.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Accepted Answer

what I am doing wrong?

There’s a couple of problems that immediately jump out. The first relates to line 13. You are creating a session and then using it for a single request. This is deeply inefficient and, as things currently stand, leaks. The two recommended approaches here:
  • Create a session and use if for all your requests.

  • Use the shared session, which you can access via URLSession.shared.

The other problem relates to your completion handler. As things stand, your available(…) method is calling its completion handler on a secondary thread. Then, inside openLinkInsideWKWebKit(…), you modify your view hierarchy directly from the completion handler. This isn’t safe because UIKit is a main-thread only framework. Someone needs to bounce to the main thread here. You can either define that available(…) always calls its completion handler on the main thread, or you can update each of its clients (like openLinkInsideWKWebKit(…)) to bounce to the main thread when they want to do UI work.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Thank you very much, very helpful.
How to update UI inside URLSession?
 
 
Q