FBSDKLoginManager logInWithPublishPermissions总是返回isCancelled = YES
我无法弄清楚如何将用户login到我的应用程序。 [FBSDKAccessToken currentAccessToken]
是零,所以我打电话:
[[[FBSDKLoginManager alloc] init] logInWithPublishPermissions:@[@"publish_actions"] handler:…];
根据所包含的示例项目。 这切换到Facebook应用程序,但消息说:“您已经授权应用程序名称 ”。 我点击确定,然后回到应用程序,但grantedPermissions
和被declinedPermissions
grantedPermissions
都nil
,结果是isCancelled
为YES
。 [FBSDKAccessToken currentAccessToken]
仍然是nil
。
我无法弄清楚我应该如何获得currentAccessToken
来填充。在我看来,调用logInWithPublishPermissions
应该这样做,但事实并非如此。
你应该尝试添加你的AppDelegate didFinishLaunchingWithOptions:
return [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
当用户login时,这会得到u [FBSDKAccessToken currentAccessToken]
。
和
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { return [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:sourceApplication annotation:annotation]; }
如果此方法不在AppDelegate中,则会导致取消状态。
请参阅: https : //developers.facebook.com/docs/ios/getting-started#startcoding
当您的Facebook应用程序没有“publish_actions”权限,或者您没有使用testing用户时,可能会发生这种情况。
在Facebook上,去pipe理你的应用程序,然后确保你使用的Facebook用户是作为pipe理员或testing人员在“angular色”下定义的。
如果它不是testing用户或pipe理员 – Facebook会要求“publish_actions”权限在允许您的应用程序使用之前进行审查和批准,否则您将收到“isCancelled = YES”的结果。
在使用此权限testing您的应用程序之后,可以提交此权限以进行审查,您需要上传一个演示如何使用此权限的二进制文件,以及如何使用此权限的详细信息。 获得批准后,您可以将其用于未经testing的Facebook用户。
由于FBSDKLoginKit 4.6.0, logInWithReadPermissions
和logInWithPublishPermissions
方法似乎有附加的fromViewController
参数,并使用它来呈现模态。
我在logInWithPublishPermissions
的callback里面调用了logInWithReadPermissions
,在那个时候模态还没有完全解决 。 (我知道在不需要的时候询问权限是个不好的习惯,但在我的情况下,这似乎是正确的地方。)这导致它失败, isCancelled
等于YES。 我添加了一些延迟,等待模式被完全解散,解决了这个问题。
当我在这里登陆时遇到了同样的问题,事实certificate我只是使用了不推荐的应用程序openURL方法,因为我也使用了谷歌login。 要支持iOS 8,并且必须实现当前和不推荐使用的方法:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool { return GIDSignIn.sharedInstance().handle(url, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String!, annotation: options[UIApplicationOpenURLOptionsKey.annotation]) || FBSDKApplicationDelegate.sharedInstance().application(app, open: url, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String, annotation: options[UIApplicationOpenURLOptionsKey.annotation]) } func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool { return GIDSignIn.sharedInstance().handle(url, sourceApplication: sourceApplication, annotation: annotation) || FBSDKApplicationDelegate.sharedInstance().application(application, open: url, sourceApplication: sourceApplication, annotation: annotation) }
弃用的是第二个。
注意:FBSDK方法是在google之后添加一个“||” 操作员,但顺序并不重要,如果你只想使用Facebook方法只是删除方法和或运营商。
注2:由于swift 3仍然稳定的方法名称可以改变我build议你在覆盖和实现一个委托的方法时总是使用从XCode自动完成。
希望这有助于o /
此方法适用于iOS 9
// Facebook Login Completion delegate - (void)loginButton:(FBSDKLoginButton *)loginButton didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error { if (result){ NSLog(@"%@",result); NSLog(@"%@",result.grantedPermissions); [self getFacebookData:result]; } } - (void)getFacebookData:(FBSDKLoginManagerLoginResult *)result{ if (![result.grantedPermissions containsObject:@"email"]) { FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init]; login.loginBehavior = FBSDKLoginBehaviorWeb; [login logInWithReadPermissions:@[@"email"] fromViewController:self handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { if (error) { // Process error } else if (result.isCancelled) { // Handle cancellations } else { if ([result.grantedPermissions containsObject:@"email"]) { NSLog(@"result is:%@",result); if ([FBSDKAccessToken currentAccessToken]) { [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields": @"first_name, last_name, email, id"}] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (!error) { NSLog(@"fetched user:%@", result); [self registerWithFacebook:result]; }else{ NSLog(@"%@",error); } }]; } } } }]; }else{ if ([FBSDKAccessToken currentAccessToken]) { [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields": @"first_name, last_name, email, id"}] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (!error) { NSLog(@"fetched user:%@", result); [self registerWithFacebook:result]; }else{ NSLog(@"%@",error); } }]; } }
}
注意 :使用FBSDKLoginBehaviorWeb而不是FBSDKLoginBehaviorBrowser 。 这一定会奏效
另外,请确保您没有在您的didFinishLaunchingWithOptions
方法中调用FBSDKAccessToken.currentAccessToken
。 didFinishLaunchingWithOptions
的设置需要完成,因此令牌可以在尝试loginFacebook之前进行初始化。
FBSDKLoginManagerLoginResult.isCancelled
意外YES
:
如果用户明确点击login对话框中的取消button,或者手动应用程序切换回您的应用程序(称为隐式取消),SDK将报告取消。 你应该确保你没有启动一个loginstream作为你的应用程序delegate
的生命周期的一部分(例如在application:openURL:sourceApplication:annotation:
启动一个loginapplication:openURL:sourceApplication:annotation:
因为这将模仿一个隐式的取消。 如果必须,稍后将login启动分派给主队列,以便应用程序委托的生命周期首先完成。
我也面临同样的问题,我花了近2个小时来解决这个问题。 我做的是
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init]; **[login logOut];** // adding this single line fixed my issue [login logInWithReadPermissions: @[@"public_profile"] fromViewController:self handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { if (error) { NSLog(@"Process error"); } else if (result.isCancelled) { NSLog(@"Cancelled"); } else { NSLog(@"Logged in"); [self GetData]; } }] // I called this logout function
问题解决了
我使用谷歌和Facebooklogin,所以我不得不实施我的openURL方法,像这样,iOS 9 +
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options { if ([[url absoluteString] containsString:@"YOURFBID"]) { return [[FBSDKApplicationDelegate sharedInstance] application:app openURL:url options:options]; } else { return [[GIDSignIn sharedInstance] handleURL:url sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]; } return NO; }
//您可以使用访问令牌进一步执行任何操作
- (void)GetData { if ([FBSDKAccessToken currentAccessToken]) { NSDictionary *AccessToken = [FBSDKAccessToken currentAccessToken]; [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields": @"id, name, first_name, picture.type(large) ,last_name"}] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (!error) { //NSLog(@"fetched user:%@", result); //NSDictionary *Result = result; NSDictionary *params = [NSMutableDictionary dictionaryWithObject:[AccessToken tokenString] forKey:@"access_token"]; } else { [self showAlertController:@"Error" message:error.localizedDescription]; } }]; } }
(BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options { return [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url options:options]; } // **Still need this for iOS8** - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(nonnull id)annotation { return [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:sourceApplication annotation:annotation]; }
称这个方法,
FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init]; [loginManager logInWithReadPermissions:@[@"user_friends"] handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { code }];