简体   繁体   English

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

[英]iOS Appcelerator Facebook Login - Login Event Doesn't Fire on Device

When attempting to login to facebook in my app, I am experiencing a few strange behaviors. 尝试在我的应用程序中登录Facebook时,我遇到一些奇怪的行为。

Current stack information: 当前堆栈信息:

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

Strange Behaviors: 奇怪的行为:

  1. login event never fires when returning from Facebook login on device. 从设备上的Facebook登录返回时, login事件永远不会触发。
  2. login event sometimes doesn't fire when returning from Facebook login on simulator. 从模拟器上的Facebook登录返回时, login事件有时不会触发。
  3. Setting facebook.LOGIN_BEHAVIOR_NATIVE still attempts to use browser login on device, sometimes . 设置facebook.LOGIN_BEHAVIOR_NATIVE 有时仍尝试在设备上使用浏览器登录。
  4. Sometimes on device, the app-switcher opens the Facebook app and the browser for login. 有时在设备上,应用程序切换器会打开Facebook应用程序浏览器进行登录。 This is quite vexing. 这真是令人讨厌。

I'm actually the original contributor of the setLoginBehavior functionality of the module, though Facebook's stance seems to have changed since that contribution from "We always want you to use browser." 我实际上是该模块的setLoginBehavior功能的原始贡献者,尽管自“我们一直希望您使用浏览器”的贡献以来,Facebook的立场似乎已经改变。 to "We always want you to use Native.". “我们一直希望您使用本机”。 I'm posting this question here in case someone has some insight - while I wait for an answer I will be back into the source for that module. 如果有人有所了解,我将在此处发布此问题-在等待答案的同时,我将返回该模块的源代码。

The only factor that I can imagine might be different from most apps is that I am using Kris Kowals Q . 我可以想象的唯一可能与大多数应用程序不同的因素是我使用的是Kris Kowals Q。 Here follows the code, almost verbatim from my app. 下面是代码,几乎完全来自我的应用程序。

The actual function that does the login: 进行登录的实际功能:

// 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;
};

The alloy controller function that calls the login function: 调用登录功能的Alloy控制器功能:

// 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);
    });
}

I have chalked this up to a bug in the Titanium module SDK, specifically Ti.fireEvent . 我将其Ti.fireEvent于Titanium模块SDK中的一个错误,特别是Ti.fireEvent My investigation ended with the Facebook Module, but all events within the module appeared to be sent and received as expected. 我的调查以Facebook模块结束,但是该模块中的所有事件似乎都已按预期发送和接收。 Only, when Ti.fireEvent was called, it was not received in the JS app "under some circumstances". 仅在Ti.fireEvent时,“在某些情况下”未在JS应用程序中接收到它。 The possibility remains of a block retain cycle within the facebook module, but I was not able to solve it. 在facebook模块内仍然存在一个块保留周期的可能性,但是我无法解决。

Here is my workaround: 这是我的解决方法:

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;
}

So, basically keep listening for the login event - it fires correctly under "some circumstances". 因此,基本上,继续监听login事件-在“某些情况下”它会正确触发。 But also listen for App.resumed . 而且还要听App.resumed Whichever fires first, cancel all listeners, and check for logged in status. 以先触发者为准,取消所有侦听器,然后检查登录状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM