2013-10-31 14 views
19

Sto utilizzando AFHTTPRequestOperationManager (libreria AFNetworking 2.0) per una richiesta POST REST. Ma il gestore ha solo la chiamata per impostare i parametri.Come impostare il corpo della richiesta HTTP usando AFHTTPRequestOperationManager?

-((AFHTTPRequestOperation *)POST:(NSString *)URLString 
        parameters:(NSDictionary *)parameters 
        success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success 
        failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; 

Ho bisogno di impostare anche il corpo della richiesta HTTP con una stringa. Come posso farlo usando AFHTTPRequestOperationManager? Grazie.

risposta

6

Verificare quale metodo di convenienza (POST: parametri: successo: errore) sta facendo sotto il cofano e fai da te per ottenere l'accesso all'oggetto NSMutableRequest effettivo.

Sto usando AFHTTPSessionManager invece di AFHTTPRequestOperation ma immagino che il meccanismo sia simile.

Questa è la mia soluzione:

  1. Session Setup Manager (intestazioni, ecc)

  2. creare manualmente richiesta NSMutable e aggiungere il mio HTTPBody, in fondo il codice copiando-incollando all'interno di quel metodo comodo. Si presenta così:

    NSMutableURLRequest *request = [manager.requestSerializer requestWithMethod:@"POST" URLString:[[NSURL URLWithString:<url string>] absoluteString] parameters:parameters]; 
    
    [request setHTTPBody:[self.POSTHttpBody dataUsingEncoding:NSUTF8StringEncoding]]; 
    __block NSURLSessionDataTask *task = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) { 
        if (error) { 
         // error handling 
        } else { 
         // success 
        } 
    }]; 
    
    [task resume]; 
    
4

Se si scava un po 'delle fonti di AFNetworking troverete che in caso di POST parametri del metodo sono impostati nel corpo della richiesta HTTP.

Ogni chiave, coppia di dizionari valore viene aggiunta al corpo nel modulo key1=value1&key2=value2. Le coppie sono separate dal segno &.

Cerca application/x-www-form-urlencoded in AFURLRequestSerialization.m.

In caso di una stringa che è solo una stringa, non una coppia di valori chiave, si potrebbe provare a utilizzare AFQueryStringSerializationBlockhttp://cocoadocs.org/docsets/AFNetworking/2.0.3/Classes/AFHTTPRequestSerializer.html#//api/name/setQueryStringSerializationWithBlock: ma questa è solo una mia ipotesi.

31

Ho avuto lo stesso problema e risolto con l'aggiunta di codice come illustrato di seguito:

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL 
       cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10]; 

[request setHTTPMethod:@"POST"]; 
[request setValue:@"Basic: someValue" forHTTPHeaderField:@"Authorization"]; 
[request setValue: @"application/json" forHTTPHeaderField:@"Content-Type"]; 
[request setHTTPBody: [body dataUsingEncoding:NSUTF8StringEncoding]]; 

AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request]; 
op.responseSerializer = [AFJSONResponseSerializer serializer]; 
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 

    NSLog(@"JSON responseObject: %@ ",responseObject); 

} failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
    NSLog(@"Error: %@", [error localizedDescription]); 

}]; 
[op start]; 
+0

Questo è un bene, ma come caricare immagini con questo, Multipart? –

+10

Ma come fare con 'AFHTTPRequestOperationManager'? –

0

Può essere possiamo usare il NSMutableURLRequest, ecco il codice:

NSURL *url = [NSURL URLWithString:yourURLString]; 
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url 
                 cachePolicy:NSURLRequestUseProtocolCachePolicy 
                timeoutInterval:60.0]; 

[request setHTTPMethod:@"POST"]; 
NSData *JSONData = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:nil]; 
NSString *contentJSONString = [[NSString alloc] initWithData:JSONData encoding:NSUTF8StringEncoding]; 
[request setHTTPBody:[contentJSONString dataUsingEncoding:NSUTF8StringEncoding]]; 

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 
[connection start]; 
4

È possibile creare la tua propria sottoclasse personalizzata di AFHTTPRequestSerializer e impostarla come requestSerializer per AFHTTPRequestOperationManager.

In questa usanza requestSerializer, si potrebbe ignorare

- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request   
           withParameters:(id)parameters 
             error:(NSError *__autoreleasing *)error; 

Dentro l'implementazione di questo metodo, avrete accesso alla NSURLRequest, così si potrebbe fare qualcosa di simile

- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request  
           withParameters:(id)parameters 
             error:(NSError *__autoreleasing *)error 
{  
    NSURLRequest *serializedRequest = [super requestBySerializingRequest:request withParameters:parameters 
    error:error]; 
    NSMutableURLRequest *mutableRequest = [serializedRequest mutableCopy];   
    // Set the appropriate content type 
    [mutableRequest setValue:@"text/xml" forHTTPHeaderField:@"Content-Type"];    
    // 'someString' could eg be passed through and parsed out of the 'parameters' value 
    NSData *httpBodyData = [someString dataUsingEncoding:NSUTF8StringEncoding]; 
    [mutableRequest setHTTPBody:httpBodyData]; 

    return mutableRequest; 
} 

È potrebbe dare un'occhiata all'interno dell'implementazione di AFJSONRequestSerializer per un esempio di impostazione del contenuto del corpo HTTP personalizzato.

3
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; 
manager.requestSerializer = [AFJSONRequestSerializer serializer]; 
[manager POST:url parameters:jsonObject success:^(AFHTTPRequestOperation *operation, id responseObject) { 
    //success 
} failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
    //fail 
}]; 

Questo è il modo migliore e più conciso che ho trovato.

+0

Questo è molto più semplice degli altri approcci. Comunque la cosa strana è che questo non sembra funzionare con GET ... – Hampotato

+0

@Hampotato Generalmente non dovresti avere un corpo nella tua richiesta get. È possibile ma non standard. – tdeegan

+0

Sì, ho capito. Grazie tdeegan! – Hampotato

7

per AFHTTPRequestOperationManager

[requestOperationManager.requestSerializer setValue:@"your Content Type" forHTTPHeaderField:@"Content-Type"]; 
[requestOperationManager.requestSerializer setValue:@"no-cache" forHTTPHeaderField:@"Cache-Control"]; 

// Fill parameters 
NSDictionary *parameters = @{@"name"  : @"John", 
          @"lastName" : @"McClane"}; 

// Customizing serialization. Be careful, not work without parametersDictionary 
[requestOperationManager.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, NSDictionary *parameters, NSError *__autoreleasing *error) { 

    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:nil]; 
    NSString *argString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 
    return argString; 
}]; 

[requestOperationManager POST:urlString parameters:parameters timeoutInterval:kRequestTimeoutInterval success:^(AFHTTPRequestOperation *operation, id responseObject) { 

    if (success) 
     success(responseObject); 

} failure:^(AFHTTPRequestOperation *operation, NSError *error) { 

    if (failure) 
     failure(error); 
}]; 
Problemi correlati