2013-08-31 17 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]; 
} 

Sto usando il codice sopra in 7 diversi posti in una delle mie app. Il pezzo esatto di codice è duplicato in 7 dei miei ViewControllers. Quello che in genere facevo era mettere il metodo che voglio usare in una classe NSObject e assegnarlo e usarlo quando mai ho bisogno ma poiché sopra è Async e usando i blocchi non posso semplicemente restituire il JSON allo ViewController che ha chiamato e devono copiare & incollare il metodo di cui sopra in ogni ViewController ho bisogno di.Passaggio di blocchi a un metodo di rete AF?

il mio obiettivo è quello di avere la precedenza in un solo posto nel mio app e ancora in grado di chiamare da diverso ViewControllers intorno alla mia app e ottenere i dati che mi servono Vorrei evitare di utilizzare un osservatore come NSNotification o KVO e cercare una soluzione più elegante. Dopo alcune letture ho notato la possibilità di passare blocchi in giro. È una possibile soluzione con quanto sopra? Un esempio di codice sarebbe apprezzato.

+1

Oltre alla risposta di Gabriele in basso, è consigliabile evitare di far ruotare un nuovo AFHTTPClient per ogni richiesta. –

+0

Stavo modificando la mia risposta esattamente per quello. Grazie per la nota. –

risposta

6

fattorizzare la chiamata API a qualcosa come

+ (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]; 
} 

È possibile inserire questo metodo in una classe di utilità come XYAPI e basta invocarlo dei controller come

[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 
}]; 

Inoltre non è necessario generare un nuovo AFHTTPClient ad ogni richiesta. Configura e usa uno condiviso nella classe XYAPI. Qualcosa come

+ (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; 
} 

Si noti che questa implementazione è già utilizzata nell'esempio precedente.
self nel contesto di un metodo di classe è la classe stessa, pertanto self.httpClient viene effettivamente risolto in fase di esecuzione come [XYAPI httpClient].

+0

Ottima risposta! Molto dettagliato e ben scritto. Lo verificherò e riferirò. Molte grazie. – Segev

Problemi correlati