gpt4 book ai didi

ios - API 线程问题 iOS

转载 作者:行者123 更新时间:2023-11-29 11:39:48 26 4
gpt4 key购买 nike

因此,我在运行响应包含另一个 API 调用的 API 调用时遇到了问题。

这是第一个函数:

class APICaller{

weak var delegate:APIDelegate?

func getCharacter(x:Int){
let character = CharacterModel()
let url = URL(string: "https://swapi.co/api/people/\(x)/")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil{
print("Error downloading character information. Empty character returned.")
} else {
if let content = data {

do{
let charJSON = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String: Any]
character.name = (charJSON?["name"] as? String)?.description ?? ""
character.height = Int((charJSON?["height"] as? String)?.description ?? "0") ?? 0
character.mass = Int((charJSON?["mass"] as? String)?.description ?? "0") ?? 0
character.hairColor = (charJSON?["hair_color"] as? String)?.description ?? ""
character.skinColor = (charJSON?["skin_color"] as? String)?.description ?? ""
character.eyeColor = (charJSON?["eye_color"] as? String)?.description ?? ""
character.birthYear = (charJSON?["birth_year"] as? String)?.description ?? ""
character.gender = (charJSON?["gender"] as? String)?.description ?? ""
character.homeWorld = self.getPlanet(uri: (charJSON?["homeworld"] as? String)?.description ?? "")
//The homeward part of the response is another URL and as such requires another API Call to get anything meaningful
DispatchQueue.main.async {
self.delegate?.didGetStarWarsCharacter(characterData:character)
}
}catch{
print("Error downloading character information. Empty or incomplete character returned")
}
}
}
}
task.resume()
}
private func getPlanet(uri:String)->String{
if uri == ""{
return uri // return empty string if the original call doesn't get anything.
}
var result = ""
let url = URL(string:uri)
let task = URLSession.shared.dataTask(with: url!){(data,response,error)->Void in
if error != nil{
result = "No Planet Found"
}else{
if let planet = data{
do{
let planetJSON = try JSONSerialization.jsonObject(with: planet, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String:Any]
//print(planetJSON?["name"] as? String ?? "No Planet")
result = (planetJSON?["name"] as? String)?.description ?? "No Planet Found"
}catch{
result = "No Planet Found"
}
}
}
}// end of task, result is lost due to multithreading
task.resume()
return result
}
}

所以我知道为 getPlanet 运行任务发生在另一个线程上,并且此方法在任务完成运行之前返回。因此,当委托(delegate)获取 CharacterModel 时,其 homeWorld 参数为空。

例如,如果我在 getPlanet 函数运行后调用 print(character.homeWorld),我将收到一个空字符串。

我想不出解决这个问题的好方法。

最佳答案

getPlanet 正在执行异步调用。 result 实例不会保存接收到的数据。而不是在 getPlanet 中使用完成 block ,并在接收数据时调用此完成 block 。像这样的东西。请继续阅读 closures .

class APICaller{

weak var delegate:APIDelegate?

func getCharacter(x:Int){
let character = CharacterModel()
let url = URL(string: "https://swapi.co/api/people/\(x)/")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil{
print("Error downloading character information. Empty character returned.")
} else {
if let content = data {

do{
let charJSON = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String: Any]
character.name = (charJSON?["name"] as? String)?.description ?? ""
character.height = Int((charJSON?["height"] as? String)?.description ?? "0") ?? 0
character.mass = Int((charJSON?["mass"] as? String)?.description ?? "0") ?? 0
character.hairColor = (charJSON?["hair_color"] as? String)?.description ?? ""
character.skinColor = (charJSON?["skin_color"] as? String)?.description ?? ""
character.eyeColor = (charJSON?["eye_color"] as? String)?.description ?? ""
character.birthYear = (charJSON?["birth_year"] as? String)?.description ?? ""
character.gender = (charJSON?["gender"] as? String)?.description ?? ""
self.getPlanet(uri: (charJSON?["homeworld"] as? String)?.description ?? "", completion:
{ (result:String) in
character.homeWorld = result
DispatchQueue.main.async {
self.delegate?.didGetStarWarsCharacter(characterData:character)
}
}
)
//The homeward part of the response is another URL and as such requires another API Call to get anything meaningful

}catch{
print("Error downloading character information. Empty or incomplete character returned")
}
}
}
}
task.resume()
}
private func getPlanet(uri:String, completion:@escaping (_ response:String)->Void){
if uri == ""{
completion(uri) // return empty string if the original call doesn't get anything.
}
var result = ""
let url = URL(string:uri)
let task = URLSession.shared.dataTask(with: url!){(data,response,error)->Void in
if error != nil{
result = "No Planet Found"
}else{
if let planet = data{
do{
let planetJSON = try JSONSerialization.jsonObject(with: planet, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String:Any]
//print(planetJSON?["name"] as? String ?? "No Planet")
result = (planetJSON?["name"] as? String)?.description ?? "No Planet Found"
}catch{
result = "No Planet Found"
}
completion(result)
}
}
}// end of task, result is lost due to multithreading
task.resume()
}
}

关于ios - API 线程问题 iOS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47249978/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com