iOS / Swift:PFFropicalUtils.logInWithPermissions返回零用户和错误
在我的应用程序中,我通过Parse的PFFVideosUtil类login用户。 如果用户在手机上存在(即在设置> Facebooklogin到FB),那么一切按预期工作。
但是,如果他们没有通过设置login ,那么用户将被带到Web视图来login。在用户放入他们的凭证之后,返回块应该接收用户或者错误,但是在这种情况下,用户和错误是零。
let permissionsArray = ["user_about_me", "email"]; PFFacebookUtils.logInWithPermissions(permissionsArray, block: { (user: PFUser!, error: NSError!) -> Void in if user != nil { //successful login } else if error != nil{ //unsuccessful login } else { //this is what I get } }
我们目前正在运行Parse 1.4.2
问题是我没有在AppDelegate调用中调用FBAppCall.handleOpenURL():
application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?)
当我从networking身份validation回来。 通过不调用FBAppCall.handleOpenURL(),Parse认为我们取消了我们的authentication。 parsing文档指出,“用户和错误都是零 – 如果用户通过切换回应用程序来取消身份validation”。
这个方法应该调用FBAppCall.handleOpenURL把authentication传回给应用程序。 在我的情况下,我也使用这个调用深度链接,我没有正确处理逻辑。 我原来是检查sourceApplication对象,看看它是不是“com.facebook.Facebook”。 如果它返回true,那么我调用FBAppCall.handleOpenURL()。 当我今天debugging它时,我注意到源应用程序实际上是“com.apple.mobilesafari”。 检查sourceApplication不是最好的办法来检查(尝试像url.host),但在这种情况下,这是问题。
这是固定的代码片段:
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) { if (url.host == DEEP_LINKING_HOST) { //Deep linking code here... } else if sourceApplication == "com.apple.mobilesafari" { return FBAppCall.handleOpenURL(url, sourceApplication: sourceApplication, withSession: PFFacebookUtils.session()) } }
这里的重点是我没有调用FBAppCall.handleOpenURL()。 因此,该应用程序认为我取消了login,给了我一个零用户和错误。
目前,我看不到您的代码的任何问题。 但我会检查空NSError
而不是PFUser
,只是从我的经验。
这里是我的解决scheme,我在我的应用程序中使用Facebookloginparsing,它在Objective-C完成,但我相信它会把你放在正确的轨道上…在你的代码中做出断点,并检查PFUser
和NSError
或日志PFUser
和NSError
。 也请前往Parse.com
并查看他们的Facebooklogin解决scheme。 有一个示例应用程序,但在Objective-C
。
[PFFacebookUtils logInWithPermissions:@[@"public_profile", @"email"] block:^(PFUser *user, NSError *error) { if (error) { [CBUtility facebookErrorHandler:error]; return; } else { if (![CBUtility userHasValidFacebookData:user]) { [FBRequestConnection startForMeWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) { if (error) { [CBUtility facebookErrorHandler:error]; return; } NSDictionary *user = (NSDictionary *)result; if (!user[@"email"]) { [[[UIAlertView alloc] initWithTitle:@"Facebook Login/Register Error" message:[NSString stringWithFormat:@"There is no email associated with the current facebook account. The Registration could not proceed! Either login to your facebook account and create one or create a new crossbook account in the Register view."] delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Dismiss", nil] show]; [[PFUser currentUser] delete]; return; } [PFUser currentUser][kCBUserFirstNameKey] = user[@"first_name"]; [PFUser currentUser][kCBUserLastNameKey] = user[@"last_name"]; [PFUser currentUser][kCBUserDisplayNameKey] = user[@"name"]; [[PFUser currentUser] setEmail:user[@"email"]]; [PFUser currentUser][kCBUserGenderKey] = [user[@"gender"] capitalizedString]; [PFUser currentUser][kCBUserFacebookIDKey] = user[@"id"]; if ([user[@"birthday"] length] != 0) { NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"MM/dd/yyyy"]; NSDate *date = [dateFormatter dateFromString:user[@"birthday"]]; NSDateFormatter *stringFormatter = [[NSDateFormatter alloc] init]; [stringFormatter setDateFormat:@"MMM dd, yyyy"]; [PFUser currentUser][kCBUserBirthdateKey] = [stringFormatter stringFromDate:date]; } [[PFUser currentUser] saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) { if ([error code] == 203) { [[[UIAlertView alloc] initWithTitle:@"Facebook Login/Register Error" message:[NSString stringWithFormat:@"Apparently, the email address %@ has already been taken. Login with the username and password that is associated with the email address %@ and link accounts to allow facebook login by going to settings and link facebook account. If you forgot the password for the account, press 'Forgot Password' and type in the email address.", user[@"email"], user[@"email"]] delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Dismiss", nil] show]; [[PFUser currentUser] delete]; return; } if (error) { [[[UIAlertView alloc] initWithTitle:@"Error" message:[error localizedDescription] delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Dismiss", nil] show]; [PFUser logOut]; return; } [[NSNotificationCenter defaultCenter] postNotificationName:CBLoginRegisterControllerUserDidFinishLoginNotification object:nil]; [self dismissViewControllerAnimated:YES completion:nil]; [(AppDelegate *)[[UIApplication sharedApplication] delegate] downloadFacebookPhoto]; return; }]; }]; return; } [[NSNotificationCenter defaultCenter] postNotificationName:CBLoginRegisterControllerUserDidFinishLoginNotification object:nil]; [self dismissViewControllerAnimated:YES completion:nil]; [(AppDelegate *)[[UIApplication sharedApplication] delegate] downloadFacebookPhoto]; return; } }];
我正在使用Facebook SDK的版本4.10.1
。 在这个版本中没有FBAppCall
类。 改用FBSDKApplicationDelegate
,并将这段代码粘贴到应用程序FBSDKApplicationDelegate
。
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { BOOL canOpen = [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:sourceApplication annotation:annotation]; return canOpen; }