iOS Appcelerator Facebook登录 - 登录事件不会在设备上触发

时间:2016-12-23 15:57:55

标签: ios facebook appcelerator appcelerator-mobile appcelerator-facebook

尝试在我的应用中登录Facebook时,我遇到了一些奇怪的行为。

当前堆栈信息:

  1. Appcelerator 6.0.1.GA
  2. Appcelerator CLI 6.1.0
  3. iOS 10.1
  4. xCode 8.2.1
  5. 奇怪的行为:

    1. login事件从Facebook登录设备返回时不会触发。
    2. login事件有时在模拟器上从Facebook登录返回时无法触发。
    3. 设置facebook.LOGIN_BEHAVIOR_NATIVE仍尝试在设备上使用浏览器登录,有时
    4. 有时在设备上,应用切换器会打开Facebook应用浏览器进行登录。这非常令人烦恼。
    5. 我实际上是该模块的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);
          });
      }
      

1 个答案:

答案 0 :(得分:0)

我已将此归结为Titanium模块SDK中的一个错误,特别是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。无论哪个首先触发,取消所有侦听器,并检查登录状态。