快速执行HTTP请求时如何显示指示器

时间:2018-12-26 10:35:09

标签: swift httprequest

我试图在快速发送HTTP请求时显示标签和指示符,但是对标签和指示符的操作总是在HTTP请求完成后执行。

因此,指示器和标签会在完成整个httpRequest之后,紧接着执行segue之前显示。可见的时间是毫秒,而不是整个等待时间。

这是代码。按下按钮后,我要显示默认情况下隐藏的指示器和标签,然后调用HTTP请求。

class NewVisitViewController: UIViewController, DownloadInfoProtocol {
let dispatchGroupController : DispatchGroup = DispatchGroup()

@IBOutlet var downloadSpinner: UIActivityIndicatorView!
@IBOutlet var downloadLabel: UILabel!
@IBAction func showAllNewVisits(_ sender: UIButton) {
    showDownloadInfo()

    let dataBaseManager = DataBaseManager()
    availableVistis = dataBaseManager.getAllFreeVisits()

    performSegue(withIdentifier: "showAllVisitsSeque", sender: self)
}

override func viewDidLoad() {
    super.viewDidLoad()
    hideDownloadInfo()
}

func hideDownloadInfo(){
    self.downloadLabel.isHidden = true
    self.downloadSpinner.isHidden = true
}

func showDownloadInfo(){
    self.downloadLabel.isHidden = false
    self.downloadSpinner.isHidden = false
}

dataBaseManager中的代码实际上发出了HTTP请求:

func getAllFreeVisits() -> [Visit] {
    print("getAllFreeVisits")
    let params: NSDictionary = [
        "entity" : "getAllFreeVisits"
    ]
    return getVisitsWithGivenParams(params: params)
}


func getVisitsWithGivenParams(params: NSDictionary) -> [Visit]  {

    print("getWithParams")
    dispatchGroup.enter()
    var vistis : [Visit] = []

    let finalURL = appendQueryParams(params: params)
    guard let url = URL(string: finalURL) else {
        print ("error while creationg URL")
        return vistis
    }

    let urlRequest = URLRequest(url: url)

    let task = session.dataTask(with: urlRequest, completionHandler:
    {
        (data, response, error) in
        let jsonData = Data(String(data: data!, encoding: String.Encoding.utf8)!.utf8)

        do {
            vistis = try self.decoder.decode([Visit].self, from: jsonData) 
        } catch {
            print(error.localizedDescription)
        }
        self.dispatchGroup.leave()
    })
    task.resume()

    dispatchGroup.wait()
    return vistis
}

我想这与多线程有关,但是我不知道在开始HTTP请求调用之前应该在此处进行什么更改以显示指示符和标签。

1 个答案:

答案 0 :(得分:1)

使用completion处理程序来了解http请求何时完成。然后,您可以隐藏活动指示器和标签,还可以执行segue

您必须按以下方式更新getVisitsWithGivenParams方法,

func getVisitsWithGivenParams(params: [String: Any], completion: @escaping (([Visit], Error?) -> Void)) {

    let finalURL = appendQueryParams(params: params)
    guard let url = URL(string: finalURL) else {
        print ("error while creationg URL")
        completion(nil, NSError()) 
        return
    }

    let urlRequest = URLRequest(url: url)

    let task = session.dataTask(with: urlRequest, completionHandler:
    {
        (data, response, error) in
        let jsonData = Data(String(data: data!, encoding: String.Encoding.utf8)!.utf8)

        do {
            let vistis = try self.decoder.decode([Visit].self, from: jsonData)
            completion(visits, nil) 
        } catch {
            print(error.localizedDescription)
            completion(nil, error) 
        }
    })
    task.resume()
}

现在您可以按以下方式使用它,

@IBAction func showAllNewVisits(_ sender: UIButton) {
    showDownloadInfo()

    let params: [String: Any] = ["entity" : "getAllFreeVisits"]
    let dataBaseManager = DataBaseManager()
    dataBaseManager.getVisitsWithGivenParams(params: params) { (visits, error) in
        self.hideDownloadInfo()

        if let error = error {
            print(error)
            return
        }
        self.availableVistis = visits
        self.performSegue(withIdentifier: "showAllVisitsSeque", sender: self)
    }
}