У меня есть массив строк для перевода, я хочу вызвать API перевода Яндекса для каждой строки в массиве, создать предложение из результатов этого перевода, а затем передать это предложение в закрытие контроллеру и обновить пользовательский интерфейс.Я хочу, чтобы, когда мое предложение было выполнено, полное предложение в закрытии, но теперь я проверяю индекс количества массивов для закрытия вызова, мне нужно лучшее решение для этого.

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 {
      myGroup.enter()
      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){
          Alamofire.request(url).responseJSON { response in
            guard let responseData = response.data else {
              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]
                      }
                    }
                  }
                }
              }
            }catch {
              responseError = error
            }

            if index == text.count - 1 {
              closure(translateString, responseError)
              self.myGroup.leave()
            }
          }
          self.myGroup.notify(queue: .main) {
            print("Finished all requests.")
          }
        }
      }

    }

  }
}
1
ava 13 Июн 2018 в 08:47

1 ответ

Лучший ответ

Попробуйте это, нет абсолютно никакой необходимости сравнивать индекс. Я думаю, вы неправильно поняли концепцию группы отправки.

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 {
                                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]
                                                }
                                            }
                                        }
                                    }
                                }
                                myGroup.leave()
                            }catch {
                                responseError = error
                                myGroup.leave()
                            }
                        }
                        self.myGroup.notify(queue: .main) {
                            print("Finished all requests.")
                            closure(translateString, responseError)
                        }
                    }
                }

            }

        }
    }

Блок уведомлений группы отправки будет выполнен только тогда, когда все асинхронные задачи, вошедшие в группу, покинут блок. Таким образом, вы можете выполнить закрытие в блоке уведомлений. Это должно дать вам четкое указание на то, что все запросы alamofire завершились успешно или с ошибкой.

Надеюсь это поможет.

1
Sandeep Bhandari 13 Июн 2018 в 07:03