Mine是Objective-C中的iOS应用程序,并集成了Facebook SDK用于登录功能。
我有一个主视图控制器,我显示我的按钮。在按钮上单击下面提到的代码在按钮处理程序上执行。
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login
logInWithReadPermissions: @[@"public_profile", @"email"]
fromViewController:self
handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if (error) {
NSLog(@"Process error %@",error.description);
}
else if (result.isCancelled) {
NSLog(@"Cancelled");
}
else {
if ([result.grantedPermissions containsObject:kEmail]) {
[self fetchfbUserInfo];
}
else {
NSLog(@"User Declined permissions");
}
}
}];
当Facebook的登录页面显示在我们应用程序的webview中时,如果facebook登录页面保持原样/无人值守一段时间,则会间歇性关闭,并在控制台中显示以下错误。
FBSDKLog:错误:SFSafariViewController的父视图 控制员被解雇了。如果您正在触发登录,则会发生这种情况 来自UIAlertController。相反,请确保您的最顶层视图 控制器不会过早被解雇。
进行了一些逆向工程并发现必须为错误消息调用 FBSDKApplicationDelegate类的委托方法。
- (void)viewControllerDidDisappear:(FBSDKContainerViewController *)viewController animated:(BOOL)animated
{
if (_safariViewController) {
[FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors
logEntry:@"**ERROR**:\n The SFSafariViewController's parent view controller was dismissed.\n"
"This can happen if you are triggering login from a UIAlertController. Instead, make sure your top most view "
"controller will not be prematurely dismissed."];
[self safariViewControllerDidFinish:_safariViewController];
}
}
登录页面(或登录后的应用程序授权页面)为何会关闭/解散其自身的任何可能原因?
答案 0 :(得分:2)
自iOS 9以来,FB iOS SDK中的默认行为是使用移动版Safari对用户进行身份验证(而不是本机iOS FB应用程序)。当用户尝试使用Facebook登录您的应用程序但从未在移动版Safari(无cookie)中登录Facebook时,Safari会加载一个页面,其中提供用户“使用Facebook应用程序登录”。点击该按钮会将用户带到FB本机应用程序,这会导致Safari页面被解除(并且您的应用程序将移至后台)。实际上取消登录流程,并使用FBSDKLoginManagerLoginResult
返回isCancelled == true
块。
当用户接受本机FB应用中的权限并返回到您的应用时,将使用application:openURL:options:
url(包含访问令牌)调用fb<your-fb-app-id>://
。根据FB SDK登录指南,此URL应传递给:
[[FBSDKApplicationDelegate sharedInstance] application:application openURL:url options:options];
但是FBSDKApplicationDelegate
只是忽略了网址并返回NO
,因为登录流程事先被“取消”了。
对我来说,这看起来像是FB SDK中的一个严重错误。
我发现此问题的唯一解决方法是:
- (BOOL) application:(UIApplication*)application openURL:(nonnull NSURL *)url options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
BOOL handled = [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url options:options];
if (!handled) {
NSMutableDictionary *launchOptions = [NSMutableDictionary new];
launchOptions[UIApplicationLaunchOptionsSourceApplicationKey] = options[UIApplicationOpenURLOptionsSourceApplicationKey];
launchOptions[UIApplicationLaunchOptionsAnnotationKey] = options[UIApplicationOpenURLOptionsAnnotationKey];
launchOptions[UIApplicationLaunchOptionsURLKey] = url;
return [[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
}
return handled;
}
以上实际上将访问令牌存储在FB SDK中。
为了继续您的登录流程,您可以观察FBSDKAccessTokenDidChange
通知,该通知将在处理上面的FB网址后调用。