Parse and Facebook login and signup returning "User Cancelled Login" (iOS 8.1 + Swift 1.2) -
i've been attempting use parse (version 1.7.4) login , sign users facebook's sdk (version 4.1), every time attempt signup, following code prints "user cancelled fb login", means user being returned nil, there isn't error. don't know if parse issue or facebook issue, if has idea how possibly solve issue, immensely grateful.
this code 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 , logged in 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") } } }) }
here's code appdelegate.swift (with 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 tasks paused (or not yet started) while application inactive. if application in background, optionally refresh user interface. fbsdkappevents.activateapp() } func applicationwillterminate(application: uiapplication) { // called when application terminate. save data if appropriate. see applicationdidenterbackground:. // saves changes in application's managed object context before application terminates. self.savecontext() } func application(application: uiapplication, url: nsurl, sourceapplication: nsstring, annotation: anyobject) -> bool { return fbsdkapplicationdelegate.sharedinstance().application( application, openurl: url, sourceapplication: sourceapplication string, annotation: annotation) }
and here screenshots of frameworks:
i double checked info.plist , made sure bundle identifier in facebook app settings , facebook information in parse app settings. tried making new parse , facebook app , issue persists. remember testing facebook login , parse user signup separately months ago , user created , account linked app, after implementing pffacebokutils , deleting old user, login seems continue state user "cancelled fb login." app saving or caching old user or facebook token i'm not aware of that's preventing login or signup? tried using pfuser.logout() , printed information confirm there no existing user in app, still says user cancelled login. using accesstoken fix things? getting facebook app approved change anything? if knows answers of these questions or has idea hasn't been brought in previous answers or comments, please let me know. thank help.
okay, after months of frustration solved problem! , surprisingly simple. decided create new xcode project testing pffacebookutils login see if create login system didn't have issue. sure enough, after following parse's facebook login guide (https://parse.com/docs/ios/guide#users-facebook-users), logged in through pffacebookutils no issue on test app! turns out had of frameworks set correctly, there mix of unnecessary code , different syntax key functions in app caused cancel login issue. put of code pffacebookutils test project below facing same issue can edit code match it. if doesn't work, recommend trying out , seeing differ.
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 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 application move active inactive state. can occur types of temporary interruptions (such incoming phone call or sms message) or when user quits application , begins transition background state. // use method pause ongoing tasks, disable timers, , throttle down opengl es frame rates. games should use method pause game. } func applicationdidenterbackground(application: uiapplication) { // use method release shared resources, save user data, invalidate timers, , store enough application state information restore application current state in case terminated later. // if application supports background execution, method called instead of applicationwillterminate: when user quits. } func applicationwillenterforeground(application: uiapplication) { // called part of transition background inactive state; here can undo many of changes made on entering 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 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 application terminate. save data if appropriate. see applicationdidenterbackground:. // saves changes in application's managed object context before application terminates. self.savecontext() }
viewcontroller.swift
import uikit class viewcontroller: uiviewcontroller { override func viewdidload() { super.viewdidload() // additional setup after loading view, typically nib. } override func didreceivememorywarning() { super.didreceivememorywarning() // dispose of resources can 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 , logged in through facebook!") } else { println("user logged in through facebook!") } } else { println("uh oh. user cancelled facebook login.") } } } }
the @ibaction simple uibutton put in center of blank viewcontroller in main.storyboard
objective-c bridging header:
#import <fbsdkcorekit/fbsdkcorekit.h> #import <parsefacebookutilsv4/pffacebookutils.h> #import <parse/parse.h>
hope helps else faces issue!
Comments
Post a Comment