ios - mac - pod install xcode
¿Cómo configurar el cuerpo de solicitud HTTP usando AFHTTPRequestOperationManager? (7)
Estoy usando AFHTTPRequestOperationManager (2.0 AFNetworking library) para una solicitud REST POST. Pero el gerente solo tiene la llamada para configurar los parámetros.
-((AFHTTPRequestOperation *)POST:(NSString *)URLString
parameters:(NSDictionary *)parameters
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
Necesito establecer el cuerpo de solicitud HTTP con una cadena también. ¿Cómo puedo hacerlo usando AFHTTPRequestOperationManager? Gracias.
Puede crear su propia subclase personalizada de AFHTTPRequestSerializer
y establecerlo como requestSerializer para su AFHTTPRequestOperationManager
.
En este requestSerializer personalizado, podría anular
- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request
withParameters:(id)parameters
error:(NSError *__autoreleasing *)error;
Dentro de la implementación de este método, tendrá acceso a la NSURLRequest
, por lo que podría hacer algo como esto
- (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;
}
Puede echar un vistazo dentro de la implementación de AFJSONRequestSerializer
para ver un ejemplo de cómo configurar el contenido del cuerpo HTTP personalizado.
Puede ser que podamos usar el NSMutableURLRequest, aquí está el código:
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];
Si cavas un poco en las fuentes de AFNetworking, encontrarás que, en caso de que el método POST
, los parámetros se configuren en el cuerpo de tu solicitud HTTP.
Cada clave, par de diccionario de valores se agrega al cuerpo en la forma key1=value1&key2=value2
. Las parejas están separadas por & signo.
Busque application/x-www-form-urlencoded
en AFURLRequestSerialization.m .
En el caso de una cadena que sea solo una cadena, no un par de valores clave, entonces puede intentar usar AFQueryStringSerializationBlock
http://cocoadocs.org/docsets/AFNetworking/2.0.3/Classes/AFHTTPRequestSerializer.html#//api/name/setQueryStringSerializationWithBlock : pero esto es solo mi suposición.
Tuve el mismo problema y lo resolví agregando el código como se muestra a continuación:
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];
Verifique lo que el método de conveniencia (POST: parámetros: éxito: falla) está haciendo bajo el capó y hágalo usted mismo para obtener acceso al objeto NSMutableRequest real.
Estoy usando AFHTTPSessionManager en lugar de AFHTTPRequestOperation pero imagino que el mecanismo es similar.
Esta es mi solución:
Configurar el administrador de sesión (encabezados, etc.)
Cree manualmente la solicitud NSMutable y agregue mi HTTPBody, básicamente copiando y pegando código dentro de ese método conveniente. Se ve como esto:
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];
para 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);
}];
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
}];
Esta es la mejor y más concisa forma que he encontrado.