我有一个应用程序,用户可以在其中使用Instapaper进行身份验证。然而,他们需要订阅Instapaper才能做到这一点,所以如果他们试图使用未订阅Instapaper.的帐户登录,我想向他们显示一个错误。
但当他们尝试登录时,AFNetworking认为它成功了,然后将此错误显示到控制台:
错误:错误域=AFNetworkingErrorDomain代码=-1011"应为状态代码在(200-299)中,得到400"UserInfo=0x8374840{NSLocalizedRecoverySuggestion=[{"error_code":1041,"message":"需要订阅帐户","type":"error"}],AFNetworkingOperationFailingURLRequestErrorKey=http://www.instapart.com/api/1/bookmarks/list>,NSErrorFailingURLKey=https://www.instantpaper.com/api/1/bookmarks/list,NSLocalizedDescription=(200-299)中的预期状态代码,得到400,AF网络操作失败URLResponseErrorKey=}
我所使用的只是AFXAuthClient,它是对AFNetworking的修改。我将其子类化,以创建一个自定义的Instapaper API客户端,看起来像这样:
#import "AFInstapaperClient.h"
#import "AFJSONRequestOperation.h"
@implementation AFInstapaperClient
+ (AFInstapaperClient *)sharedClient {
static AFInstapaperClient *sharedClient = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedClient = [[AFInstapaperClient alloc] initWithBaseURL:[NSURL URLWithString:@"https://www.instapaper.com/"]
key:@"..."
secret:@"..."];
});
return sharedClient;
}
- (id)initWithBaseURL:(NSURL *)url {
if (self = [super initWithBaseURL:url]) {
[self registerHTTPOperationClass:[AFJSONRequestOperation class]];
[self setDefaultHeader:@"Accept" value:@"application/json"];
}
return self;
}
@end
当他们登录时,会执行以下代码:
- (IBAction)doneButtonPressed:(UIBarButtonItem *)sender {
[[AFInstapaperClient sharedClient] authorizeUsingXAuthWithAccessTokenPath:@"/api/1/oauth/access_token"
accessMethod:@"POST"
username:self.loginBox.text
password:self.passwordBox.text
success:^(AFXAuthToken *accessToken) {
// Save the token information into the Keychain
[UICKeyChainStore setString:accessToken.key forKey:@"InstapaperKey"];
[UICKeyChainStore setString:accessToken.secret forKey:@"InstapaperSecret"];
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@"Login Successful"
message:@"Your articles are being downloaded now and will appear in your queue."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles: nil];
[alert show];
[[NSUserDefaults standardUserDefaults] setObject:@"YES" forKey:@"IsLoggedInToInstapaper"];
[self dismissViewControllerAnimated:YES completion:nil];
}
failure:^(NSError *error) {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@"Login Failed."
message:@"Are you connected to the internet? Instapaper may also be down. Try again later."
delegate:nil
cancelButtonTitle:@"Okay"
otherButtonTitles: nil];
[alert show];
}];
}
但代码永远不会进入故障块。我如何修改我的代码,以便告诉他们他们需要一个Instapaper订阅帐户?
根据您的情况,我认为您永远不会触发失败块,因为您的请求没有失败。您正在从web服务获得响应。根据我的经验,只有当你因为网络可用性或类似的原因而无法得到响应时,才会执行故障块
因此,您需要处理成功块中的帐户错误。一种方法是读取响应中返回的状态代码。如果状态代码是400,就像你的控制台显示的那样,那么提醒用户。
您可以按照此处使用的方法"https://stackoverflow.com/q/8469492/2670912"
正如WeekendCodeWarrior所说,似乎有了这个实现,即使他们无法提出进一步的请求,它也会认为它是成功的。吐出错误的代码实际上是我在发出请求后做的NSLog(哇,没有意识到这是我的代码输出),因为我认为一切都很好。
我的解决方案只是在成功块中向API发出请求,检查该请求的结果(返回了response
对象),然后对response
对象采取相应的操作。