Ошибка в библиотеке приводила к сотням сбоев, но я не могу точно определить это. У меня есть данные о сбое от пользователей, что является причиной этого сбоя?
Чтобы аутентифицировать Instapaper, который использует XAuth, я использую AFXAuthClient, который является расширением AFNetworking 1.0, который добавляет поддержку XAuth для аутентификации.
Это работает очень хорошо, для 99% моих пользователей. Но на несколько десятков это вызвало тонну сбоев (гораздо больше, чем любой другой сбой в моем приложении). Мое приложение использует Crashlytics, поэтому у меня есть информация о каждом сбое, но я не могу понять, как это исправить или даже как воссоздать его.
Информация
Crashlytics дает мне это для сообщения об ошибке:
Неустранимое исключение: NSInvalidArgumentException * setObjectForKey: объект не может быть nil (ключ: oauth_token)
И это для журналов:
Thread : Fatal Exception: NSInvalidArgumentException
0 CoreFoundation 0x2e355f4b __exceptionPreprocess + 130
1 libobjc.A.dylib 0x386e56af objc_exception_throw + 38
2 CoreFoundation 0x2e291667 -[__NSDictionaryM setObject:forKey:] + 818
3 Syllable 0x0007511f -[AFXAuthClient authorizationHeaderWithRequest:parameters:] + 224 (AFXAuthClient.m:224)
4 Syllable 0x000752ad -[AFXAuthClient requestWithMethod:path:parameters:] + 239 (AFXAuthClient.m:239)
5 Syllable 0x00069377 -[AppDelegate loadInstapaperArticles] + 356 (AppDelegate.m:356)
6 Syllable 0x000680fb -[AppDelegate application:performFetchWithCompletionHandler:] + 137 (AppDelegate.m:137)
7 UIKit 0x30d469d1 -[UIApplication _handleOpportunisticFetchWithSequenceNumber:] + 448
8 UIKit 0x30b38fbb -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 2010
9 UIKit 0x30b33353 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 714
10 UIKit 0x30ace41f -[UIApplication handleEvent:withNewEvent:] + 3130
11 UIKit 0x30acd721 -[UIApplication sendEvent:] + 72
12 UIKit 0x30b32b3d _UIApplicationHandleEvent + 664
13 GraphicsServices 0x32f6970d _PurpleEventCallback + 608
14 GraphicsServices 0x32f692f7 PurpleEventCallback + 34
15 CoreFoundation 0x2e3209df __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 34
16 CoreFoundation 0x2e32097b __CFRunLoopDoSource1 + 346
17 CoreFoundation 0x2e31f14f __CFRunLoopRun + 1398
18 CoreFoundation 0x2e289c27 CFRunLoopRunSpecific + 522
19 CoreFoundation 0x2e289a0b CFRunLoopRunInMode + 106
20 UIKit 0x30b31dd9 -[UIApplication _run] + 760
21 UIKit 0x30b2d049 UIApplicationMain + 1136
22 Syllable 0x0003817f main + 16 (main.m:16)
23 libdyld.dylib 0x38bedab7 start + 2
Видимо приложение передает ноль setObjectForKey:
, Вот где говорится, что это происходит (я поместил стрелку -> в строке) в AFXAuthClient.m (файл реализации для библиотеки AFXAuthClient):
- (NSMutableDictionary *)authorizationHeaderWithRequest:(NSURLRequest *)request parameters:(NSDictionary *)parameters
{
NSMutableDictionary *authorizationHeader = [[NSMutableDictionary alloc] initWithDictionary:@{@"oauth_nonce": _nonce,
@"oauth_signature_method": @"HMAC-SHA1",
@"oauth_timestamp": _timestamp,
@"oauth_consumer_key": self.consumerKey,
@"oauth_signature": AFHMACSHA1Signature([self baseStringWithRequest:request parameters:parameters], _consumerSecret, _token.secret),
@"oauth_version": @"1.0"}];
if (self.token)
--> [authorizationHeader setObject:RFC3986EscapedStringWithEncoding(self.token.key, NSUTF8StringEncoding) forKey:@"oauth_token"];
return authorizationHeader;
}
в RFC3986EscapedStringWithEncoding()
Функция, которую она вызывает, в начале говорит следующее:
// Escape per RFC 3986 standards as required by OAuth. Previously, not
// escaping asterisks (*) causes passwords with * to fail in
// Instapaper authentication
Мои пользователи действительно входят в систему с Instapaper, поэтому кажется, что у этой библиотеки были проблемы с Instapaper в прошлом. Я не уверен, что вызывает это в этом случае, или даже как воспроизвести это.
Моя единственная теория состояла в том, что Instapaper позволяет создавать учетные записи без пароля, поэтому, когда пользователь входит в систему без пароля, возможно, он передает ноль setObjectForKey
? Но нет, я попытался с учетной записью без пароля, и мое приложение не зависало вообще.
Что может быть причиной этой проблемы? Как бы это исправить? Если есть больше информации, которую я могу предоставить от Crashlytics, пожалуйста, просто скажите.
1 ответ
Во-первых, убедитесь, что вы используете последнюю версию - я нашел исправление от 7 месяцев назад для этой проблемы.
Во-вторых, если вы в курсе, я бы применил подход к изменению AFXAuthClient следующим образом:
if (self.token) {
NSString *escapedToken = RFC3986EscapedStringWithEncoding(self.token.key, NSUTF8StringEncoding);
if (escapedToken) {
/* guaranteed not to crash here */
[authorizationHeader setObject:escapedToken forKey:@"oauth_token"];
} else {
/* Log self.token you can inspect the types of tokens that are causing
invalid escapedTokens, perhaps using a service like Flurry. */
}
}
Это позволит вам собирать любые данные, вызывающие RFC3986EscapedStringWithEncoding
возвращать nil
, Очевидно, будьте осторожны с тем, как вы храните / передаете эти данные, так как это токен пользователя.
Плюс, это должно превратить эти сбои в ошибки проверки подлинности, что (вероятно) лучше.