objective ios objective-c post afnetworking afnetworking-3

ios - objective - Afnetworking 3.0 Migration: cómo publicar con encabezados y cuerpo HTTP



afnetworking swift 4 (10)

Estoy tratando de hacer una solicitud POST que tiene campos HTTPHeader y un cuerpo HTTP para la API de youtube.

Anteriormente en la versión 2.0 de AFNetworking, solía hacerlo de esta manera, lo que funcionó:

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

Los documentos de migración para la versión 3.0 reemplazan AFHTTPRequestOperationManager con AFHTTPSessionManager Sin embargo, parece que no puedo encontrar un método HTTPRequestOperationWithRequest para AFHTTPSessionManager .

Intenté usar constructingBodyWithBlock pero no funciona tal vez porque no lo estoy haciendo correctamente.

Esto es lo que tengo hasta ahora que no funciona:

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


La respuesta aceptada de #Pranoy C se convierte para 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];


Otra forma de llamar a un método POST con AFNetworking 3.0 es:

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

¡Espero eso ayude!


Para HTTPBody con 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); } }];

Para HTTPBody con formato de cadena personalizado

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


Pude resolver esto yo mismo.

Aquí está la solución.

Primero, primero debe crear NSMutableURLRequest desde AFJSONRequestSerializer donde puede establecer el tipo de método en POST.

En esta solicitud, puede setHTTPBody después de haber configurado sus HTTPHeaderFields . Asegúrese de configurar el cuerpo después de haber configurado los campos de Encabezado para el tipo de contenido, de lo contrario, la API dará un error 400.

Luego, en el administrador, cree un dataTaskWithRequest utilizando el NSMutableURLRequest anterior. No olvide resume la DataTask al final o de lo contrario no se enviará nada todavía. Aquí está mi código de solución, espero que alguien pueda usar esto con éxito:

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


Use el método común de clase NSObject para llamar a Wenservices con AFNetworking 3.0 Esta es mi respuesta duplicada pero se actualizó con AFNetworking 3.0 Primero, haga que la clase NSObject como Webservice.h y Webservice.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 su archivo nsobject.m tiene este aspecto ( agregue dos funciones en el archivo .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

asegúrese de reemplazar la clave del diccionario con éxito y mensaje para manejar la función de devolución de llamada

Utilice de esta manera llamar a este método común desde cualquier viewcontroller.m y cualquier método desde cualquier viewControllers . para temporal estoy usando viewDidLoad para llamar a este 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 }]; }

agregue su parámetro, valores y URL de servicio web en el método anterior. puede usar fácilmente esta clase NSObjcet . Para obtener más detalles, visite AFNetworking 3.0 o mi antiguo answear con AFNetworking 2.0 .


#import <Foundation/Foundation.h> #import "UserDetailObject.h" #import "AFNetworking.h" #import "XMLReader.h" //宏定义成功block 回调成功后得到的信息 typedef void (^HttpSuccess)(id data); //宏定义失败block 回调失败信息 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 ]; // 将这个XML字符串打印出来 NSLog(@"%@", soapMessage); // 创建URL,内容是前面的请求报文报文中第二行主机地址加上第一行URL字段 NSURL *url = [NSURL URLWithString:urlString]; // 根据上面的URL创建一个请求 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{ //创建请求管理者 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; //内容类型 manager.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{ //创建请求管理者 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; // manager.responseSerializer = [AFHTTPResponseSerializer serializer]; //内容类型 manager.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

luego agregue solicitud en el controlador

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


/** * 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); }]; }


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

Este método funciona bien para AFNetworking 3.0.


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


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