ios 如何使用 AFNetwork 的 AFHTTPRequestOperationManager 设置 HTTP 请求正文?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19712612/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 02:41:49  来源:igfitidea点击:

How to set HTTP request body using AFNetwork's AFHTTPRequestOperationManager?

iosiphoneobjective-cipadafnetworking

提问by user2543991

I am using AFHTTPRequestOperationManager (2.0 AFNetworking library) for a REST POST request. But the manager only have the call to set the parameters.

我正在使用 AFHTTPRequestOperationManager(2.0 AFNetworking 库)进行 REST POST 请求。但是经理只能调用设置参数。

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

I need to set HTTP request body with a string as well. How can I do it using the AFHTTPRequestOperationManager? Thanks.

我还需要使用字符串设置 HTTP 请求正文。我如何使用 AFHTTPRequestOperationManager 来做到这一点?谢谢。

回答by Ganesh Guturi

I had the same problem and solved it by adding code as shown below:

我遇到了同样的问题,并通过添加如下所示的代码解决了它:

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

回答by Igor Bachek

for AFHTTPRequestOperationManager

对于 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);
}];

回答by Halyna Rubashko

Check what that convenience method (POST:parameters:success:failure) is doing under the hood and do it yourself to get access to actual NSMutableRequest object.

检查该便捷方法 (POST:parameters:success:failure) 在幕后做了什么,并自己动手以访问实际的 NSMutableRequest 对象。

I'm using AFHTTPSessionManager instead of AFHTTPRequestOperation but I imagine the mechanism is similar.

我使用 AFHTTPSessionManager 而不是 AFHTTPRequestOperation 但我想机制是相似的。

This is my solution:

这是我的解决方案:

  1. Setup Session Manager (headers etc)

  2. Manually create NSMutable request and add my HTTPBody, basically copying-pasting code inside that convenience method. Looks like this:

    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];
    
  1. 设置会话管理器(标题等)

  2. 手动创建 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];
    

回答by MichK

If you dig a little in sources of AFNetworking you will find that in case of POSTmethod parameters are set into body of your HTTP request.

如果您深入研究 AFNetworking 的来源,您会发现如果POST方法参数被设置到您的 HTTP 请求正文中。

Each key,value dictionary pair is added to the body in form key1=value1&key2=value2. Pairs are separated by & sign.

每个键值字典对都以 form 形式添加到正文中key1=value1&key2=value2。对由 & 符号分隔。

Search for application/x-www-form-urlencodedin AFURLRequestSerialization.m.

application/x-www-form-urlencodedAFURLRequestSerialization.m 中搜索。

In case of a string which is only a string, not key value pair then you might try to use AFQueryStringSerializationBlockhttp://cocoadocs.org/docsets/AFNetworking/2.0.3/Classes/AFHTTPRequestSerializer.html#//api/name/setQueryStringSerializationWithBlock: but this is only my guess.

如果字符串只是字符串,而不是键值对,那么您可以尝试使用AFQueryStringSerializationBlockhttp://cocoadocs.org/docsets/AFNetworking/2.0.3/Classes/AFHTTPRequestSerializer.html#//api/name/setQueryStringSerializationWithBlock: 但这只是我的猜测。

回答by Herre

You could create your own custom subclass of AFHTTPRequestSerializer, and set this as the requestSerializer for your AFHTTPRequestOperationManager.

您可以创建自己的自定义子类AFHTTPRequestSerializer,并将其设置为您的AFHTTPRequestOperationManager.

In this custom requestSerializer, you could override

在这个自定义 requestSerializer 中,您可以覆盖

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

Inside your implementation of this method, you'll have access to the NSURLRequest, so you could do something like this

在此方法的实现中,您将可以访问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;
}

You could take a look inside the implementation of AFJSONRequestSerializerfor an example of setting custom HTTP body content.

您可以查看 的实现内部,以AFJSONRequestSerializer获取设置自定义 HTTP 正文内容的示例。

回答by tdeegan

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

This is the best and most concise way that I have found.

这是我发现的最好和最简洁的方法。

回答by Hilen

May be we can use the NSMutableURLRequest, here is the code :

也许我们可以使用 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];