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。无论首先发生什么事,取消所有听众,并检查登录状态。