Swift 3-使用dispatchGroup()等待每个URL会话的完成



嗨,所以我有一个问题,我有一个填充字符串的数组(例如:[狗,猫,吉尔拉夫,牛](,我要使用此ID来制作API致电某些网站从该网站获取图像。我需要结果与数组的顺序相同。

对于此示例,如果我打印两个数组,我需要这样的输出,应该是这样: thestring-狗,猫,吉拉夫,牛

年龄-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()
}

简而

我建议您首先使用nil值初始化age

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

尝试这样!

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)
}

最新更新