2016-07-28 4 views
1

У меня есть несколько запросов, которые я хотел бы звонить один за другим без вложенного кода спагетти.Alamofire количество запросов один за другим

Я пробовал уже с порядковой очередью отправки

let queue = dispatch_queue_create("label", DISPATCH_QUEUE_SERIAL) 

Alamofire.request(Router.Countries).responseString { (response:Response<String, NSError>) in 
      print(1) 
     } 

Alamofire.request(Router.Countries).responseString { (response:Response<String, NSError>) in 
      print(2) 
     } 

Alamofire.request(Router.Countries).responseString { (response:Response<String, NSError>) in 
      print(3) 
     } 

Но, к сожалению, не работает. Выходной сигнал может составлять 1,3,2 или 3,1,2 или любую другую комбинацию.

Какой был бы лучший способ получить выход 1,2,3 так один за другим.

+0

У вас есть n количество попыток, или вы уже знаете, сколько у вас будет запросов? – Miknash

+0

Я знаю, сколько у меня было, но, конечно, было бы лучше быть динамичным – Eike

+0

Вы пытались использовать 'dispatch_semaphore'? У меня нет времени, чтобы на самом деле ответить с хорошим ответом, но вы можете найти много примеров здесь, в SO –

ответ

3

Хорошо, я закончил тем, что написал свою собственную реализацию.

Я создал класс RequestChain которым требуется Alamofire.Request в качестве параметра

class RequestChain { 
    typealias CompletionHandler = (success:Bool, errorResult:ErrorResult?) -> Void 

    struct ErrorResult { 
     let request:Request? 
     let error:ErrorType? 
    } 

    private var requests:[Request] = [] 

    init(requests:[Request]) { 
     self.requests = requests 
    } 

    func start(completionHandler:CompletionHandler) { 
     if let request = requests.first { 
      request.response(completionHandler: { (_, _, _, error) in 
       if error != nil { 
        completionHandler(success: false, errorResult: ErrorResult(request: request, error: error)) 
        return 
       } 
       self.requests.removeFirst() 
       self.start(completionHandler) 
      }) 
      request.resume() 
     }else { 
      completionHandler(success: true, errorResult: nil) 
      return 
     } 

    } 
} 

И я использую его как этот

let r1 = Alamofire.request(Router.Countries).responseArray(keyPath: "endpoints") { (response: Response<[CountryModel],NSError>) in 
    print("1") 
} 

let r2 = Alamofire.request(Router.Countries).responseArray(keyPath: "endpoints") { (response: Response<[CountryModel],NSError>) in 
    print("2") 
} 

let r3 = Alamofire.request(Router.Countries).responseArray(keyPath: "endpoints") { (response: Response<[CountryModel],NSError>) in 
    print("3") 
} 

let chain = RequestChain(requests: [r1,r2,r3]) 

chain.start { (success, errorResult) in 
    if success { 
     print("all have been success") 
    }else { 
     print("failed with error \(errorResult?.error) for request \(errorResult?.request)") 
    } 


} 

ВАЖНАЯ является то, что вы говорите менеджеру, чтобы не выполнить запрос немедленно

let manager = Manager.sharedInstance 
    manager.startRequestsImmediately = false 

Надеюсь, что это поможет кому-то se

-1

Одним из решений является для вызова второй запрос в первой своей функции обратного вызова:

Alamofire.request(Router.Countries).responseString { (response:Response<String, NSError>) in 
      print(1) 
      Alamofire.request(Router.Countries).responseString { (response:Response<String, NSError>) in 
       print(2) 
       Alamofire.request(Router.Countries).responseString { (response:Response<String, NSError>) in 
         print(3) 
       } 
      } 
     } 
0

Я использую Artman's Signals уведомить мое приложение один раз результат возвращается, после чего очередь в другом месте можно назвать это следующий запрос :

Alamofire.request(httpMethod, url, parameters: params).responseJSON 
{ 
    (response: Response< AnyObject, NSError >) in 

    self._signals.dispatchSignalFor(Key: url, data: response.result) 
} 

Подробнее here.

+0

Интересный подход! Спасибо за этот удар, но он не поместится в моей базе кода. Спасибо – Eike

Смежные вопросы