嵌套的DispatchGroup

时间:2018-06-18 13:31:55

标签: ios swift dispatch-async

我尝试使用嵌套的DispatchGroup,有我的代码:

 class TranslateService {
      private let myGroup = DispatchGroup()
      func translateText(text:[String],closure:@escaping ((_ success:String?,_ error:Error?) -> Void)) {

        var translateString: String = ""
        var responseError: Error?

        for index in 0...text.count - 1 {

          let urlString = "https://translate.yandex.net/api/v1.5/tr.json/translate?key=trnsl.1.1.20171105T134956Z.795c7a0141d3061b.dc25bae76fa5740b2cdecb02396644dea58edd24&text=\(text[index])&lang=fa&format=plain&options=1"
          if let allowString = Utilities.shareInstance.getQueryAllowedString(url: urlString) {
            if let url = URL(string:allowString){
                myGroup.enter()
              Alamofire.request(url).responseJSON { response in
                guard let responseData = response.data else {
                  self.myGroup.leave()
                  return
                }
                do {
                  let json = try JSONSerialization.jsonObject(with: responseData, options: [])
                  if let res = json as? [String:Any] {
                    if let code = res["code"] as? Int {
                      if code == 200 {
                        if let textArr = res["text"] as? [AnyObject] {
                          let flattArr = Utilities.shareInstance.flatStringMapArray(textArr)
                          if flattArr.count > 0 {
                            translateString += "،" + flattArr[0]
                          }
                        }
                      }
                    }
                     self.myGroup.leave()
                  }
                }catch {
                  responseError = error
                 self.myGroup.leave()
                }
              }
              self.myGroup.notify(queue: .main) {
                print("Finished all requests.")
                print(translateString)
                closure(translateString, responseError)
              }
            }
          }
        }
      }
    }

    class AddressService {
  private let translateService: TranslateService = TranslateService()
  private let myGroup = DispatchGroup()
  func fetchAddressFromGeographicalLocation(latitude: Double, longitude: Double,closure:@escaping ((_ success:String,_ name:String,_ error:Error?) -> Void)) {

    var address: String = ""
    let name: String = ""
    var responseError: Error?
    if let url = URL(string:"https://maps.googleapis.com/maps/api/geocode/json?latlng=\(latitude),\(longitude)&key=AIzaSyAdEzHZfZWyjLMuuW92w5fkR86S3-opIF0&language=fa&region=IR&locale=fa"){
       self.myGroup.enter()
      Alamofire.request(url).responseJSON { response in

        guard let responseData = response.data else {
          self.myGroup.leave()
          return
        }
        do {
          let json = try JSONSerialization.jsonObject(with: responseData, options: [])
          if let addressDic = json as? [String:Any] {
            if let result = addressDic["results"] as? [AnyObject] {
              if result.count > 0 {
                let flattRes = Utilities.shareInstance.flatMapArray(result)
                let item = flattRes[0]
                address = item["formatted_address"] as? String ?? ""
                var res = address
                if res.isContainEnglishCharachter {
                  self.myGroup.enter()
                  let resArr = res.components(separatedBy: ",")
                  var all : [String] = []
                  for item in resArr {
                    if item != " " {
                      all.append(item)
                    }}
                  self.translateService.translateText(text: all, closure: {stringAdd,error in
                    self.myGroup.enter()
                    if error != nil {
                      self.myGroup.leave()
                    }else {
                      address = stringAdd ?? ""
                      self.myGroup.leave()
                    } })
                }else {
                  self.myGroup.leave()
                }
              }
            }
          }
        }catch {
          responseError = error
          self.myGroup.leave()
        }
        self.myGroup.notify(queue: .main) {
          // print("Finished all requests.")
          closure(address, name, responseError)
          }
      }
    }
  }
}

我想要的是myGroup我放在AddressService类中等待我放在TranslateService类中的myGroup。 但是现在self.myGroup.notify没有在AddressService类中调用,所以闭包不起作用。 如何解决这个问题,谢谢你的所有答案。

1 个答案:

答案 0 :(得分:0)

我认为你过度复杂了。

如果我理解了一下,你想要做的是以下几点:

  • 从地址服务处获取地址。
  • 使用翻译服务逐个翻译该地址的一些字词。

使用地址服务时,只进行了一次调用,因此此时无需使用调度组。 Dispatch Groups用于同步多个异步调用。

对于您的翻译服务,您可以充分利用Dispatch组,因为您正在for循环中调用服务。这里的问题是,实现有点错误。您正在for循环中设置通知块,它应该在外部,因此只有在循环内的所有调用完成后才会触发一次。

所以在翻译服务中将此块移到for循环之外:

self.myGroup.notify(queue: .main) {
            print("Finished all requests.")
            print(translateString)
            closure(translateString, responseError)
          }

现在"完成所有请求。"所有请求完成后,只会打印一次。

在地址服务中,根本不需要调度组。等到调用完成块后。

self.translateService.translateText(text: all, closure: {stringAdd,error in
      Everything is done here already.
}