解析并返回Facebook登录和注册,并返回“用户已取消登录".(iOS 8.1 + Swift 1.2) [英] Parse and Facebook login and signup returning "User Cancelled Login" (iOS 8.1 + Swift 1.2)

查看:63
本文介绍了解析并返回Facebook登录和注册,并返回“用户已取消登录".(iOS 8.1 + Swift 1.2)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试使用Parse(版本1.7.4)登录并使用Facebook的SDK(版本4.1)注册用户,但是每次尝试注册时,以下代码都会显示用户取消了FB登录",这意味着将返回nil用户,但没有错误.我不知道这是Parse问题还是Facebook问题,但是如果有人知道如何解决此问题,我将不胜感激.

I've been attempting to use Parse (version 1.7.4) to login and sign up users with Facebook's SDK (version 4.1), but every time I attempt to signup, the following code prints "User cancelled FB login", which means the user is being returned as nil, but there isn't an error. I don't know if this is a Parse issue or a Facebook issue, but if anyone has any idea how to possibly solve this issue, I will be immensely grateful.

这是我的登录/注册视图控制器"的代码:

This is the code for my Login/Signup View Controller:

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中的代码(当然,其中的Parse键也已编辑):

Here's the code from my AppDelegate.swift (with the Parse keys edited out of course):

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)

}

这是我的框架的屏幕截图:

And here are screenshots of my frameworks:

我仔细检查了info.plist并确保我的捆绑包标识符在我的Facebook应用程序设置中,而我的facebook信息在我的Parse应用程序设置中.我尝试制作一个全新的Parse和Facebook应用程序,问题仍然存在.我记得几个月前分别测试了Facebook登录名和Parse用户注册,并创建了一个用户并将该帐户链接到该应用程序,但是在实施PFFacebokUtils并删除旧用户之后,登录名似乎继续表明用户"Cancelled FB"登录."该应用是否可以保存或缓存我不知道的旧用户或某些Facebook令牌,从而阻止了另一次登录或注册?我尝试使用PFUser.logOut()并打印信息以确认我的应用程序中没有现有用户,但仍然显示该用户取消了登录.使用accessToken可以解决问题吗?得到我的Facebook应用程序的批准会有所改变吗?如果有人知道上述任何问题的答案,或者以前的答案或评论中没有提到任何想法,请告诉我.非常感谢您的帮助.

I double checked my info.plist and made sure my bundle identifier was in my Facebook app settings and my facebook information was in my Parse app settings. I tried making a completely new Parse and Facebook app and the issue persists. I remember testing the Facebook login and Parse user signup separately months ago and a user was created and the account was linked to the app, but after implementing PFFacebokUtils and deleting the old user, the login seems to continue to state that the user "Cancelled FB login." Could the app be saving or caching the old user or some facebook token that I'm not aware of that's preventing another login or signup? I tried using the PFUser.logOut() and printed the information to confirm that there was no existing user in my app, but it still says that the user cancelled the login. Would using an accessToken fix things? Would getting my Facebook app approved change anything? If anyone knows the answers to any of these questions or has an idea that hasn't been brought up in previous answers or comments, please let me know. Thank you so much for your help.

推荐答案

好吧,经过数月的无奈,我终于解决了这个问题!而且这非常简单.我决定只创建一个新的Xcode项目,专门用于测试PFFacebookUtils登录,以查看是否可以创建没有此问题的登录系统.果然,在仔细遵循Parse的Facebook登录指南( https://parse.com/docs/ios/guide#users-facebook-users ),我成功通过PFFacebookUtils登录,测试应用程序没有任何问题!事实证明,我所有的框架都正确设置,但是应用程序中某些关键功能的混合使用不必要的代码和语法略有不同,这导致了取消登录问题.我将把PFFacebookUtils测试项目中的所有代码放在下面,以便遇到相同问题的任何人都可以编辑其代码以使其匹配.如果那行不通,我建议您自己尝试一下,看看它们的不同之处.

Okay, after months of frustration I finally solved the problem! And it was surprisingly simple. I decided to just create a new Xcode project specifically for testing the PFFacebookUtils login to see if I could create a login system that didn't have this issue. Sure enough, after carefully following Parse's Facebook Login guide (https://parse.com/docs/ios/guide#users-facebook-users), I successfully logged in through PFFacebookUtils with no issue on the test app! It turns out I had all of my frameworks set up correctly, but there was a mix of unnecessary code and slightly different syntax for certain key functions in my app that caused the cancel login issue. I will put all of the code from my PFFacebookUtils test project below so anyone facing the same issue can edit their code to match it. If that doesn't work, I would recommend trying it out yourself and seeing where they differ.

AppDelegate.swift

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

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中空白视图控制器的中心

The @IBAction is for a simple UIButton I put in the center of the blank viewcontroller in my Main.storyboard

Objective-C桥接标头:

Objective-C Bridging Header:

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

希望这对遇到此问题的其他人有所帮助!

Hope this helps anyone else who faces this issue!

这篇关于解析并返回Facebook登录和注册,并返回“用户已取消登录".(iOS 8.1 + Swift 1.2)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆