項(xiàng)目常見崩潰10(陸續(xù)更新)

做國(guó)際化的app, facebook登錄是一定少不了的, 今天介紹一種facebook登錄引起的崩潰.

先看堆棧

Thread 0 (crashed)
 0  libobjc.A.dylib!objc_msgSend + 0x1c
    Found by: given as instruction pointer in context
 1  SafariServices!__75-[SFAuthenticationViewController dismissViewControllerAnimated:completion:]_block_invoke + 0x1c
    Found by: previous frame's frame pointer
 2  UIKit!-[UIPresentationController transitionDidFinish:] + 0x524
    Found by: previous frame's frame pointer
 3  UIKit!-[_UICurrentContextPresentationController transitionDidFinish:] + 0x28
    Found by: previous frame's frame pointer
 4  UIKit!__56-[UIPresentationController runTransitionForCurrentState]_block_invoke_2 + 0xb8
    Found by: previous frame's frame pointer
 5  UIKit!-[_UIViewControllerTransitionContext completeTransition:] + 0x70
    Found by: previous frame's frame pointer
 6  UIKit!-[UITransitionView notifyDidCompleteTransition:] + 0xf8
    Found by: previous frame's frame pointer
 7  UIKit!-[UITransitionView _didCompleteTransition:] + 0x464
    Found by: previous frame's frame pointer
 8  UIKit!-[UITransitionView _transitionDidStop:finished:] + 0x74
    Found by: previous frame's frame pointer
 9  UIKit!-[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 0x134
    Found by: previous frame's frame pointer
10  UIKit!-[UIViewAnimationState animationDidStop:finished:] + 0x124
    Found by: previous frame's frame pointer
11  UIKit!-[UIViewAnimationState animationDidStop:finished:] + 0x1c4
    Found by: previous frame's frame pointer
12  QuartzCore!CA::Layer::run_animation_callbacks(void*) + 0x118
    Found by: previous frame's frame pointer
13  libdispatch.dylib!_dispatch_client_callout + 0xc
    Found by: previous frame's frame pointer
14  libdispatch.dylib!_dispatch_main_queue_callback_4CF$VARIANT$mp + 0x3f4
    Found by: previous frame's frame pointer
15  CoreFoundation!__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 0x8
    Found by: previous frame's frame pointer
16  CoreFoundation!__CFRunLoopRun + 0x7d8
    Found by: previous frame's frame pointer
17  CoreFoundation!CFRunLoopRunSpecific + 0x1b0
    Found by: previous frame's frame pointer
18  GraphicsServices!GSEventRunModal + 0x60
    Found by: previous frame's frame pointer
19  UIKit!UIApplicationMain + 0xcc
    Found by: previous frame's frame pointer
20  Hago!main [main.mm : 18 + 0x10]
    Found by: previous frame's frame pointer
21  libdyld.dylib + 0x1568
    Found by: previous frame's frame pointer

WTF, SFAuthenticationViewController? 好像不是我們的代碼哦, 這個(gè)實(shí)際上是系統(tǒng)的一個(gè)VC, 在我們點(diǎn)擊facebook登錄前, 會(huì)引導(dǎo)我們?nèi)サ揭粋€(gè)facebook授權(quán)頁面, 這個(gè)頁面就是SFAuthenticationViewController類型的, 在測(cè)試中確實(shí)很難模擬出這種情況, 因?yàn)辄c(diǎn)擊一次登錄后就會(huì)彈出彈窗, 要我們確認(rèn), 這時(shí)候按道理是沒機(jī)會(huì)再次點(diǎn)擊facebook登錄的, 但是如果用戶的手機(jī)比較卡, 連續(xù)點(diǎn)了兩次, 但是第二次沒傳遞到按鈕時(shí)候, 用戶已經(jīng)迫不及待的同意授權(quán), 并喚出SFAuthenticationViewController這時(shí)候第二次點(diǎn)擊傳遞到了按鈕, 觸發(fā)了再次彈窗, 這時(shí)候再次點(diǎn)擊確認(rèn)就崩潰了.

分析: 我們程序在自動(dòng)登錄的時(shí)候, 如果發(fā)現(xiàn)facebook不能自動(dòng)登錄(token過期, 概率很小)也會(huì)觸發(fā)彈出彈窗, 但這之前用戶如果也點(diǎn)擊了facebook登錄, 并且點(diǎn)擊彈窗的繼續(xù), 并且來到SFAuthenticationViewController頁面才觸發(fā)自動(dòng)登錄失敗的彈窗, 這時(shí)候再次點(diǎn)擊彈窗就崩潰了.

代碼重現(xiàn)崩潰

- (void)tp_login:(PKTpLoginCallback)callback timeout:(TimeOutHandler)timeout
{
    [self fbNewLogin:callback timeout:timeout];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self fbNewLogin:callback timeout:timeout];
    });
}

在3秒內(nèi), 下次彈窗彈出前, 觸發(fā)彈窗, 并點(diǎn)擊繼續(xù), 來到SFAuthenticationViewController頁面. 3秒到, 再次彈窗, 點(diǎn)擊, 崩潰~

還有以下幾種堆棧也是類似的問題

Thread 0 (crashed)
 0  libobjc.A.dylib!objc_object::release() + 0x10
    Found by: given as instruction pointer in context
 1  SafariServices!__75-[SFAuthenticationViewController dismissViewControllerAnimated:completion:]_block_invoke + 0x1c
    Found by: previous frame's frame pointer
 2  SafariServices!__75-[SFAuthenticationViewController dismissViewControllerAnimated:completion:]_block_invoke + 0x1c
    Found by: previous frame's frame pointer
 3  UIKit!-[UIPresentationController transitionDidFinish:] + 0x524
    Found by: previous frame's frame pointer
 4  UIKit!-[_UICurrentContextPresentationController transitionDidFinish:] + 0x24
    Found by: previous frame's frame pointer
 5  UIKit!__56-[UIPresentationController runTransitionForCurrentState]_block_invoke.436 + 0xb8
    Found by: previous frame's frame pointer
 6  UIKit!-[_UIViewControllerTransitionContext completeTransition:] + 0x70
    Found by: previous frame's frame pointer
 7  UIKit!-[UITransitionView notifyDidCompleteTransition:] + 0xf8
    Found by: previous frame's frame pointer
 8  UIKit!-[UITransitionView _didCompleteTransition:] + 0x468
    Found by: previous frame's frame pointer
 9  UIKit!-[UITransitionView _transitionDidStop:finished:] + 0x74
    Found by: previous frame's frame pointer
10  UIKit!-[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 0x134
    Found by: previous frame's frame pointer
11  UIKit!-[UIViewAnimationState animationDidStop:finished:] + 0x124
    Found by: previous frame's frame pointer
12  UIKit!-[UIViewAnimationState animationDidStop:finished:] + 0x1c4
    Found by: previous frame's frame pointer
13  QuartzCore!CA::Layer::run_animation_callbacks(void*) + 0x118
    Found by: previous frame's frame pointer
14  libdispatch.dylib!_dispatch_client_callout + 0xc
    Found by: previous frame's frame pointer
15  libdispatch.dylib!_dispatch_main_queue_callback_4CF$VARIANT$mp + 0x3f0
    Found by: previous frame's frame pointer
16  CoreFoundation!__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 0x8
    Found by: previous frame's frame pointer
17  CoreFoundation!__CFRunLoopRun + 0x8dc
    Found by: previous frame's frame pointer
18  CoreFoundation!CFRunLoopRunSpecific + 0x224
    Found by: previous frame's frame pointer
19  GraphicsServices!GSEventRunModal + 0x60
    Found by: previous frame's frame pointer
20  UIKit!UIApplicationMain + 0xe8
    Found by: previous frame's frame pointer
21  Hago!main [main.mm : 18 + 0x10]
    Found by: previous frame's frame pointer
22  libdyld.dylib!start + 0x0
    Found by: previous frame's frame pointer

問題出現(xiàn)在這段代碼

FBSDKApplicationDelegate.m
if (@available(iOS 11.0, *)) {
    if ([sender isAuthenticationURL:url]) {
      Class SFAuthenticationSessionClass = fbsdkdfl_SFAuthenticationSessionClass();
      if (SFAuthenticationSessionClass != nil) {
          WEAKIFYSELF
        _authenticationSession = [[SFAuthenticationSessionClass alloc] initWithURL:url callbackURLScheme:[FBSDKInternalUtility appURLScheme] completionHandler:^ (NSURL *aURL, NSError *error) {
          handler(error == nil, error);
            STRONGIFYSELF
          if (error == nil) {
            [self application:[UIApplication sharedApplication] openURL:aURL sourceApplication:@"com.apple" annotation:nil];
          }
          self.authenticationSession = nil;
        }];
        [self.authenticationSession start];
        return;
      }
    }
  }

這里發(fā)現(xiàn)是iOS11系統(tǒng)先來一段裝B的代碼, 就是這段代碼造成了后續(xù)的崩潰. 這里我的解決辦法就是注釋掉這段裝B的代碼, 直接走后面的邏輯. 當(dāng)然, 還是要直面問題.

stackoverflow已經(jīng)給出了解決辦法.

- (void)tp_login:(PKTpLoginCallback)callback timeout:(TimeOutHandler)timeout
{
    UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
    while (topController.presentedViewController) {
        topController = topController.presentedViewController;
    }
    
    if (![topController isKindOfClass:NSClassFromString(@"SFSafariViewController")])
    {
        [self fbNewLogin:callback timeout:timeout];
    }
}
- (void)fbNewLogin:(PKTpLoginCallback)callback
           timeout:(TimeOutHandler)timeout
{
    [_fbLoginMgr logOut];
    _fbLoginMgr.loginBehavior = FBSDKLoginBehaviorBrowser;
    [_fbLoginMgr logInWithReadPermissions:@[ @"public_profile", @"email", @"user_friends", @"user_birthday", @"user_gender" ] fromViewController:nil handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
        MFLogInfo(LogTag, @"facebook login result.grantedPermissions = %@, error = %@", result.grantedPermissions, error);
        if (error) {
            safetyCallblock(callback, kPKLoginResultTpAuthFailed, error.description, nil);
            MFLogError(LogTag, @"Process error");
        } else if (result.isCancelled) {
            safetyCallblock(callback, kPKLoginResultTpLoginCancel, nil, nil);
            MFLogInfo(LogTag, @"Cancelled");
        } else {
            if (result.token.userID.length > 0) {
                [[NSNotificationCenter defaultCenter] postNotificationName:kPKFbAuthSuccessNotification object:nil userInfo:@{kPKFbAuthInfoKey : result.token.userID}];
            }

            HGTpAuthRes *authInfo = [[HGTpAuthRes alloc] init];
            authInfo.accessToken = result.token.tokenString;
            authInfo.openId = result.token.userID;
            authInfo.tpLoginType = kPKTpLoginTypeFacebook;

            //https://developers.facebook.com/docs/graph-api/reference/user  接口文檔

            NSDictionary *parameters = @{ @"fields" : @"id,name,gender,birthday,picture.width(1080).height(1080)" };
            [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:parameters] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
                if (!error && [result isKindOfClass:[NSDictionary class]]) {
                    MFLogInfo(LogTag, @"third parth get userinfo succ");
                    authInfo.tpUserInfo = [self parseUserInfo:result];
                }

                safetyCallblock(callback, kPKLoginResultOk, nil, authInfo);
            }];

            MFLogInfo(LogTag, @"third parth log in succ");
        }
    }];
}

這里在每次調(diào)用前都判斷下當(dāng)前present的vc是否是SFSafariViewController的子類, 這樣就沒問題了, 等待上線看效果.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末壳猜,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子坠狡,更是在濱河造成了極大的恐慌淹遵,老刑警劉巖口猜,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異透揣,居然都是意外死亡济炎,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門淌实,熙熙樓的掌柜王于貴愁眉苦臉地迎上來冻辩,“玉大人,你說我怎么就攤上這事拆祈『奚粒” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵放坏,是天一觀的道長(zhǎng)咙咽。 經(jīng)常有香客問我,道長(zhǎng)淤年,這世上最難降的妖魔是什么钧敞? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮麸粮,結(jié)果婚禮上溉苛,老公的妹妹穿的比我還像新娘。我一直安慰自己弄诲,他們只是感情好愚战,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著齐遵,像睡著了一般寂玲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上梗摇,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天拓哟,我揣著相機(jī)與錄音,去河邊找鬼伶授。 笑死断序,一個(gè)胖子當(dāng)著我的面吹牛流纹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播违诗,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼捧颅,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了较雕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤挚币,失蹤者是張志新(化名)和其女友劉穎亮蒋,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體妆毕,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡慎玖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了笛粘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片趁怔。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖薪前,靈堂內(nèi)的尸體忽然破棺而出润努,到底是詐尸還是另有隱情,我是刑警寧澤示括,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布铺浇,位于F島的核電站,受9級(jí)特大地震影響垛膝,放射性物質(zhì)發(fā)生泄漏鳍侣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一吼拥、第九天 我趴在偏房一處隱蔽的房頂上張望倚聚。 院中可真熱鬧,春花似錦凿可、人聲如沸惑折。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽唬复。三九已至,卻和暖如春全肮,著一層夾襖步出監(jiān)牢的瞬間敞咧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工辜腺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留休建,地道東北人乍恐。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像测砂,于是被迫代替她去往敵國(guó)和親茵烈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1砌些、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽明先生_x閱讀 15,968評(píng)論 3 119
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)呜投、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,029評(píng)論 4 62
  • 《成為沃倫·巴菲特》Becoming Warren Buffett是一部由彼得·W·孔哈特 / 布瑞恩·奧克斯...
    Mr玉民閱讀 1,113評(píng)論 0 0
  • 晚上下班回到家存璃,已經(jīng)快8點(diǎn)仑荐,因?yàn)橄挛鐩]有去學(xué)校,所以書包是孩子他爸后面拿回來的纵东。無奈他覺得自己太累粘招,希望晚點(diǎn)...
    JessieMM閱讀 147評(píng)論 0 1
  • 昨天偶然在網(wǎng)上查了gopro洒扎,第一次聽說,第一次了解衰絮,感覺很不錯(cuò)袍冷。經(jīng)過深入的分析,發(fā)現(xiàn)gopro主要適用于極限運(yùn)動(dòng)...
    做一個(gè)有特色的民工閱讀 630評(píng)論 0 0