web-dev-qa-db-fra.com

Comment définir le corps de la requête HTTP en utilisant AFHTTPRequestOperationManager d'AFNetwork?

J'utilise AFHTTPRequestOperationManager (bibliothèque 2.0 AFNetworking) pour une demande REST POST. Mais le gestionnaire n'a que l'appel pour définir les paramètres).

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

Je dois également définir le corps de la requête HTTP avec une chaîne. Comment puis-je le faire en utilisant AFHTTPRequestOperationManager? Merci.

19
user2543991

J'ai eu le même problème et l'ai résolu en ajoutant du code comme indiqué ci-dessous:

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];
31
Ganesh Guturi

pour 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);
}];
7
Igor Bachek

Vérifiez ce que cette méthode pratique (POST: paramètres: succès: échec) fait sous le capot et faites-le vous-même pour accéder à l'objet NSMutableRequest réel.

J'utilise AFHTTPSessionManager au lieu de AFHTTPRequestOperation mais j'imagine que le mécanisme est similaire.

Voici ma solution:

  1. Configuration du gestionnaire de session (en-têtes, etc.)

  2. Créez manuellement la demande NSMutable et ajoutez mon HTTPBody, en gros copier-coller du code à l'intérieur de cette méthode pratique. Ressemble à ça:

    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];
    
6
Halyna Rubashko

Vous pouvez créer votre propre sous-classe personnalisée de AFHTTPRequestSerializer et la définir comme requestSerializer pour votre AFHTTPRequestOperationManager.

Dans cette demande personnalisée Serializer, vous pouvez remplacer

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

Dans votre implémentation de cette méthode, vous aurez accès à NSURLRequest, donc vous pourriez faire quelque chose comme ça

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

Vous pouvez jeter un oeil à l'intérieur de l'implémentation de AFJSONRequestSerializer pour un exemple de définition de contenu de corps HTTP personnalisé.

4
Herre

Si vous creusez un peu dans les sources d'AFNetworking, vous constaterez qu'en cas de POST les paramètres de la méthode sont définis dans le corps de votre requête HTTP.

Chaque paire de clés, dictionnaire de valeurs est ajoutée au corps sous la forme key1=value1&key2=value2. Les paires sont séparées par un signe &.

Rechercher application/x-www-form-urlencoded dans AFURLRequestSerialization.m .

Dans le cas d'une chaîne qui n'est qu'une chaîne, pas une paire valeur/clé, vous pouvez essayer d'utiliser AFQueryStringSerializationBlockhttp://cocoadocs.org/docsets/AFNetworking/2.0.3/Classes/AFHTTPRequestSerializer .html # // api/name/setQueryStringSerializationWithBlock : mais ce n'est que ma supposition.

4
MichK
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
}];

C'est le meilleur moyen et le plus concis que j'ai trouvé.

3
tdeegan

Peut-être que nous pouvons utiliser la NSMutableURLRequest, voici le code:

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];
0
Hilen