Parse: Facebook login doesn't create new PFUser

I am trying to integrate Facebook login and Parse so that a new PFUser is created on login. I created a Facebook login button and when I click on it the standard login screen for login / permission request appears. When I accept the login, I am redirected back to the start screen and the log shows that the user has canceled the Facebook login. When I check my details on the Parse website, there is no PFUsers.

As far as I can tell, I followed the exact instructions outlined in Parse ( https://parse.com/docs/ios/guide#users ) and Facebook. ( https://developers.facebook.com/docs/ios/getting-started ). I am using XCode 6.3.2. I added integrated Parse (ParseFacebookUtilsV4 v1.7 and ParseUI v1.1) and Facebook (FBSDKCoreKit v4.2 and FBSDKLoginKit v4.2) to Cocoapods and linked the following libraries:

libsqlite3.dylib
libz.dylib
Accounts.framework
AudioToolbox.framework
CFNetwork.framework
CoreGraphics.framework
CoreLocation.framework
CoreLocation.framework
MobileCoreService.framework
QuartzCore.framework
Security.framework
Social.framework
StoreKit.framework
SystemConfiguration.framework
libPods-xxx.a (being the name of my project)

      

My code looks like this:

//Appdelegate.swift
import UIKit


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

//--------------------------------------
// MARK: - UIApplicationDelegate
//--------------------------------------

func application(application: UIApplication, didFinishLaunchingWithOptions   launchOptions: [NSObject: AnyObject]?) -> Bool {


    Parse.setApplicationId("xxxxxxxx",
        clientKey: "xxxxxxxxxx")
               PFFacebookUtils.initializeFacebookWithApplicationLaunchOptions(launchOptions)

    return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)


}

}


func application(   application: UIApplication,
                openURL url: NSURL,
                sourceApplication: String,
                annotation: AnyObject?) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application,
                                                            openURL: url,
                                                            sourceApplication: sourceApplication,
                                                            annotation: annotation)
}

//Facebook analytics
func applicationDidBecomeActive(application: UIApplication!) {
FBSDKAppEvents.activateApp()
} 

      

And the View controller that hosts the login:

//OnboardingRootViewController.swift

import Foundation
import UIKit




class OnboardingRootViewController: UIViewController {


override func viewDidLoad() {
    super.viewDidLoad()
}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}



@IBAction func fbLoginClick(sender: AnyObject) {

var permissions = ["public_profile", "email", "user_likes"]


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.")
    }
}
}


}

      

So, can anyone help? Again, Facebook login at least works when IBAction fbLoginClick is called, but "Uh oh. User canceled Facebook login". the message is displayed in the log and no new PFUser is generated in Parse. I've seen several other similar questions, but none of them answered real questions, so I'm sure the answer to this question will be appreciated by many, especially since it uses the exact code shown in the login tutorials created by Parse and Facebook !

Edit: If no one else can help, I would still appreciate help with the following: I was told that I should check what error message loginInBackgroundWithReadPermissions is returning, unfortunately without further explanation. Was this person just a link to "Oh, oh, the user has canceled their Facebook login." message or can I get any information via NSError?

Edit # 2: I added the following line of code to see what the NSError returns: println ("write failure: (error? .LocalizedDescription)")

And get the following message in the log: Oh, oh. The user has canceled their Facebook login. failed write: nil

So, I guess it didn't make me anymore ...

Edit # 3: Seriously, I'll pay $ 10 to anyone who can help me

+3


source to share


1 answer


This code will work if you've configured your frameworks correctly and follow the instructions for setting up Facebook Parse ( https://parse.com/docs/ios/guide#users-facebook-users ). Make sure your syntax matches the functions I have and try to get rid of unnecessary code that is not included below.

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 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 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 is a simple UIButton that I put in the center of an empty view manager in my Main.storyboard

Objective-C Bridge Header:

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

      

Hope this solves your problem!

+1


source







All Articles