2015-06-04 35 views
1

我一直在嘗試使用Parse(版本1.7.4)登錄並使用Facebook的SDK(版本4.1)註冊用戶,但每次我嘗試註冊時,下面的代碼都會打印出「用戶取消的FB登錄」,這意味着用戶被返回爲零,但沒有錯誤。我不知道這是一個解析問題還是一個Facebook問題,但如果任何人有任何想法如何解決這個問題,我將非常感激。解析和Facebook登錄和註冊返回「用戶已取消登錄」(iOS 8.1 + Swift 1.2)

這是我登錄的代碼/註冊視圖控制器:

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代碼(與編輯了當然的解析鍵):

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) 

} 

而且這裏是我的框架截圖:

Frameworks as seen on side bar

Frameworks as seen on Link Binaries section

我再次檢查了我的info.plist並確保我的包標識符位於我的Facebook應用設置中,而我的Facebook信息位於我的Parse應用設置中。我嘗試製作一個全新的Parse和Facebook應用程序,問題依然存在。我記得幾個月前分別測試了Facebook登錄和解析用戶註冊,並創建了一個用戶並將該帳戶鏈接到了該應用,但是在實現PFFacebokUtils並刪除舊用戶後,登錄似乎繼續聲明用戶「已取消FB登錄。」應用程序可以保存或緩存舊用戶或一些我不知道這阻止了其他登錄或註冊的Facebook令牌嗎?我嘗試使用PFUser.logOut()並打印信息以確認我的應用程序中沒有現有用戶,但仍表示用戶取消了登錄。將使用accessToken修復事情?我的Facebook應用程序批准會改變什麼?如果有人知道任何這些問題的答案,或者有以前的答案或評論中沒有提出的想法,請告訴我。非常感謝你的幫助。

+0

是什麼讓你認爲這個問題是在請求的Facebook()或returnUserData()?您是否看到「用戶註冊並使用Facebook登錄!」在控制檯中?如果沒有,那麼代碼永遠不會到達這段代碼。不幸的是,我看不到你的代碼中的錯誤,儘管我建議你儘量減少它以幫助診斷問題。事實上,我建議你臨時剪切除權限外的所有內容,並將Parse建議的代碼粘貼到你的項目中,以檢查它是否有效。 https://parse.com/docs/ios/guide#users-log-in-amp-sign-up –

+0

@CraigGrummitt感謝您如此樂於助人,並如此迅速地回覆!我只是嘗試了你的建議,並複製了你發給我的Parse鏈接中的代碼,而我的所有控制檯都說「呃,用戶取消了Facebook登錄。」所以你是對的,問題不在於請求Facebook()或returnUserData()。現在我不太確定該怎麼做。我的AppDelegate中可能存在訪問令牌問題或可能有問題?如果沒有其他解決方案,我可以嘗試製作一個新的應用程序來解析並鏈接我的項目,然後看看問題是否仍然存在 – Armin

+0

我懷疑如果Parse教程中的通用代碼無法正常工作,那麼您缺少一個框架,或者你的AppDelegate didFinishLaunchingWithOptions方法有問題。在此方法中,您是否運行Parse.setApplicationId和PFFropicalUtils.initializeFacebookWithApplicationLaunchOptions,並且您是否返回FBSDKApplicationDelegate.sharedInstance()。應用程序? –

回答

1

好吧,經過幾個月的沮喪,我終於解決了這個問題!而且這非常簡單。我決定創建一個專門用於測試PFFVideosUtils登錄的新Xcode項目,以查看是否可以創建一個沒有此問題的登錄系統。果然,在仔細地遵循Parse的Facebook登錄指南(https://parse.com/docs/ios/guide#users-facebook-users)之後,我成功通過PFFVideosUtils登錄,而且在測試應用中沒有任何問題!事實證明,我的所有框架設置都正確,但是在我的應用程序中導致取消登錄問題的某些關鍵功能中存在不必要的代碼和稍微不同的語法組合。我將把我的PFFVideosUtils測試項目中的所有代碼放在下面,這樣任何面臨相同問題的人都可以編輯它們的代碼來匹配它。如果這不起作用,我會建議你自己嘗試一下,看看它們有什麼不同。

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

Objective-C橋接頭:

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

希望這可以幫助任何面對此問題的人!

0

我有2項建議在這種情況下:)

1)PFUser.enableRevocableSessionInBackground(創建新的有效 會話並嘗試再次

2-)在模擬器中刪除應用程序,有時會造成 無效會話問題

+0

我只是試過這種方法,它沒有任何區別,它仍然說:「呃哦,用戶取消了Facebook登錄。」我認爲問題出在請求的Facebook()funciton或returnUserData()函數 – Armin

+0

我編輯我的答案我似乎你需要獲得登錄權限 –

+0

在我的代碼的最頂部你可以看到我已經創建了權限數組 – Armin

0

BSession openActiveSessionWithReadPermissions:@ [@「email」,@「us er_location」,@ 「user_birthday」,@ 「user_hometown」,@ 「user_friends」] allowLoginUI:YES completionHandler:^(FBSession *會話,FBSessionState狀態,NSError *錯誤){

switch (state) { 
     case FBSessionStateOpen:{ 


      NSString *link=[NSString stringWithFormat:@"https://www.apple.com"]; 



      NSString *str_img = [NSString stringWithFormat:@"http://get-groupy.com/images/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; 
    } 

}];

+0

您能否重新格式化此答案,以便它在Swift(而不是Objective-C)中,並且還提供了更多的上下文? – Armin