0

I am writing simple REST API client. On each UITableViewCell selection the GET request is performed. As the request is performed in another thread, the view loads faster than it receives the response. So, the empty screen is shown at every segue for a second. I want the segue to be performed only after the data is loaded from the server.

I've tried to move the request code from the viewDidLoad to the prepare(forSegue) method. But the request is async, so it doesn't change anything... I've tried to synchronize the execution of the request, but this will block the UI, so I have no idea how to do that.

FilM
  • 21
  • 1
  • 4
  • 3
    Call `performSegue` in the completion handler of the request. For good user experience add a progress indicator (at least trigger the instance in the status bar) – vadian Aug 28 '19 at 19:28
  • On click of tablecell, call the api, show the loader. When you get the api response, only then `performSegue ` – pkc456 Aug 28 '19 at 19:30
  • How about [DispatchGroup](https://stackoverflow.com/a/40670398/419348) ? When all tasks done, execute the final block in main thread. – AechoLiu Aug 29 '19 at 08:10

1 Answers1

0

Here's an example on how to go implementing it:

import UIKit
import Foundation


loadData()

func loadData() {
  let request = NSMutableURLRequest(url: URL(string: "https://www.myUrl.com")!)
  request.httpMethod = "GET"

  let dataTask = URLSession.shared.dataTask(with: request as URLRequest) { [weak self] data,response,error in

    do {//TODO: Parse Response
      if let jsonResult = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary {
        print("data \(jsonResult)")
        self?.loadNextScreen(data: jsonResult)
      }
    } catch let error as NSError {
      print(error.localizedDescription)
    }

  }
  dataTask.resume()
}

//instantiating the vc
func loadNextScreen(data: NSDictionary) {
  let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "NewVCIdentifier") as! ViewController
  vc.model = data
  vc.present(animated: true)
}


//using a segue
func loadNextScreen(data: NSDictionary) {
  self.performSegue(withIdentifier: "MySegue", sender: data)//set the data from the segue to the controller
}
vale
  • 1,376
  • 11
  • 25
  • 2
    Please, this is Swift. Why `NSMutableURLRequest`? Why a request at all? Why `NSDictionary`? Why `NSError`? – vadian Aug 28 '19 at 19:57