2016-05-04 14 views
1

Was ist die beste Vorgehensweise für Swift, um die Warteschlange einer API-Anfrage zu erstellen? Ich meine, während mehr als 1 API für eine Funktion aufgerufen wird, wie kann man sicherstellen, dass die erste API zuerst eine Antwort bekommt, dann wird die zweite API ausgeführt?Best Practice für die Warteschlange der API-Anfrage

func test() { 
    getAPI1() 
    getAPI2() 
} 

func getAPI1() { 
    Connector.sharedInstance().getAPI1({ (
     data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in 

    }) 
} 

... 

Ich denke eine Fahne geben, um anzuzeigen, dass es eine andere API ist immer noch auf Antwort wartet, so dass die zweite API, die ausgeführt werden, warten wird, bis das Flag durch das zuvor genannte API geändert wird. Aber, gibt es noch andere bessere Möglichkeiten? Vielen Dank.

+1

Vielleicht ist Ihre Funktion Dispatch müssen eine Schlange? Weitere Informationen finden Sie im [Concurrency Programming Guide] (https://developer.apple.com/library/ios/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html#//apple_ref/doc/uid/TP40008091-CH102-SW1). Beachten Sie in jedem Fall, dass Dispatch-Warteschlangen First-In und First-Out sind, während Operationswarteschlangen dies nicht tun. –

+2

Sie können auch Versandgruppen verwenden. Sie funktionieren oft besser, wenn Sie asynchrone Funktionen versenden müssen – Paulw11

Antwort

1

Fast jedes Cocoa-API asynchron zum Beispiel arbeitet

eine ENUM erstellen mit einem generischen Success Typ

enum Result<T> : ErrorType { 
    case Success(T) 
    case Failure(NSError) 
} 

getAPI1 liefert ein Objekt NSData auf Erfolg andernfalls NSError

func getAPI1(completion:Result<NSData> ->()) { 
    var data : NSData? 
    // 
    if data != nil { 
    completion(.Success(data!)) 
    } else { 
    let error = NSError(domain: "my.domain", code: 9999, userInfo: [:]) 
    completion(.Failure(error)) 
    } 
}  

getAPI2 hat einen NSData Parameter und gibt ein Wörterbuch [String:AnyObject] Objekt auf Erfolg sonst NSError

func getAPI2(data:NSData, completion:Result<[String:AnyObject]> ->()) { 
    // 
    completion(.Success([String:AnyObject]())) 
} 

test führt asynchron beide Methoden je nach ihren Ergebnissen

func test() { 
    getAPI1 { (result1) in 
    switch result1 { 
    case .Success(let data) : 
     getAPI2(data) { (result2) in 
     switch result2 { 
     case .Success(let dictionary) : 
      dispatch_async(dispatch_get_main_queue()) { 
      // update UI with the dictionary 
      } 
     case .Failure(let error) : print(error) 
     } 
     } 

    case .Failure(let error) : print(error) 
    } 
    } 
} 
1

Wie @ Paulw11 festgestellt hat, wird dispatch_groups in Ihrem Fall arbeiten

dispatch_group_t myGroup = dispatch_group_create(); 

dispatch_group_enter(myGroup); 
[asyncMethodWithCompletion:^(id *results, NSError* error){ 
    // process results 
    dispatch_group_leave(myGroup); 
}]; 

dispatch_group_notify(myGroup, dispatch_get_main_queue(),^{ 
    // This will be called when asyncMethodWithCompletion is completed 
});