Как установить тело запроса HTTP с помощью AFNetwork AFHTTPRequestOperationManager?
Я использую AFHTTPRequestOperationManager (2.0 AFNetworking library) для запроса REST POST. Но у менеджера есть только вызов для установки параметров.
-((AFHTTPRequestOperation *)POST:(NSString *)URLString
parameters:(NSDictionary *)parameters
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
Мне нужно также установить тело запроса HTTP с помощью строки. Как это сделать, используя AFHTTPRequestOperationManager? Спасибо.
Ответы
Ответ 1
У меня была такая же проблема, и я решил ее добавить, как показано ниже:
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];
Ответ 2
для 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);
}];
Ответ 3
Проверьте, что этот удобный метод (POST: parameters: success: failure) выполняется под капотом и делает это сам, чтобы получить доступ к реальному объекту NSMutableRequest.
Я использую AFHTTPSessionManager вместо AFHTTPRequestOperation, но я думаю, что механизм похож.
Это мое решение:
-
Настройка диспетчера сеансов (заголовки и т.д.)
-
Вручную создайте запрос NSMutable и добавьте мой HTTPBody, в основном копирующий код в этом удобном методе. Выглядит так:
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
Если вы копаете немного источников AFNetworking, вы обнаружите, что в случае POST
параметры метода устанавливаются в тело вашего HTTP-запроса.
Каждая пара ключей словаря значений добавляется к телу в форме key1=value1&key2=value2
. Пары разделяются и подписываются.
Найдите application/x-www-form-urlencoded
в AFURLRequestSerialization.m.
В случае строки, которая является только строкой, а не парой значений ключа, вы можете попытаться использовать AFQueryStringSerializationBlock
http://cocoadocs.org/docsets/AFNetworking/2.0.3/Classes/AFHTTPRequestSerializer.html#//api/name/setQueryStringSerializationWithBlock: но это только моя догадка.
Ответ 5
Вы можете создать свой собственный подкласс AFHTTPRequestSerializer
и установить это как requestSerializer для своего AFHTTPRequestOperationManager
.
В этом пользовательском requestSerializer вы можете переопределить
- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request
withParameters:(id)parameters
error:(NSError *__autoreleasing *)error;
Внутри реализации этого метода у вас будет доступ к NSURLRequest
, чтобы вы могли сделать что-то вроде этого
- (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;
}
Вы можете заглянуть внутрь реализации AFJSONRequestSerializer
для примера настройки настраиваемого содержимого тела HTTP.
Ответ 6
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
}];
Это лучший и самый сжатый способ, который я нашел.
Ответ 7
Может быть, мы можем использовать NSMutableURLRequest, вот код:
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];