如何使用数组作为标头和 AFNetworking 进行 POST

Posted

技术标签:

【中文标题】如何使用数组作为标头和 AFNetworking 进行 POST【英文标题】:How to make POST with array as header and AFNetworking 【发布时间】:2017-06-20 10:39:14 【问题描述】:

这是标题:

                "url": "host/images/bla",
            "method": "POST",
            "header": [
                
                    "key": "Content-Type",
                    "value": "application/json",
                    "description": ""
                ,
                
                    "key": "Authorization",
                    "value": "Bearer token",
                    "description": ""
                
            ],
            "body":  ... 

我尝试分两种情况解决:

案例 1(崩溃):

NSDictionary *headerDict = @@"key": @"Content-Type",
                                 @"value": @"application/json",
                                 @"description": @"";

NSDictionary *headerDict1 = @@"key": @"Authorization",
                                 @"value": kBearerKey,
                                 @"description": @"";
NSArray *headerArray = @[headerDict, headerDict1];

[weakSelf.requestOperationManager.requestSerializer setValue:headerArray forHTTPHeaderField:@"header"];

案例 2(不会崩溃但也不起作用):

weakSelf.requestOperationManager.requestSerializer = [AFHTTPRequestSerializer serializer];
[weakSelf.requestOperationManager.requestSerializer setValue:@"Content-Type" forHTTPHeaderField:@"key"];
[weakSelf.requestOperationManager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"value"];
[weakSelf.requestOperationManager.requestSerializer setValue:@"Authorization" forHTTPHeaderField:@"key"];
[weakSelf.requestOperationManager.requestSerializer setValue:kBearerKey forHTTPHeaderField:@"value"];

无论如何,在 案例 1 中会生成一个警告(并且也会导致崩溃),因为 setValue 应该是 NSString 而不是 NSArray

【问题讨论】:

你需要将数组转换成json字符串: NSData *jsonData2 = [NSJSONSerialization dataWithJSONObject: headerArray options:NSJSONWritingPrettyPrinted error:&error]; NSString *jsonString = [[NSString alloc] initWithData:jsonData2 encoding:NSUTF8StringEncoding]; 这是有效的,但问题是数据解释器在@"application/json" 中添加了一个“\”,它看起来像 @"application\/json" : (lldb) po headerString [ " key”:“Content-Type”,“value”:“application\/json”,“description”:“”,“key”:“授权”,“value”:“Bearer xpkaVSckJSfCWzcXfODtiBu38B6mOMzPW....”, “描述”:“”] 【参考方案1】:

例如,您可以将 NSMutableDictionary 中的所有标头值保留为键/值对

NSDictionary *headersDict = @@"Content-Type": @"application/json",
                                  @"Authorization": kBearerKey ;

然后你可以迭代键值并设置http头

[headersDict enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL *stop) 
        [requestManager.requestSerializer setValue:obj forHTTPHeaderField:key];
    ];

在您的情况下,您使用的是数组。您可以迭代数组并设置标头值,希望这会有所帮助。

for (NSDictionary *dict in headerArray) 

        NSString *key = [dict objectForKey:@"key"];
        NSString *value = [dict objectForKey:@"value"];

        [requestManager.requestSerializer setValue:value forHTTPHeaderField:key];

【讨论】:

【参考方案2】:

试试这个;

NSError *error;

NSData *jsonData = [NSJSONSerialization:headerArray options:NSJSONWritingPrettyPrinted error:&error];                                                                                 

NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

[weakSelf.requestOperationManager.requestSerializer setValue:jsonString forHTTPHeaderField:@"header"];

【讨论】:

【参考方案3】:

试试这个:

AFNetworking 3

NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject: headerArray options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];

NSMutableURLRequest *req = [[AFJSONRequestSerializer serializer] requestWithMethod:@"POST" URLString:url parameters:nil error:nil];

req.timeoutInterval= [[[NSUserDefaults standardUserDefaults] valueForKey:@"timeoutInterval"] longValue];
[req setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[req setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[req setHTTPBody:[jsonString dataUsingEncoding:NSUTF8StringEncoding]];


NSURLSessionUploadTask *uploadTask;
uploadTask = [manager
              uploadTaskWithStreamedRequest:req
              progress:^(NSProgress * _Nonnull uploadProgress) 
                  dispatch_async(dispatch_get_main_queue(), ^
                  );
              
              completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) 
                  if (error) 
                      NSLog(@"Error: %@", [[NSString alloc]initWithData:[[error valueForKey:@"userInfo"] valueForKey:@"com.alamofire.serialization.response.error.data"] encoding:NSUTF8StringEncoding]);

                   else 
                  
              ];

[uploadTask resume];

【讨论】:

【参考方案4】:
NSDictionary *headerDict = @@"Content-Type": @"application/json", @"Authorization": kBearerKey;

[weakSelf.requestOperationManager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[weakSelf.requestOperationManager.requestSerializer setValue:kBearerKey forHTTPHeaderField:@"Authorization"];

【讨论】:

试试这个weakSelf.requestOperationManager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/plain"];

以上是关于如何使用数组作为标头和 AFNetworking 进行 POST的主要内容,如果未能解决你的问题,请参考以下文章

如何设置 AFNetworking 2.0 默认标头?

在 AFNetworking 3.0 中使用自定义 HTTP 标头

如何在 AfNetworking 3.0 中向请求添加标头?

AFNetworking 2.0:传递标头信息

如何删除 AFNetworking 中的 http 标头选项?

AFNetworking 2.0 和请求标头