2012-06-15 13 views
12

Ich benutze diese Methode AFNetworking mehrere Anfragen auf einmal zu starten:AFNetworking: enqueueBatchOfHTTPRequestOperations Ausgabe mit Abschluss Block

- (void)enqueueBatchOfHTTPRequestOperations:(NSArray *)operations 
           progressBlock:(void (^)(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations))progressBlock 
          completionBlock:(void (^)(NSArray *operations))completionBlock 

Einer von ihnen ein AFJSONRequestOperation ist. Das Problem besteht darin, dass der Erfolgsblock dieser JSON-Operation nach dem Abschlussblock des Stapels ausgeführt wird. Der Grund ist: AFJSONRequestOperation verfügt über eine interne Dispatch-Warteschlange für die JSON-Verarbeitung. Daher werden die JSON-Daten noch verarbeitet, während der Completion-Block aufgerufen wird.

Frage: Wie kann Code im Abschlussblock nach der Erfolgsblock der JSON-Operation aufgerufen wurde?

Ich habe versucht, einen Codeblock in der Hauptwarteschlange zu versenden, aber das hat nicht geholfen.

Antwort

1

Wenn es möglich ist, besteht die einfachste Lösung darin, den Verarbeitungscode aus dem Erfolgsblock jeder Operation in den Abschlussblock des gesamten Stapels zu verschieben.

Sie haben die NSArray *operations in dem Abschluss-Block, Sie durch die Operationen laufen kann und sucht:

for(AFHTTPRequestOperation *operation in operations){ 
    if(operation.response.statusCode == 200){ 
     //Do something with the response 
    }else{ 
    //Handle the failure 
    } 
} 

Sie auch die URL-Adresse für jeden Betrieb zur Verfügung durch die operation.request.URL Eigenschaft haben, wenn Sie auf die Vorform müssen verschiedene Aktionen

+0

OP sagte der JSON ist immer noch nicht verarbeitet, wenn die Fertigstellung aufgerufen wird, also würde das nicht funktionieren, oder? – kevboh

+0

Ja, deshalb frage ich. Diese Antwort hilft mir nicht. – Felix

+1

Oh, ich habe es falsch gelesen. Was Ihr Problem betrifft, könnte es bald einen Patch geben, wenn Sie darauf warten können. https://github.com/AFNetworking/AFNetworking/issues/362 –

0

Sie können Ihre json Betrieb an den Anfang der Warteschlange verschieben, und dann eine Abhängigkeit hinzufügen, so dass eine weitere Operation erst nach dem json Betrieb beginnen beendet:

[lastOperation addDependency:jsonOperation] 
+0

Könnten Sie genauer sein? –

+0

ich denke mal so etwas: if (previousOperation) {[operation addDependency: previousOperation]; } previousOperation = Operation; [Operationen addObject: operation]; es hat für mich nicht funktioniert – Sosily

0

Es scheint, es gibt keinen einfachen Weg, genau das zu tun, was das OP anfordert, also hier sind einige einfache Problemumgehungen.

Eine eher stumpfe Strategie wäre, AFHTTPRequestOperation anstelle von AFJSONRequestOperation zu verwenden und dann die Antwort zu konvertieren, die NSJSONSerialization verwendet.

So ist der Erfolg Block der Operation aussehen würde

success:^(AFHTTPRequestOperation *operation, id responseObject){ 
       NSError *error ; 
       id json = [NSJSONSerialization JSONObjectWithData:responseObject 
              options:kNilOptions error:&error] ; 
       ... 
      } 

Caveats gelten würde - für große JSON Antworten dies möglicherweise Code blockiert wird, und einige der AFNetworking Abhilfen zu NSJSONSerialization Probleme gelten nicht. Aber das würde dich weiterbringen.

Update: Der erste Kommentator unten schlägt AFJSONRequestOperation mit und responseJSON darauf im Batch-Abschluss Block aufrufen. Ich bin gut damit, wenn es deine Situation erlaubt. In meinem aktuellen Anwendungsfall verkompliziert es meinen Code etwas (ich verwende einen gemischten Satz von JSON-Aufrufen, daher ist der Code sauberer, wenn ich ihn in einem success-Block behalten kann, der direkt mit der Operation verknüpft ist).

+0

Es wäre sinnvoller, die JSON-Operation zu verwenden, und rufen Sie einfach 'responseJSON' im Batch-Vervollständigungsblock auf. Diese Methode gibt synchron zurück. Dies liefert das Verhalten, das das OP ohne die von Ihnen erwähnten Einschränkungen wünscht. –

+0

Danke @Aaron. Ich habe meine Antwort aktualisiert. – brainjam