尝试在我的应用中登录Facebook时,我遇到了一些奇怪的行为。
当前堆栈信息:
奇怪的行为:
login
事件从Facebook登录设备返回时不会触发。login
事件有时在模拟器上从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 :(得分: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
。无论哪个首先触发,取消所有侦听器,并检查登录状态。