0

XAuth を使用する Instapaper を認証するために、認証用の XAuth サポートを追加する AFNetworking 1.0 の拡張機能であるAFXAuthClientを使用します。

私のユーザーの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

どうやらアプリは に nil を渡してい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 ではパスワードなしでアカウントを作成できるため、ユーザーがパスワードなしでログインしている場合、nil をsetObjectForKey?に渡しているということでした。しかし、いいえ、パスワードのないアカウントで試してみましたが、アプリはまったくクラッシュしませんでした.

この問題の原因は何ですか? どうすれば修正できますか?Crashlytics から提供できる情報がさらにある場合は、その旨をお伝えください。

4

1 に答える 1

2

まず、最新バージョンを使用していることを確認してください。この問題は 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。明らかに、このデータはユーザーの認証トークンであるため、このデータを保存/送信する方法には注意してください。

さらに、これらのクラッシュが認証失敗エラーに変わるはずです。これは (おそらく) 優れています。

于 2014-01-28T16:13:02.947 に答える