2014-09-18 70 views
7

我一直在努力在swift中创建一个Facebook登录/注册函数。我一直在寻找一个教程,但一直没能找到任何东西。所以我一直在努力自己做。它似乎工作,但为什么它不保存我的facebookName,性别和图像在数据库中?它将它保存在模拟器中,但不是当我使用我的ios 8设备时?facebook解析注册swift

我收到此日志消息“用户注册并通过Facebook登录!”,一个新的用户添加到解析类,而不是姓名,形象和性别......

@IBAction func login(sender: UIButton!) { 




    var permissionArray = ["user_about_me", "user_relationships", "user_birthday", "user_location"] 

    PFFacebookUtils.initializeFacebook() 

    PFFacebookUtils.logInWithPermissions(permissionArray, block: { (user: PFUser!, error: NSError!) in 
     println(user) 
     if user == nil { 
      println(error.localizedDescription) 


     } else { 



      if user.isNew { 



       var userQuery = PFUser.query() 
       userQuery.getObjectInBackgroundWithId(PFUser.currentUser().objectId) { 
        (userObject: PFObject!, error: NSError!) -> Void in 


        var fbRequest = FBRequest.requestForMe() 
        fbRequest.startWithCompletionHandler { (connection: FBRequestConnection!, result:AnyObject!, error: NSError!) in 


         if error == nil { 

          //FACEBOOK DATA IN DICTIONARY 
          var userData = result as NSDictionary 
          var faceBookId = userData.objectForKey("id") as NSString 
          var faceBookName = userData.objectForKey("first_name") as NSString 
          var faceBookMiddle = userData.objectForKey("middle_name") as NSString 
          var faceBookGender = userData.objectForKey("gender") as NSString 

          var url:NSURL = NSURL.URLWithString(NSString(format:"https://graph.facebook.com/%@/picture?width=320", faceBookId)) 
          var err: NSError? 
          var imageData :NSData = NSData.dataWithContentsOfURL(url, options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &err) 

          var imageFile = PFFile(name: "image.jpg", data: imageData) as PFFile 

          println(userData) 

          userObject.setObject(faceBookName, forKey: "name") 
          userObject.setObject(imageFile, forKey: "file") 
          userObject.setObject(faceBookGender, forKey: "gender") 

          userObject.saveInBackground() 



          var sharedInstance:userSingleton = userSingleton.sharedInstance 

          sharedInstance.userName = (userObject.objectForKey("name") as NSString) 
          sharedInstance.userGender = (userObject.objectForKey("gender") as NSString) 


          (userObject.objectForKey("file") as PFFile).getDataInBackgroundWithBlock { 
           (theImageData: NSData!, error: NSError!) -> Void in 

           println(error) 
           if error == nil { 

            sharedInstance.userImage = UIImage(data:theImageData) 
           } 
           self.performSegueWithIdentifier("LoginSegue", sender: self) 
          } 


         } 
        } 
       } 





       println("User signed up and logged in through Facebook!") 
      } else { 



       println("User logged in through Facebook!") 
      } 


     } 

    }) 

} 

} 

回答

4

假设你使用Parse,这里是我该怎么做。我个人创建一个类Utils.swift,我把所有我想要重用的东西(或者说我不想在我的ViewControllers):

class Utils { 

    class func notLoggedIn() -> Bool { 
     let user = PFUser.currentUser() 
     // here I assume that a user must be linked to Facebook 
     return user == nil || !PFFacebookUtils.isLinkedWithUser(user) 
    } 
    class func loggedIn() -> Bool { 
     return !notLoggedIn() 
    } 


    class func logInWithFacebook() { 
     PFFacebookUtils.logInWithPermissions(["public_profile", "user_friends"]) { 
      (user: PFUser!, error: NSError!) -> Void in 
      if user == nil { 
       NSLog("The user cancelled the Facebook login (user is nil)") 
      } else { 
       NSLog("The user successfully logged in with Facebook (user is NOT nil)") 
       // HERE I SET A USER POINTER TO THE INSTALLATION 
       // That way we can send push notifications to specific users 
       if let installation = PFInstallation.currentInstallation() { 
        installation["user"] = PFUser.currentUser() 
        installation.saveEventually() 
       } 
       // THEN I GET THE USERNAME AND fbId 
       Utils.obtainUserNameAndFbId() 
      } 
     } 
    } 


    class func obtainUserNameAndFbId() { 
     if notLoggedIn() { 
      return 
     } 
     let user = PFUser.currentUser() // Won't be nil because is logged in 
     // RETURN IF WE ALREADY HAVE A USERNAME AND FBID 
     // Note that we check the fbId because Parse automatically fills in the username with random numbers 
     if let fbId = user["fbId"] as? String { 
      if !fbId.isEmpty { 
       println("we already have a username and fbId -> return") 
       return 
      } 
     } 
     // REQUEST TO FACEBOOK 
     println("performing request to FB for username and IDF...") 
     if let session = PFFacebookUtils.session() { 
      if session.isOpen { 
       println("session is open") 
       FBRequestConnection.startForMeWithCompletionHandler({ (connection: FBRequestConnection!, result: AnyObject!, error: NSError!) -> Void in 
        println("done me request") 
        if error != nil { 
         println("facebook me request - error is not nil :(") 
        } else { 
         println("facebook me request - error is nil :)") 
         println(result) 
         // You have 2 ways to access the result: 
         // 1) 
         println(result["name"]) 
         println(result["id"]) 
         // 2) 
         println(result.name) 
         println(result.objectID) 
         // Save to Parse: 
         PFUser.currentUser().username = result.name 
         PFUser.currentUser().setValue(result.objectID, forKey: "fbId") 
         PFUser.currentUser().saveEventually() // Always use saveEventually if you want to be sure that the save will succeed 
        } 
       }) 
      } 
     } 
    } 

} 

然后,你可以简单地调用Utils.logInWithFacebook()当你想执行登录。

请注意,由于facebook我的请求可能会失败,因此无法保证您将用户名和Facebook ID成功保存到Parse。这就是我创建方法Utils.obtainUserNameAndFbId()的原因,我在application(_: didFinishLaunchingWithOptions)中调用它(每次启动都可以调用它,因为它只会执行对FB的请求,直到成功为止)。