afnetworking 3.0迁移:如何使用标题和HTTP正文进行POST

我试图做一个POST请求有HTTPHeader字段和HTTP正文的YouTube的API。

以前在AFNetworking 2.0版中,我曾经这样做过,

NSDictionary *parameters = @{@"snippet": @{@"textOriginal":self.commentToPost.text,@"parentId":self.commentReplyingTo.commentId}}; NSString *url = [NSString stringWithFormat:@"https://www.googleapis.com/youtube/v3/comments?part=snippet&access_token=%@",[[LoginSingleton sharedInstance] getaccesstoken]]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; [request setHTTPMethod:@"POST"]; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; NSError *error; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:&error]; NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; // And finally, add it to HTTP body and job done. [request setHTTPBody:[jsonString dataUsingEncoding:NSUTF8StringEncoding]]; AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; manager.requestSerializer.timeoutInterval=[[[NSUserDefaults standardUserDefaults] valueForKey:@"timeoutInterval"] longValue]; manager.requestSerializer = [AFJSONRequestSerializer serializer]; AFHTTPRequestOperation *operation = [manager HTTPRequestOperationWithRequest:request progress:nil success:^(NSURLSessionTask *task, id responseObject) { NSLog(@"Reply JSON: %@", responseObject); } } failure:^(NSURLSessionTask *operation, NSError *error) { NSLog(@"Error: %@, %@, %@, %@, %@", error, operation.responseObject, operation.responseData, operation.responseString, operation.request); }]; [operation start]; 

3.0版的迁移文档用AFHTTPRequestOperationManagerreplaceAFHTTPRequestOperationManager但是我似乎无法findAFHTTPSessionManagerHTTPRequestOperationWithRequest方法。

我尝试使用constructingBodyWithBlock但它不工作,也许是因为我没有正确地做。

这是我迄今为止不起作用的:

 NSDictionary *body = @{@"snippet": @{@"topLevelComment":@{@"snippet":@{@"textOriginal":self.commentToPost.text}},@"videoId":self.videoIdPostingOn}}; NSError *error; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:body options:0 error:&error]; NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; AFJSONRequestSerializer *serializer = [AFJSONRequestSerializer serializer]; serializer.timeoutInterval= [[[NSUserDefaults standardUserDefaults] valueForKey:@"timeoutInterval"] longValue]; [serializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; [serializer setValue:@"application/json" forHTTPHeaderField:@"Accept"]; [manager POST:[NSString stringWithFormat:@"https://www.googleapis.com/youtube/v3/commentThreads?part=snippet&access_token=%@",[[LoginSingleton sharedInstance] getaccesstoken]] parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) { [formData appendPartWithHeaders:nil body:[jsonString dataUsingEncoding:NSUTF8StringEncoding]]; } progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"Reply JSON: %@", responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"Error: %@, %@, %@, %@, %@", error, operation.responseObject, operation.responseData, operation.responseString, operation.request); }]; 

与AFNetworking 3.0调用POST方法的另一种方法是:

 AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; manager.requestSerializer = [AFJSONRequestSerializer serializer]; [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; [manager POST:url parameters:parametersDictionary progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"success!"); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"error: %@", error); }]; 

希望能帮助到你!

我能够自己弄清楚这一点。

这是解决scheme。

首先,您需要首先从AFJSONRequestSerializer创buildNSMutableURLRequest ,您可以在其中将方法types设置为POST。

在这个请求中,你设置了你的HTTPHeaderFields后,你就可以设置HTTPHeaderFields 。 确保在为内容types设置Header字段后设置主体,否则api将给出400错误。

然后在pipe理器上使用上面的NSMutableURLRequest创build一个dataTaskWithRequest 。 不要忘记在最后resume dataTask,否则什么都不会发送。 这是我的解决scheme代码,希望有人能成功地使用它:

 NSDictionary *body = @{@"snippet": @{@"topLevelComment":@{@"snippet":@{@"textOriginal":self.commentToPost.text}},@"videoId":self.videoIdPostingOn}}; NSError *error; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:body options:0 error:&error]; NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; NSMutableURLRequest *req = [[AFJSONRequestSerializer serializer] requestWithMethod:@"POST" URLString:[NSString stringWithFormat:@"https://www.googleapis.com/youtube/v3/commentThreads?part=snippet&access_token=%@",[[LoginSingleton sharedInstance] getaccesstoken]] 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]]; [[manager dataTaskWithRequest:req completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { if (!error) { NSLog(@"Reply JSON: %@", responseObject); if ([responseObject isKindOfClass:[NSDictionary class]]) { //blah blah } } else { NSLog(@"Error: %@, %@, %@", error, response, responseObject); } }] resume]; 
  -(void)postRequest:(NSString *)urlStr parameters:(NSDictionary *)parametersDictionary completionHandler:(void (^)(NSString*, NSDictionary*))completionBlock{ NSURL *URL = [NSURL URLWithString:urlStr]; AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; [manager POST:URL.absoluteString parameters:parametersDictionary progress:nil success:^(NSURLSessionDataTask *task, id responseObject) { NSError* error; NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:&error]; completionBlock(@"Success",json); } failure:^(NSURLSessionDataTask *task, NSError *error) { NSLog(@"Error: %@", error); completionBlock(@"Error",nil); }]; } 

这种方法对AFNetworking 3.0工作正常。

 // for HTTTPBody with JSON [sessionManager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; [sessionManager.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, id parameters, NSError * __autoreleasing * error) { NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:error]; NSString *argString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; return argString; }]; [sessionManager POST:urlString parameters:parameters progress:nil success:^(NSURLSessionDataTask *task, id responseObject) { if (completion) { completion(responseObject, nil); } } failure:^(NSURLSessionDataTask *task, NSError *error) { if (completion) { NSData *errorData = [error.userInfo objectForKey:@"com.alamofire.serialization.response.error.data"]; NSDictionary *responseErrorObject = [NSJSONSerialization JSONObjectWithData:errorData options:NSJSONReadingAllowFragments error:nil]; completion(responseErrorObject, error); } }]; // For HTTPBody with custom String format [sessionManager.requestSerializer setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; [sessionManager.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, id parameters, NSError * __autoreleasing * error) { NSString *argString = [self dictionaryToString:parameters]; return argString; }]; [sessionManager POST:urlString parameters:parameters progress:nil success:^(NSURLSessionDataTask *task, id responseObject) { if (completion) { completion(responseObject, nil); } } failure:^(NSURLSessionDataTask *task, NSError *error) { if (completion) { NSData *errorData = [error.userInfo objectForKey:@"com.alamofire.serialization.response.error.data"]; NSDictionary *responseErrorObject = [NSJSONSerialization JSONObjectWithData:errorData options:NSJSONReadingAllowFragments error:nil]; completion(responseErrorObject, error); } }]; 

使用常见的NSObject类方法调用与AFNetworking 3.0文件服务这是我的重复的答案,但它已被AFNetworking 3.0更新首先使NSObject类像Webservice.hWebservice.m

Webservice.h

 @interface Webservice : NSObject + (void)requestPostUrl:(NSString *)strURL parameters:(NSDictionary *)dictParams success:(void (^)(NSDictionary *responce))success failure:(void (^)(NSError *error))failure; @end 

Webservice.m你的nsobject.m文件看起来像这样( 在.m文件中添加两个函数

 #import "Webservice.h" #define kDefaultErrorCode 12345 @implementation Webservice + (void)requestPostUrl:(NSString *)strURL parameters:(NSDictionary *)dictParams success:(void (^)(NSDictionary *responce))success failure:(void (^)(NSError *error))failure { AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; [manager setResponseSerializer:[AFHTTPResponseSerializer serializer]]; [manager POST:strURL parameters:dictParams progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { if([responseObject isKindOfClass:[NSDictionary class]]) { if(success) { success(responseObject); } } else { NSDictionary *response = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:nil]; if(success) { success(response); } } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { if(failure) { failure(error); } }]; } @end 

确保您必须将成功的字典密钥replace为处理响应callback函数的消息

使用像这样从任何viewControllers和任何viewControllers任何方法调用这个常用的方法。 暂时我使用viewDidLoad调用这个WS。

  - (void)viewDidLoad { [super viewDidLoad]; NSDictionary *dictParam = @{@"parameter1":@"value1",@"parameter1":@"value2"}; [Webservice requestPostUrl:@"add your webservice URL here" parameters:dictParam success:^(NSDictionary *responce) { //Success NSLog(@"responce:%@",responce); //do code here } failure:^(NSError *error) { //error }]; } 

在上面的方法中添加你的参数,值和web服务的URL。 你可以很容易地使用这个NSObjcet类。 欲了解更多详情,请访问AFNetworking 3.0或我的旧AFANSworking 2.0 answear 。

 NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:log.text, @"email", pass.text, @"password", nil]; AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; manager.requestSerializer = [AFHTTPRequestSerializer serializer]; [manager POST:@"add your webservice URL here" parameters:dict progress:nil success:^(NSURLSessionTask *task, id responseObject) { NSLog(@"%@", responseObject); } failure:^(NSURLSessionTask *operation, NSError *error) { NSLog(@"Error: %@", error); }]; 
 /** * Services gateway * Method get response from server * @parameter -> object: request josn object ,apiName: api endpoint * @returm -> void * @compilationHandler -> success: status of api, response: respose from server, error: error handling */ + (void)getDataWithObject:(NSDictionary *)object onAPI:(NSString *)apiName withController:(UIViewController*)controller :(void(^)(BOOL success,id response,NSError *error))compilationHandler { controller = controller; [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; // set request type to json manager.requestSerializer = [AFJSONRequestSerializer serializer]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; // post request to server [manager POST:apiName parameters:object success:^(AFHTTPRequestOperation *operation, id responseObject) { // NSError *error; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:responseObject options:0 error:&error]; //NSString *JSONString = [[NSString alloc] initWithBytes:[jsonData bytes] length:[jsonData length] encoding:NSUTF8StringEncoding]; //// // check the status of API NSDictionary *dict = responseObject; NSString *statusOfApi = [[NSString alloc]initWithFormat:@"%@" ,[dict objectForKey:@"OK"]]; // IF Status is OK -> 1 so complete the handler if ([statusOfApi isEqualToString:@"1"] ) { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; compilationHandler(TRUE,responseObject,nil); } else { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; NSArray *errorMessages = [responseObject objectForKey:@"messages"]; NSString *message = [errorMessages objectAtIndex:0]; [Utilities showAlertViewWithTitle:apiName message:message]; compilationHandler(FALSE,responseObject,nil); } } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSString *message = [NSString stringWithFormat:@"%@",[error localizedDescription]]; NSLog(@"Message is %@", message); NSString *errorMessage = [NSString stringWithFormat:@"%@",[error localizedDescription]]; if (!([message rangeOfString:@"The request timed out."].location == NSNotFound)) { [Utilities showAlertViewWithTitle:apiName message:errorMessage]; } compilationHandler(FALSE,errorMessage,nil); }]; } 

接受的答案#Pranoy C转换为AFNetworking 3.0

  NSError *writeError = nil; NSData* jsonData = [NSJSONSerialization dataWithJSONObject:params options:NSJSONWritingPrettyPrinted error:&writeError]; NSString* jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:120]; [request setHTTPMethod:@"POST"]; [request setValue: @"application/json; encoding=utf-8" forHTTPHeaderField:@"Content-Type"]; [request setValue: @"application/json" forHTTPHeaderField:@"Accept"]; [request setHTTPBody: [jsonString dataUsingEncoding:NSUTF8StringEncoding]]; AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; [[manager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { if (!error) { NSLog(@"Reply JSON: %@", responseObject); if ([responseObject isKindOfClass:[NSDictionary class]]) { //blah blah } } else { NSLog(@"Error: %@", error); NSLog(@"Response: %@",response); NSLog(@"Response Object: %@",responseObject); } }] resume]; 
 - (instancetype)init { self = [super init]; if (self) { [self configureSesionManager]; } return self; } #pragma mark - Private - (void)configureSesionManager { sessionManager = [AFHTTPSessionManager manager]; sessionManager.responseSerializer = [AFJSONResponseSerializer serializer]; sessionManager.responseSerializer.acceptableContentTypes = [sessionManager.responseSerializer.acceptableContentTypes setByAddingObject:@"text/html"]; sessionManager.requestSerializer = [AFHTTPRequestSerializer serializer]; sessionManager.requestSerializer.timeoutInterval = 60; } #pragma mark - Public - (void)communicateUsingPOSTMethod:(NSString*)pBaseURL parameterDictionary:(NSDictionary*)pParameterDictionary success:(void(^)(id))pSuccessCallback failure:(void(^)(NSError* error))pFailiureCallback { [sessionManager POST:pBaseURL parameters:pParameterDictionary progress:nil success:^(NSURLSessionTask *task, id responseObject) { pSuccessCallback(responseObject); } failure:^(NSURLSessionTask *operation, NSError *error) { pFailiureCallback(error); }]; } 
 #import <Foundation/Foundation.h> #import "UserDetailObject.h" #import "AFNetworking.h" #import "XMLReader.h" //macros定义成功block callback成功后得到的信息typedef void (^HttpSuccess)(id data); //macros定义失败block callback失败信息typedef void (^HttpFailure)(NSError *error); @interface NetworkManager : NSObject<NSXMLParserDelegate, NSURLConnectionDelegate> @property (strong, nonatomic) NSMutableData *webData; @property (strong, nonatomic) NSMutableString *soapResults; @property (strong, nonatomic) NSXMLParser *xmlParser; @property (nonatomic) BOOL elementFound; @property (strong, nonatomic) NSString *matchingElement; @property (strong, nonatomic) NSURLConnection *conn; //请求水文信息数据+ (void)sendRequestForSQInfo:(UserDetailObject *)detailObject success:(HttpSuccess)success failure:(HttpFailure)failure; //get请求+(void)getWithUrlString:(NSString *)urlString success:(HttpSuccess)success failure:(HttpFailure)failure; //post请求+(void)postWithUrlString:(NSString *)urlString parameters:(NSDictionary *)parameters success:(HttpSuccess)success failure:(HttpFailure)failure; @end 

NetworkManager.m

  #import "NetworkManager.h" @implementation NetworkManager @synthesize webData; @synthesize soapResults; @synthesize xmlParser; @synthesize elementFound; @synthesize matchingElement; @synthesize conn; + (void)sendRequestForSQInfo:(UserDetailObject *)detailObject success:(HttpSuccess)success failure:(HttpFailure)failure{ NSString *parameter = @"{\"endDate\":\"2015-06-01 08\",\"beginDate\":\"2015-06-01 08\"}"; NSString *urlStr = @"http://10.3.250.136/hwccysq/cxf/water"; NSString *methodName = @"getSqInfo"; AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; //回复的序列化manager.responseSerializer = [AFHTTPResponseSerializer serializer]; [[manager dataTaskWithRequest:[self loadRequestWithParameter:parameter url:urlStr methodName:methodName] completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { if (!error) { success(responseObject); } else { // NSLog(@"Error: %@, %@, %@", error, response, responseObject); failure(error); } }] resume]; } + (NSMutableURLRequest *)loadRequestWithParameter:(NSString *)parameter url:(NSString *)urlString methodName:(NSString *)methodName{ NSString *soapMessage = [NSString stringWithFormat: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>" "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:agen=\"http://agent.water.tjswfxkh.lonwin.com/\" >" "<soapenv:Body>" "<agen:%@>" "<arg0>%@</arg0>" "</agen:%@>" "</soapenv:Body>" "</soapenv:Envelope>", methodName,parameter,methodName ]; // 将这个XMLstring打印出来NSLog(@"%@", soapMessage); // 创buildURL,内容是前面的请求报文报文中第二行主机地址加上第一行URL字段NSURL *url = [NSURL URLWithString:urlString]; // 根据上面的URL创build一个请求NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url]; NSString *msgLengt = [NSString stringWithFormat:@"%ld", [soapMessage length]]; // 添加请求的详细信息,与请求报文前半部分的各字段对应[req addValue:@"application/soap+xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; [req addValue:msgLengt forHTTPHeaderField:@"Content-Length"]; // 设置请求行方法为POST,与请求报文第一行对应[req setHTTPMethod:@"POST"]; // 将SOAP消息加到请求中[req setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]]; return req; } //GET请求+(void)getWithUrlString:(NSString *)urlString success:(HttpSuccess)success failure:(HttpFailure)failure{ //创build请求pipe理者AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; //内容typesmanager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/json",@"text/javascript",@"text/html", nil]; //get请求[manager GET:urlString parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) { //数据请求的进度} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { success(responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { failure(error); }]; } //POST请求+(void)postWithUrlString:(NSString *)urlString parameters:(NSDictionary *)parameters success:(HttpSuccess)success failure:(HttpFailure)failure{ //创build请求pipe理者AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; // manager.responseSerializer = [AFHTTPResponseSerializer serializer]; //内容typesmanager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/json",@"text/javascript",@"text/html", nil]; //post请求[manager POST:urlString parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) { //数据请求的进度} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { success(responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { failure(error); }]; } @end 

然后在控制器中添加请求

 UserDetailObject *detailObject = [[UserDetailObject alloc]init]; [NetworkManager sendRequestForSQInfo:detailObject success:^(id data) { NSXMLParser *parser = [[NSXMLParser alloc]initWithData:data]; NSError *parseError = nil; NSDictionary *dict = [XMLReader dictionaryForNSXMLParser:parser error:&parseError]; NSLog(@"JSON: - %@", dict); } failure:^(NSError *error) { NSLog(@"%@",error); }]; 

https://github.com/Rita5969/afnetwork3.0-for-webservice