iOS Appcelerator Facebook 登录 - 登录事件不会在设备上触发
iOS Appcelerator Facebook Login - Login Event Doesn't Fire on Device
尝试在我的应用程序中登录 Facebook 时,我遇到了一些奇怪的行为。
当前堆栈信息:
- Appcelerator 6.0.1.GA
- Appcelerator CLI 6.1.0
- iOS10.1
- xCode8.2.1
奇怪的行为:
login
从设备上的 Facebook 登录返回时,事件从不触发。
login
在模拟器上从 Facebook 登录返回时,事件有时不会触发。
- 设置 facebook.LOGIN_BEHAVIOR_NATIVE 仍会尝试在设备上使用浏览器登录,有时。
- 有时在设备上,应用切换器会打开 Facebook 应用 和 浏览器进行登录。挺烦人的。
我实际上是该模块 setLoginBehavior
功能的原始贡献者,尽管 Facebook 的立场似乎在贡献从 "We always want you to use browser." 到 "We always want you to use 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;
};
调用登录函数的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);
});
}
我已将其归因于 Titanium 模块 SDK 中的错误,特别是 Ti.fireEvent
。我的调查以 Facebook 模块结束,但模块内的所有事件似乎都按预期发送和接收。只是,当Ti.fireEvent
被调用时,在JS应用"under some circumstances"中没有收到。 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
事件 - 它在 "some circumstances" 下正确触发。但也要听 App.resumed
。以先触发者为准,取消所有侦听器,并检查登录状态。
尝试在我的应用程序中登录 Facebook 时,我遇到了一些奇怪的行为。
当前堆栈信息:
- Appcelerator 6.0.1.GA
- Appcelerator CLI 6.1.0
- iOS10.1
- xCode8.2.1
奇怪的行为:
login
从设备上的 Facebook 登录返回时,事件从不触发。login
在模拟器上从 Facebook 登录返回时,事件有时不会触发。- 设置 facebook.LOGIN_BEHAVIOR_NATIVE 仍会尝试在设备上使用浏览器登录,有时。
- 有时在设备上,应用切换器会打开 Facebook 应用 和 浏览器进行登录。挺烦人的。
我实际上是该模块 setLoginBehavior
功能的原始贡献者,尽管 Facebook 的立场似乎在贡献从 "We always want you to use browser." 到 "We always want you to use 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;
};
调用登录函数的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);
});
}
我已将其归因于 Titanium 模块 SDK 中的错误,特别是 Ti.fireEvent
。我的调查以 Facebook 模块结束,但模块内的所有事件似乎都按预期发送和接收。只是,当Ti.fireEvent
被调用时,在JS应用"under some circumstances"中没有收到。 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
事件 - 它在 "some circumstances" 下正确触发。但也要听 App.resumed
。以先触发者为准,取消所有侦听器,并检查登录状态。