嗨所以我有这个问题,我有一个数组填充字符串(例如:[狗,猫,girraffe,牛]),我将使用此ID对某些网站进行API调用以获取图像从该网站。我需要结果与数组的顺序相同。
对于这个例子,我需要输出是这样的,如果我打印两个数组,它应该是这样的: theString - dog,cat,girraffe,cow
年龄 - 5,10,20,5< - 排序对应动物
但相反,我得到的年龄输出如下: 年龄 - 5岁,20岁,10岁,5岁或
年龄 - 10岁,20岁,5岁,5岁等
我几乎不得不对骰子起作用,直到我得到输出为准。
因为每个API调用都是异步的,所以当涉及到年龄时,排序总是随机的。我已经被困在这个问题好几天了,不太确定如何去做..
示例代码:
let theString = ["dog", "cat", "girraffe", "cow"]
var age = Array<Int>() // to store the ages of the animal in order
override func viewDidLoad() {
super.viewDidLoad()
//make the call 4 times
for each in theString{
doAPICall(name:each)
print(age)//the output is not in order
}
}
func doAPICall(name: String){
let animal = name
let urlString:String = "https://somewebsite.com/api/"+ animal
let url = URL(string: urlString)!
let task = URLSession.shared.dataTask(with: url, completionHandler: {
(data, response, error) in
if error != nil {
print(error!.localizedDescription)
} else{
do{
let parsedData = try JSONSerialization.jsonObject(with: data!, options: []) as! [String:Any]
let age = parsedData["age"] as! Int
self.age.append(age) //appends the age to the array
} catch let error as NSError {
print(error)
}
}//end else
})
task.resume()
}
简而言之,我需要一些方法来告诉for循环或异步调用等到上一个完成之后再转到下一个
答案 0 :(得分:0)
我建议您先使用age
值初始化nil
:
var age = [Int?](repeating: nil, count: theString.count)
然后,在每次调用完成后,将右侧索引处的值设置为您获得的结果。
} else{
do{
let parsedData = try JSONSerialization.jsonObject(with: data!, options: []) as! [String:Any]
let age = parsedData["age"] as! Int
// Note these lines!
if let index = theString.index(of: animal) {
self.age[index] = age
}
} catch let error as NSError {
print(error)
}
}//end else
答案 1 :(得分:0)
试试这个!
let theString = ["dog", "cat", "girraffe", "cow"]
var age = Array<Int>() // to store the ages of the animal in order
override func viewDidLoad() {
super.viewDidLoad()
//make the call 4 times
for each in theString{
doAPICall(animal: each,completion: { (responseArray,error) -> () in
let age = responseArray["age"] as! Int
if let index = theString.index(of: each) {
self.age[index] = age
}
})
print(age)//the output is in order
}
}
func doAPICall(animal: String,completion:@escaping (_ responsedata:NSDictionary?_ error:NSError?) -> Void){
let Baseurl = "https://somewebsite.com/api/"+ animal
let RequestUrl = URL(string: Baseurl)
let request = NSMutableURLRequest(url: RequestUrl!)
let semaphore = DispatchSemaphore(value: 0)
let task = session.dataTask(with: request as URLRequest) { (data, response, error) in
guard error == nil && data != nil else {
print("error=\(error?.localizedDescription)")
return
}
if let httpStatus = response as? HTTPURLResponse{
if httpStatus.statusCode != 200 {
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
}
do {
let ResponseDictionary = try JSONSerialization.jsonObject(with: data! as Data, options: .allowFragments) as! as! NSDictionary?
completion(ResponseDictionary,nil)
semaphore.signal()
}
catch let error as NSError {
print("Details of JSON parsing error:\n \(error.localizedDescription)")
completion(nil,error)
}
}
task.resume()
_ = semaphore.wait(timeout: .distantFuture)
}