AFNetworking 500响应机构
我一直在我的应用程序中使用AFNetworking 2.0。 我注意到,如果我的Web服务返回一个500状态码,我没有得到响应的主体。
这里是我的PHP代码的一个例子
try { $conn = new PDO( "sqlsrv:server=$serverName;Database = $database", $uid, $pwd); $conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); return $conn; } catch( PDOException $e ) { $response->status(500); echo( "Connection Error: " . $e->getMessage() ); }
如果我使用一个简单的rest客户端,这是一个响应主体的例子。
Connection Error: SQLSTATE[08001]: [Microsoft][SQL Server Native Client 11.0]SQL Server Network Interfaces: Error Locating Server/Instance Specified [xFFFFFFFF].
但是,这似乎是我能从AFNetworking得到的唯一答复
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn't be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0x15e58fa0 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
这是我的Objective-C代码的一部分。
...} failure:^(NSURLSessionDataTask *task, NSError *error) { NSLog(@"%@",error.description); }];
有没有一种方法可以得到响应体?
编辑:更多的澄清代码
下面是我的AFHTTPSessionManager的子类的一部分
@implementation MSMAMobileAPIClient + (MSMAMobileAPIClient *)sharedClient { static MSMAMobileAPIClient *_sharedClient = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _sharedClient = [[MSMAMobileAPIClient alloc] initWithDefaultURL]; }); return _sharedClient; } - (id)initWithDefaultURL { return [self initWithBaseURL:[NSURL URLWithString:[NSString stringWithFormat:@"https://%@/mamobile/index.php/" ,[[NSUserDefaults standardUserDefaults] stringForKey:@"serviceIPAddress"]]]]; } - (id)initWithBaseURL:(NSURL *)url { self = [super initWithBaseURL:url]; if (!self) { return nil; } self.responseSerializer = [AFCompoundResponseSerializer compoundSerializerWithResponseSerializers:@[[AFJSONResponseSerializer serializer], [AFHTTPResponseSerializer serializer]]]; return self; }
我尝试将响应序列化器设置为AFCompoundResponseSerializer,但似乎没有什么区别
下面是我称之为图书pipe理员的一个子类的例子。
-(void)searchForItemWithString:(NSString *)searchString withCompletionBlock:(arrayBlock)block { self.inventorySearchBlock = block; NSDictionary *parameters = @{@"query": searchString}; [[MSMAMobileAPIClient sharedClient] GET:@"inventory/search" parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) { if (!responseObject) { NSLog(@"Error parsing JSON"); } else { //do stuff with the json dictionary that's returned.. } } failure:^(NSURLSessionDataTask *task, NSError *error) { NSLog(@"Error: %@",error.description); }]; }
更新:我创build了一个github存储库,以包含我正在使用的最新代码。 所有的更改将在那里发布。 https://github.com/Hackmodford/HMFJSONResponseSerializerWithData
答案来自github上的这个问题。 https://github.com/AFNetworking/AFNetworking/issues/1397
gfiumara是提出这个的开发者。 我只稍微修改了他的AFJSONResponseSerializer的子类,以包含一个实际的string,而不是NSData
//MSJSONResponseSerializerWithData.h #import "AFURLResponseSerialization.h" /// NSError userInfo key that will contain response data static NSString * const JSONResponseSerializerWithDataKey = @"JSONResponseSerializerWithDataKey"; @interface MSJSONResponseSerializerWithData : AFJSONResponseSerializer @end
// MSJSONResponseSerializerWithData.m #import "MSJSONResponseSerializerWithData.h" @implementation MSJSONResponseSerializerWithData - (id)responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing *)error { if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) { if (*error != nil) { NSMutableDictionary *userInfo = [(*error).userInfo mutableCopy]; userInfo[JSONResponseSerializerWithDataKey] = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSError *newError = [NSError errorWithDomain:(*error).domain code:(*error).code userInfo:userInfo]; (*error) = newError; } return (nil); } return ([super responseObjectForResponse:response data:data error:error]); } @end
这里是我如何在故障块中使用它的一个例子。
} failure:^(NSURLSessionDataTask *task, NSError *error) { NSLog(@"%@",[error.userInfo objectForKey:@"JSONResponseSerializerWithDataKey"]); }];
您需要使用AFCompoundSerializer
来告诉AFNetworking框架如何处理它可能收到的所有可能的响应。 默认情况下,它只会尝试映射JSON。 一个复合串行器将通过串行器,直到find一个不会引发错误。
你想使用:
+ (instancetype)compoundSerializerWithResponseSerializers:(NSArray *)responseSerializers
在AFCompoundResponseSerializer
(在AFURLResponseSerialization.h
)。
您需要传递一个可以处理响应的序列化程序。 数组中的一个序列化程序应该是AFHTTPResponseSerializer
一个实例来处理你的错误响应。
如果您将我的类别包含在您的项目中,则如下所示:
[mySessionManager POST:@"some-api" parameters:params success:^(NSURLSessionDataTask *task, NSDictionary *responseObject) { ... } failure:^(NSURLSessionDataTask *task, NSError *error) { id responseObject = error.userInfo[kErrorResponseObjectKey]; ... do something with the response ... }];
这是我的类别的代码。 它调整AFURLSessionManager注入完成处理程序中的垫片。 Shim将响应放入NSError的userInfo中。
- 从Login ViewController提供先前活动的ViewController
- <Error>:CGAffineTransformInvert:奇异matrix
- 调整在drawRect中绘制的矩形的大小
- 在SKScene上呈现一个viewController
- parsing无效会话令牌(代码:209,版本:1.7.1)
- iOS 7.1 Sprite工具包AVAudioSession在进入背景时崩溃
- 不能通过点击UITextVIew中的邮件链接显示MFMailComposeViewController(iOS 8 beta bug)
- IOS UIImageView以黑色背景显示
- 从iOS sdk中获取date