如何使dataTaskWithRequest在swift(Xcode 9,swift 4)中按时间顺序排列?

时间:2018-06-26 08:52:52

标签: ios swift

我对Xcode9 Swift 4有这个问题。我试图从某些api中获取一些数据,并且需要使用这些数据进行显示。但是,由于urlSession是高度异步的,因此我无法在正确的时间(大多数情况下数据为零)获取数据。这是代码。

this.navCtrl.push('ContactPage');

我将数据存储到变量userInfo中,该变量具有ID,帐户名和头像等属性。但是,当我在另一个方法“ configNavigationBar”中调用该函数时,它无法为我初始化userInfo。

func getUserInfo(){
    let data = user!.Data as? [String : Any] ?? nil
    if let data = data{
        let ID = data["ID"] as? Int ?? nil
        if let ID = ID{
            let jsonUrlString = "SomeString"
            let requestUrl = URL(string: jsonUrlString)
            var request = URLRequest(url: requestUrl!)

            request.httpMethod = "GET"

            request.setValue("SomeKey", forHTTPHeaderField: "AppKey")
            request.setValue(md5("Someinfo"), forHTTPHeaderField: "Sign")

            dataTask = URLSession.shared.dataTask(with: request){(data, response, err) in

                guard let data = data, err == nil else {                                              // check for fundamental networking err
                    print("error=\(String(describing: err))")
                    return
                }

                if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
                    // check for http errors
                    print("statusCode should be 200, but is \(httpStatus.statusCode)")
                    print("response = \(String(describing: response))")
                }

                do{
              guard let json = try JSONSerialization.jsonObject(with: data, options:  .mutableContainers) as? [Any] else{return}
                    var userInfo = userDetail(json: json)
                    let dataDic = userInfo.dataArray as? [String:Any] ?? nil

                    userInfo.ID = dataDic?["ID"] as? Int
                    userInfo.AccountName = dataDic?["AccountName"] as? String
                    userInfo.Avatar = dataDic?["Avatar"] as? String
                } catch let jsonErr{
                    print(jsonErr)
                }

            }
            dataTask?.resume()
            }

        }
    }

有人可以帮我解决这个问题!我非常感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

http请求成功后如何更改标题?在回调中。您可以在接收数据之前配置除标题以外的所有内容。

func configNavigationBar(){
    getUserInfo { accountName in
        self.navigationItem.title = accountName
    }
    navigationItem.setHidesBackButton(true, animated: true)
    navigationController?.navigationBar.prefersLargeTitles = true
}

func getUserInfo(_ callback: @escaping (String) -> Void) {
    ...
    var userInfo = userDetail(json: json)
    let dataDic = userInfo.dataArray as? [String:Any] ?? nil

    userInfo.ID = dataDic?["ID"] as? Int
    userInfo.AccountName = dataDic?["AccountName"] as? String
    userInfo.Avatar = dataDic?["Avatar"] as? String

    // here's the insertion
    callback(userInfo.AccountName)
    // end of insertion
    ....
}

如果http请求使用后台线程,您可能还需要将ui更新包装到主线程中。

getUserInfo { accountName in
    DispatchQueue.main.async {
        self.navigationItem.title = accountName
    }
}

答案 1 :(得分:0)

您只需要等待数据下载完毕即可。

下载繁忙时,您应该决定在导航栏上显示临时状态。

然后,当下载完成(或失败)时,您再次更新导航栏。