2013-08-31 9 views
5
-(void)getDataFromServer: (NSMutableDictionary *)dict 
{ 

NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/doSomething",MainURL ]]; 
[AFJSONRequestOperation addAcceptableContentTypes:[NSSet setWithObject:@"text/html"]]; 

AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url]; 
NSMutableURLRequest *request = [httpClient requestWithMethod:@"POST" path:nil parameters:dict]; 

AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request 
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) 
{ 
    _myArray = JSON; 
    [_myTableView reloadData]; //Or do some other stuff that are related to the current `ViewController` 
} 
failure:^(NSURLRequest *request , NSURLResponse *response , NSError *error , id JSON) 
{ 
    NSLog(@"request: %@",request); 
    NSLog(@"Failed: %@",[error localizedDescription]); 
}]; 

[httpClient enqueueHTTPRequestOperation:operation]; 
} 

Ich verwende den oben genannten Code an 7 verschiedenen Orten in einer meiner Apps. Das genaue Stück Code ist in 7 meiner ViewControllers dupliziert. Normalerweise verwende ich die Methode, die ich in einer NSObject-Klasse verwenden möchte, und weise sie zu und benutze sie, wann immer ich sie brauche, aber weil das obige async ist und Blöcke verwendet, kann ich nicht einfach die JSON an die ViewController zurückrufen, die angerufen hat es haben und & fügen sie das obige Verfahren in jedem ViewController ich es brauche zu kopieren in.Weitergabe von Blöcken an eine AFNetworking-Methode?

Mein Ziel ist es, die oben nur an einer Stelle in meiner App zu haben und noch in der Lage sein, es zu nennen aus verschiedenen ViewControllers um meine App und bekomme die Daten, die ich brauche. Ich möchte vermeiden, einen Beobachter wie NSNotification oder KVO zu verwenden und eine elegantere Lösung zu suchen. Nach einigem Lesen fiel mir die Möglichkeit auf, Blöcke herum zu geben. Ist das eine mögliche Lösung mit dem oben genannten? Ein Codebeispiel würde geschätzt werden.

+1

Zusätzlich zu Gabriels Antwort unten möchten Sie möglicherweise vermeiden, für jede Anfrage einen neuen AFHTTPClient zu erstellen. –

+0

Ich habe meine Antwort genau dafür bearbeitet. Danke für die Nachricht. –

Antwort

6

Factorize der API-Aufruf zu so etwas wie

+ (void)getDataFromServerWithParameters:(NSMutableDictionary *)params completion:(void (^)(id JSON))completion failure:(void (^)(NSError * error))failure { 
    NSString * path = @"resources/123"; 
    NSMutableURLRequest *request = [self.httpClient requestWithMethod:@"POST" path:path parameters:params]; 
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 
     if (completion) 
      completion(JSON); 
    } failure:^(NSURLRequest *request , NSURLResponse *response , NSError *error , id JSON) { 
     if (failure) 
      failure(error); 
    }]; 

    [httpClient enqueueHTTPRequestOperation:operation]; 
} 

Sie diese Methode wie XYAPI in einer Utility-Klasse platzieren können und es nur von Ihrem Controller aufrufen wie

[XYAPI getDataFromServer:params completion:^(id JSON){ 
    // do something, for instance reload the table with a new data source 
    _myArray = JSON; 
    [_myTableView reloadData]; 
} failure:^(NSError * error) { 
    // do something 
}]; 

Auch brauchen Sie nicht um eine neue AFHTTPClient bei jeder Anfrage zu spawnen. Konfigurieren und verwenden Sie einen freigegebenen in der Klasse XYAPI. So etwas wie

+ (AFHTTPClient *)httpClient { 
    static AFHTTPClient * client = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     client = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"http://foo.com/api/v1/"]]; 
     [AFJSONRequestOperation addAcceptableContentTypes:[NSSet setWithObject:@"text/html"]]; 
    }); 
    return client; 
} 

Beachten Sie, dass diese Implementierung bereits im obigen Beispiel verwendet wird.
self im Zusammenhang mit einer Klassenmethode ist die Klasse selbst, so self.httpClient ist tatsächlich zur Laufzeit als [XYAPI httpClient] aufgelöst.

+0

Große Antwort! Sehr detailliert und schön geschrieben. Ich werde es testen und melden. Danke vielmals. – Segev

Verwandte Themen