У меня есть этот вопрос для Xcode9 Swift 4. Я пытаюсь получить некоторые данные из некоторого api, и мне нужно использовать эти данные для отображения. Однако, поскольку urlSession очень асинхронный, я не могу получить данные в нужное время (в большинстве случаев данные равны нулю). Вот код.
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()
}
}
}
Я сохраняю данные в переменной userInfo, которая имеет такие свойства, как ID, Имя учетной записи и Аватар. Но когда я вызываю функцию в другом методе configNavigationBar, она не может инициализировать для меня userInfo.
func configNavigationBar(){
getUserInfo()
if dataTask?.state == .completed{
navigationItem.title = userInfo?.AccountName
navigationItem.setHidesBackButton(true, animated: true)
navigationController?.navigationBar.prefersLargeTitles = true
}
}
Кто-нибудь может мне помочь с вопросом! Я глубоко признателен за любую помощь.





Вам просто нужно подождать, пока ваши данные будут загружены.
Пока загрузка занята, вы должны решить показать временное состояние на панели навигации.
Затем, когда загрузка будет завершена (или не удалась), вы снова обновите панель навигации.
Как насчет изменения заголовка после успешного 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-запрос использует фоновый поток.
getUserInfo { accountName in
DispatchQueue.main.async {
self.navigationItem.title = accountName
}
}
Оно работает! Большое спасибо. Кстати, вы случайно не знаете, как добавить экран загрузки в мое приложение? Это действительно мне очень помогает.
@BoNi, что вы имеете в виду под "экраном загрузки"? UIActivityIndicator?
Как вращающийся круг, но я думаю, что понял это. Спасибо!
Вы знаете, как мне это сделать? Я изо всех сил пытался найти способ решить временное состояние.