AFNetworking выдает ошибку, но как ее отобразить?

У меня есть приложение, где пользователь может пройти аутентификацию с Instapaper. Однако для этого им нужна подписка Instapaper, поэтому, если они попытаются войти в систему с учетной записью, которая не подписана на Instapaper, я хочу показать им ошибку.

Но когда они пытаются войти, AFNetworking видит это как успешное, а затем отображает эту ошибку на консоли:

Ошибка: Ошибка Домен =AFNetworkingErrorDomain Code=-1011 "Ожидаемый код состояния в (200-299), получено 400" UserInfo=0x8374840 {NSLocalizedRecoverySuggestion=[{"error_code": 1041, "message": "Требуется учетная запись подписки", тип " ":" error "}], 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?

2 ответа

Решение

Исходя из вашей ситуации, я не думаю, что вы когда-нибудь вызовете блокировку сбоя, потому что ваш запрос не сбой. Вы получаете ответ от веб-службы. По моему опыту блок сбоя выполняется только в том случае, если вы не получили ответ из-за чего-то вроде доступности сети или чего-то подобного.

Поэтому вам нужно обработать ошибку учетной записи в блоке успеха. Один из способов сделать это - прочитать код состояния, который возвращается в ответе. Если код состояния 400, как показывает ваша консоль, предупредите пользователя.

Вы можете следовать методу, используемому здесь /questions/43434589/est-li-prostoj-sposob-poluchit-kod-sostoyaniya-http-v-bloke-sboya-ot-afhttpclient

Кажется, что с этой реализацией, как сказал WeekendCodeWarrior, она будет считаться успешной, даже если они не смогут делать дальнейшие запросы. Код, который выплевывал ошибку, на самом деле был NSLog, который я сделал (упс, не понял, что это был мой код, выводящий это) после выполнения запроса, поскольку я предполагал, что все в порядке.

Мое решение состояло в том, чтобы просто сделать запрос к API в этом блоке успеха, проверить результат этого запроса (который имеет response объект вернулся), а затем действовать соответственно на response объект.

Другие вопросы по тегам