-1

ユーザーが Instapaper で認証できるアプリがあります。ただし、これを行うには Instapaper のサブスクリプションが必要なので、Instapaper にサブスクライブしていないアカウントでログインしようとすると、エラーを表示したいと考えています。

しかし、ログインしようとすると、AFNetworkingはログインが成功したと見なし、次のエラーをコンソールに表示します。

エラー: エラー Domain=AFNetworkingErrorDomain Code=-1011 "Expected status code in (200-299), got 400" UserInfo=0x8374840 {NSLocalizedRecoverySuggestion=[{"error_code": 1041, "message": "サブスクリプション アカウントが必要です", "type ": "エラー"}]、AFNetworkingOperationFailingURLRequestErrorKey=https://www.instapaper.com/api/1/bookmarks/list>、NSErrorFailingURLKey = https://www.instapaper.com/api/1/bookmarks/list、NSLocalizedDescription =(200-299) の予期されるステータス コード、400 を取得、AFNetworkingOperationFailingURLResponseErrorKey=}

私が使用しているのは、 AFNetworkingの変更である AFXAuthClient だけです。これをサブクラス化して、次のようなカスタム 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 サービスからの応答を取得しています。私の経験では、障害ブロックは、ネットワークの可用性などのために応答を取得できなかった場合にのみ実行されます。

したがって、成功ブロックでアカウント エラーを処理する必要があります。これを行う 1 つの方法は、応答で返されるステータス コードを読み取ることです。コンソールに表示されているようにステータス コードが 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 に答える