2011-12-11 9 views
11

Cerchi un esempio di come postare json con AFHTTPClient. Vedo che esiste un metodo postPath che accetta uno NSDictionary e il metodo AFJSONEncode restituisce uno NSData. C'è un modo semplice per serializzare un oggetto su NSDictionary, o c'è un modo più semplice con jsonkit?c'è un esempio di AFHTTPClient che invia json con AFNetworking?

Ho solo bisogno di postare l'oggetto come json su un'API REST.

AGGIORNAMENTO: Così ho provato a passare un dizionario, ma sembra interrompere la serializzazione di un array nidificato.

Per esempio, se ho un oggetto:

Post* p = [[Post alloc] init]; 
p.uname = @"mike"; 
p.likes =[NSNumber numberWithInt:1]; 
p.geo = [[NSArray alloc] initWithObjects:[NSNumber numberWithFloat:37.78583], [NSNumber numberWithFloat:-122.406417], nil ]; 
p.place = @"New York City"; 
p.caption = @"A test caption"; 
p.date = [NSDate date]; 

chi è ottenere dizionario ha dati come il seguente:

{ 
    caption = "A test caption"; 
    date = "2011-12-13 17:58:37 +0000"; 
    geo =  (
     "37.78583", 
     "-122.4064" 
    ); 
    likes = 1; 
    place = "New York City"; 

} 

la serializzazione sarà o semplicemente non riuscire a titolo definitivo o geo non sarà serializzato come un array ma come una stringa letterale come ("37.78583", "-122.4064");

risposta

26

Se stai postando su un'API REST JSON, dovrebbe esserci un particolare mappatura dalla proprietà dell'oggetto alla chiave JSON, giusto? Cioè, il server si aspetta determinate informazioni in determinati campi con nome.

Quindi, ciò che si vuole fare è costruire un NSDictionary o NSMutableDictionary con le chiavi utilizzate nell'API e i loro valori corrispondenti. Quindi, passa semplicemente il dizionario nell'argomento parameters di qualsiasi metodo di richiesta in AFHTTPClient. Se la proprietà parameterEncoding del client è impostata su AFJSONParameterEncoding, il corpo delle richieste verrà automaticamente codificato come JSON.

+0

Hey Matt, ci stavo provando prima e ho avuto problemi con un nsarray nidificato. Sembra funzionare bene fino a quando non ho preso la mia proprietà geo che è un NSArray di due NSNumbers. Lo passerà come una stringa quotata con caratteri di escape quindi viene inviato come "(\ n 43.1, \ n -70.0)" – MonkeyBonkey

+0

Ok, quindi stavo ottenendo quella formattazione divertente se non avessi impostato la serializzazione di json, ma con json serializzazione Ottengo un errore nella serializzazione di NSDate. Posso passarlo a un formattatore di date o dovrei formattarlo in stringa nel dizionario prima di passarlo a AFNetworking? – MonkeyBonkey

+1

ha elaborato la serializzazione con jsonkit passando un blocco per gestire NSDates nel metodo JSONDataWithOptions ... qual è il modo migliore in cui pensi di tornare alla richiesta di rete? – MonkeyBonkey

7

Il modo migliore e più semplice per farlo è sottoclasse di AFHTTPClient.

Utilizzare questo frammento di codice

MBHTTPClient

#define YOUR_BASE_PATH @"http://sample.com" 
#define YOUR_URL @"post.json" 
#define ERROR_DOMAIN @"com.sample.url.error" 

/**************************************************************************************************/ 
#pragma mark - Life and Birth 

+ (id)sharedHTTPClient 
{ 
    static dispatch_once_t pred = 0; 
    __strong static id __httpClient = nil; 
    dispatch_once(&pred, ^{ 
     __httpClient = [[self alloc] initWithBaseURL:[NSURL URLWithString:YOUR_BASE_PATH]]; 
     [__httpClient setParameterEncoding:AFJSONParameterEncoding]; 
     [__httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]]; 
     //[__httpClient setAuthorizationHeaderWithUsername:@"" password:@""]; 
    }); 
    return __httpClient; 
} 

/**************************************************************************************************/ 
#pragma mark - Custom requests 

- (void) post<#Objects#>:(NSArray*)objects 
success:(void (^)(AFHTTPRequestOperation *request, NSArray *objects))success 
failure:(void (^)(AFHTTPRequestOperation *request, NSError *error))failure 
{ 
    [self postPath:YOUR_URL 
     parameters:objects 
      success:^(AFHTTPRequestOperation *request, id JSON){ 
       NSLog(@"getPath request: %@", request.request.URL); 

       if(JSON && [JSON isKindOfClass:[NSArray class]]) 
       { 
        if(success) { 
         success(request,objects); 
        } 
       } 
       else { 
        NSError *error = [NSError errorWithDomain:ERROR_DOMAIN code:1 userInfo:nil]; 
        if(failure) { 
         failure(request,error); 
        } 
       } 
      } 
      failure:failure]; 
} 

Poi nel codice basta chiamare

[[MBHTTPClient sharedHTTPClient] post<#Objects#>:objects 
              success:^(AFHTTPRequestOperation *request, NSArray *objects) { 
    NSLog("OK"); 
} 
              failure:(AFHTTPRequestOperation *request, NSError *error){ 
    NSLog("NOK %@",error); 
} 

oggetti è un NSArray (si può cambiare a NSDictonary) e sarà codificare in Formato JSON

+0

non sembra funzionare con le versioni latests di AFNetworking. postPath si aspetta un NSDictionary come parametri. –

0
- (NSMutableURLRequest *)requestByPostWithNSArrayToJSONArray:(NSArray *)parameters 
{ 
    NSURL *url = [NSURL URLWithString:@"" relativeToURL:self.baseURL]; 
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url]; 
    [request setHTTPMethod:@"POST"]; 
    [request setAllHTTPHeaderFields:self.defaultHeaders]; 

    if (parameters) 
    { 
      NSString *charset = (__bridge NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(self.stringEncoding)); 
      NSError *error = nil; 

      [request setValue:[NSString stringWithFormat:@"application/json; charset=%@", charset] forHTTPHeaderField:@"Content-Type"]; 
#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Wassign-enum" 
      [request setHTTPBody:[NSJSONSerialization dataWithJSONObject:parameters options:0 error:&error]]; 
#pragma clang diagnostic pop 

      if (error) { 
       NSLog(@"%@ %@: %@", [self class], NSStringFromSelector(_cmd), error); 
      } 
    } 

    return request; 
} 
AFHTTPClient *httpClient = [[AFHTTPClient alloc]initWithBaseURL:[NSURL   URLWithString:URL_REGISTER_DEVICE]]; 
NSArray *array = @[@"hello", @"world"]; 
NSMutableURLRequest *request = [httpClient requestByPostWithNSArrayToJSONArray:array]; 


AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) 
{ 
    NSLog(@"network operation succ"); 

} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) { 
    NSLog(@"network operation fail"); 

}]; 

[operation start]; 
+0

ha provato a formattare il codice (non ha esagerato ;-) - per favore modifica e migliora – kleopatra

Problemi correlati