ios - example - obtener responseObject en el bloque de falla AFNetworking 3.0
afnetworking swift 4 (6)
He encontrado solución en GitHub :
@interface ResponseSerializer : AFJSONResponseSerializer
@end
@implementation ResponseSerializer
- (id)responseObjectForResponse:(NSURLResponse *)response
data:(NSData *)data
error:(NSError *__autoreleasing *)errorPointer
{
id responseObject = [super responseObjectForResponse:response data:data error:errorPointer];
if (*errorPointer) {
NSError *error = *errorPointer;
NSMutableDictionary *userInfo = [error.userInfo mutableCopy];
userInfo[@"responseObject"] = responseObject;
*errorPointer = [NSError errorWithDomain:error.domain code:error.code userInfo:[userInfo copy]];
}
return responseObject;
}
@end
Y luego asignarlo a su gerente:
self.manager.responseSerializer = [ResponseSerializer serializer];
¿Cómo puedo obtener la cadena de respuesta del bloque de falla en AFNetworking 3.x,
En la versión 2.x la forma de hacerlo era:
[manager GET:path parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSDictionary *dictionary_FetchResult = responseObject;
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSDictionary *dictionary_FetchResult = operation.responseObject;
}];
pero en la versión 3.x no hay ninguna operación en el parámetro del bloque de retorno como se muestra a continuación:
[manager POST:path parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSDictionary *dictionary_FetchResult = responseObject;
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"Error: %@", error);
}];
Así que esperaba que alguien fuera capaz de lograrlo.
He encontrado una solución para esto que funciona perfectamente. En veloz
if let userInfo : NSDictionary = error.userInfo as NSDictionary {
if let innerError : NSError = userInfo.objectForKey("NSUnderlyingError") as? NSError {
if let innerUserInfo : NSDictionary = innerError.userInfo as NSDictionary {
if innerUserInfo.objectForKey(AFNetworkingOperationFailingURLResponseDataErrorKey) != nil {
let StrError = NSString(data: innerUserInfo.objectForKey(AFNetworkingOperationFailingURLResponseDataErrorKey) as! NSData, encoding: NSUTF8StringEncoding)
print(StrError)
}
} else if let errResponse: String = String(data: (error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] as! NSData), encoding: NSUTF8StringEncoding) {
print(errResponse)
}
}
}
y el código Objective-C es
NSDictionary *userinfo1 = [[NSDictionary alloc] initWithDictionary:error.userInfo];
if(userinfo1) {
NSError *innerError = [userinfo1 valueForKey:@"NSUnderlyingError"];
if(innerError) {
NSDictionary *innerUserInfo = [[NSDictionary alloc] initWithDictionary:innerError.userInfo];
if(innerUserInfo)
{
if([innerUserInfo objectForKey:AFNetworkingOperationFailingURLResponseDataErrorKey])
{
NSString *strError = [[NSString alloc] initWithData:[innerUserInfo objectForKey:AFNetworkingOperationFailingURLResponseDataErrorKey] encoding:NSUTF8StringEncoding];
NSLog(@"Error is : %@",strError);
}
}
} else
{
NSString *errResponse = [[NSString alloc] initWithData:[userinfo1 valueForKey:@"AFNetworkingOperationFailingURLResponseDataErrorKey"] encoding:NSUTF8StringEncoding];
if(errResponse)
{
NSLog(@"%@",errResponse);
}
}
}
Se corrigió algún código aquí, manejando adecuadamente los opcionales Swift 3 (.1) ...
let nserror = error as NSError
if let errordata = nserror.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] as? Data {
if let errorResponse = String(data: errordata, encoding: String.Encoding.utf8) {
print("errorResponse: /(errorResponse)")
}
}
Solo haz esto en tu bloque de falla:
NSString* errResponse = [[NSString alloc] initWithData:(NSData *)error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] encoding:NSUTF8StringEncoding];
NSLog(@"%@",errResponse);
Para Swift: -
var errResponse: String = String(data: (error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] as! NSData), encoding: NSUTF8StringEncoding)
NSLog("%@", errResponse)
Actualizado para Swift 4.1
var errResponse: String = String(data: (error._userInfo![AFNetworkingOperationFailingURLResponseDataErrorKey] as! Data), encoding: String.Encoding.utf8)!
print(errResponse)
- (void)requestWithURL:(NSString *)url parameterDictionary:(NSMutableDictionary *)data requestType:(NSString *)reqType handler:(NSObject *)handler selector:(SEL)selector
{
// reqType is POST or GET
// handler would be self if you define selector method in same class
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSMutableURLRequest *req = [[AFJSONRequestSerializer serializer] requestWithMethod:reqType URLString:[NSString stringWithFormat:@"%@",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"];
if (data != nil) {
NSLog(@"Data is not nil");
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:data options:0 error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
[req setHTTPBody:[jsonString dataUsingEncoding:NSUTF8StringEncoding]];
}else{
NSLog(@"Data is nil");
}
[[manager dataTaskWithRequest:req completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
if (!error) {
// NSLog(@"Reply JSON: %@", responseObject);
[handler performSelector:selector withObject:responseObject];
if ([responseObject isKindOfClass:[NSDictionary class]]) {
//blah blah
}
} else {
NSLog(@"Error: %@, %@, %@", error, response, responseObject);
[handler performSelector:selector withObject:responseObject];
}
}] resume];
}
let responseData:NSData = (error as NSError).userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] as! NSData
let s :String = String(data: responseData as Data, encoding: String.Encoding.utf8)!
Para Swift 3