-1

我有一个应用程序,用户可以在其中使用 Instapaper 进行身份验证。但是,他们需要订阅 Instapaper 才能执行此操作,因此如果他们尝试使用未订阅 Instapaper 的帐户登录,我想向他们显示错误。

但是当他们尝试登录时,AFNetworking认为登录成功,然后在控制台显示此错误:

错误:错误域 = AFNetworkingErrorDomain 代码 = -1011 “预期状态代码在 (200-299),得到 400” UserInfo = 0x8374840 {NSLocalizedRecoverySuggestion = [{“error_code”:1041,“消息”:“需要订阅帐户”,“类型": "错误"}], AFNetworkingOperationFailingURLRequestErrorKey=https://www.instapaper.com/api/1/bookmarks/list>, NSErrorFailingURLKey= https://www.instapaper.com/api/1/bookmarks/list , NSLocalizedDescription = (200-299) 中的预期状态代码,得到 400,AFNetworkingOperationFailingURLResponseErrorKey=}

我使用的是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 订阅帐户?

4

2 回答 2

1

根据您的情况,我认为您不会触发失败阻止,因为您的请求没有失败。您正在收到来自 Web 服务的响应。根据我的经验,只有当您由于网络可用性或类似情况而无法获得响应时,才会执行失败块。

因此,您需要在成功块中处理帐户错误。一种方法是读取响应中返回的状态代码。如果状态码是 400,就像您的控制台显示的那样,请提醒用户。

您可以按照此处使用的方法“https://stackoverflow.com/q/8469492/2670912”

于 2013-08-10T19:13:28.740 回答
0

正如 WeekendCodeWarrior 所说,似乎有了这个实现,即使他们无法提出进一步的请求,它也会认为它是成功的。吐出错误的代码实际上是我在提出请求后所做的 NSLog(哎呀,没有意识到这是我的代码输出),因为我认为一切都很好。

我的解决方案只是在该成功块中向 API 发出请求,检查该请求的结果确实response返回了一个对象),然后对该response对象采取相应的行动。

于 2013-08-11T16:54:43.280 回答