0

嘗試在我的應用中登錄Facebook時,我遇到了一些奇怪的行爲。iOS Appcelerator Facebook登錄 - 登錄事件不會在設備上觸發

當前堆棧信息:

  1. Appcelerator的6.0.1.GA
  2. Appcelerator的CLI 6.1.0
  3. 的iOS 10.1
  4. XCODE 8.2.1

怪異的行爲:

  1. login從Facebook登錄設備返回時,事件永不會觸發。
  2. login從模擬器上的Facebook登錄返回時,事件有時不會觸發。
  3. 設置facebook.LOGIN_BEHAVIOR_NATIVE仍嘗試使用設備上的瀏覽器登錄,有時
  4. 有時在設備上,應用程序切換器會打開Facebook應用程序瀏覽器進行登錄。這很令人煩惱。

我實際上是模塊的setLoginBehavior功能的原始貢獻者,儘管自從「我們總是希望您使用瀏覽器」的貢獻以來,Facebook的立場似乎發生了變化。到「我們總是希望你使用Native。」。我在這裏發佈這個問題,以防某人有一些洞察力 - 當我等待答案時,我將回到該模塊的源代碼中。

我能想象的唯一因素可能與大多數應用程序不同,因爲我使用的是Kris Kowals Q。下面的代碼,幾乎逐字從我的應用程序。

實際的函數,它登錄:

// linkingmodule.js 
exports.linkFacebook = function() { 
    var Q = require('vendor/q'), 
     response = Q.defer(), 
     facebook = require('facebook'), 
     permissions = ['public_profile', 'user_friends', 'user_likes']; 

    facebook.initialize(); 
    facebook.setLoginBehavior(facebook.LOGIN_BEHAVIOR_NATIVE); 
    facebook.permissions = permissions; 

    facebook.addEventListener('login', function fireLogin(e) { 
     if(!e.success || !facebook.loggedIn) { 
      return response.reject({ 
       status: e.code, 
       error: e.error 
      }); 
     } 

     response.resolve({ 
      uid: e.uid, 
      data: e.data, 
      token: facebook.getAccessToken() 
     }); 
    }); 

    facebook.authorize(); 
    return response.promise; 
}; 

調用登錄功能的合金控制器功能:

// login.js 
function facebookLogin() { 
    var remote = require('linkingmodule'); 

    remote.linkFacebook(). 
    then(function(r) { 
      // do some things 
     }). 
     fail(function(e) { 
      console.error(e); 
      throw 'Unable to login with Facebook.'; 
     }); 
    }). 
    fail(function(e) { 
     console.error('Facebook login failed'); 
     console.error(e); 
    }); 
} 
+0

附加信息:在模擬器上,只有在清除內容和設置後才能登錄,然後重新構建應用程序。隨後重建應用程序將導致登錄無法啓動。 – threeve

回答

0

我在鈦模塊SDK粉筆這份長達一個bug,特別是Ti.fireEvent。我的調查以Facebook模塊結束,但模塊中的所有事件似乎都按預期發送和接收。只有當調用Ti.fireEvent時,「在某些情況下」JS應用程序沒有收到它。 facebook模塊中的block retain cycle的可能性仍然存在,但我無法解決它。

這裏是我的解決方法:

function facebookLogin() { 
    var Q = require('vendor/q'), 
     response = Q.defer(), 
     fb = require('facebook'), 
     permissions = ['public_profile', 'user_friends', 'user_likes']; 

    var checkLoginStatus, fireLogin; 

    checkLoginStatus = function(e) { 
     Ti.App.removeEventListener('resumed', checkLoginStatus); 
     fb.removeEventListener('login', fireLogin); 

     // login often doesn't fire, so let's check on resumed as well 
     if(fb.loggedIn) { 
      return response.resolve({ 
       uid: fb.uid, 
       data: null, 
       token: fb.getAccessToken() 
      }); 
     } 
     console.log('resumed and found that are NOT logged in'); 
     return response.reject({ 
      status: -1, 
      error: 'Did not work.' 
     }); 
    }; 
    fireLogin = function(e) { 
     fb.removeEventListener('login', fireLogin); 
     Ti.App.removeEventListener('resumed', checkLoginStatus); 
     if(!e.success || !fb.loggedIn) { 
      return response.reject({ 
       status: e.code, 
       error: e.error 
      }); 
     } 

     response.resolve({ 
      uid: e.uid, 
      data: e.data, 
      token:fb.getAccessToken() 
     }); 
    }; 

    Ti.App.addEventListener('resumed', checkLoginStatus); 
    fb.addEventListener('login', fireLogin); 

    fb.initialize(); 
    fb.setLoginBehavior(fb.LOGIN_BEHAVIOR_NATIVE); 
    fb.permissions = permissions; 
    fb.authorize(); 

    return response.promise; 
} 

所以,基本上保持監聽login事件 - 它在「某些情況下」正確地觸發。但也聽取App.resumed。無論首先發生什麼事,取消所有聽衆,並檢查登錄狀態。