2014-09-18 125 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的請求,直到成功爲止)。