在故障块 AFNetworking 3.0 上获取 responseObject
Posted
技术标签:
【中文标题】在故障块 AFNetworking 3.0 上获取 responseObject【英文标题】:get responseObject on failure block AFNetworking 3.0 【发布时间】:2016-01-29 11:21:36 【问题描述】:如何从 AFNetworking 3.x 中的故障块中获取响应字符串,
在 2.x 版本中,这样做的方法是:
[manager GET:path parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject)
NSDictionary *dictionary_FetchResult = responseObject;
failure:^(AFHTTPRequestOperation *operation, NSError *error)
NSDictionary *dictionary_FetchResult = operation.responseObject;
];
但在3.x版本中,返回块的参数中没有操作如下图:
[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);
];
所以我希望有人能够做到这一点。
【问题讨论】:
【参考方案1】:只需在你的失败块中执行此操作:-
NSString* errResponse = [[NSString alloc] initWithData:(NSData *)error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] encoding:NSUTF8StringEncoding];
NSLog(@"%@",errResponse);
对于 Swift:-
var errResponse: String = String(data: (error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] as! NSData), encoding: NSUTF8StringEncoding)
NSLog("%@", errResponse)
为 Swift 4.1 更新
var errResponse: String = String(data: (error._userInfo![AFNetworkingOperationFailingURLResponseDataErrorKey] as! Data), encoding: String.Encoding.utf8)!
print(errResponse)
【讨论】:
在swift中做什么? 如果我想从 url ios 下载图片怎么办 @Vizllx 如果我使用 error._userInfo 会被 AppStore 拒绝【参考方案2】:我找到了一个完美的解决方案。很快
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)
Objective-C 代码是
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);
【讨论】:
【参考方案3】:- (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];
【讨论】:
【参考方案4】:我在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
然后分配给你的经理:
self.manager.responseSerializer = [ResponseSerializer serializer];
【讨论】:
【参考方案5】:let responseData:NSData = (error as NSError).userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] as! NSData
let s :String = String(data: responseData as Data, encoding: String.Encoding.utf8)!
对于 Swift 3
【讨论】:
【参考方案6】:在这里修复了一些代码,正确处理选项。斯威夫特 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)")
【讨论】:
以上是关于在故障块 AFNetworking 3.0 上获取 responseObject的主要内容,如果未能解决你的问题,请参考以下文章
在 AFNetworking 故障块中弹出 UINavigationController
我如何在 AFNetworking 3.0 中获取 allHTTPHeaderFields