We were unable to review your app as it crashed on launch. We have attached detailed crash logs to help troubleshoot this issue.
Specifically, your app still crashed on launch after the user logged in with facebook.
I m unable to catch the crash or any error.
Here's the code for where I think it's crashing (run right after users log in with Facebook)
#IBAction func Btn_facebook(_ sender: Any)
{
getFacebookUserInfo()
}
func getFacebookUserInfo()
{
let fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
fbLoginManager.logIn(withReadPermissions: ["public_profile","email"], from: self) { (result, error) -> Void in
if (error == nil)
{
let fbloginresult : FBSDKLoginManagerLoginResult = result!
// if user cancel the login
if (result?.isCancelled)!{
return
}
if(fbloginresult.grantedPermissions.contains("email"))
{
self.getFBUserData()
self.fbtoken = result!.token.tokenString
}
}
}
}
func getFBUserData()
{
if((FBSDKAccessToken.current()) != nil)
{
FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, email, picture"]).start(completionHandler: { (connection, result, error) -> Void in
if result != nil {
guard FBSDKAccessToken.current().tokenString != nil else {
debugPrint("failed to get access token")
return
}
guard let result = result as? NSDictionary, let user_id_fb = result["id"] as? String else {
print("error")
return
}
}
if (error == nil)
{
let fbDetails = result as! NSDictionary
let field = result! as? [String:Any]
if let imageURL = ((field!["picture"] as? [String: Any])?["data"] as? [String: Any])?["url"] as? String {
print(imageURL)
let url = URL(string: imageURL)
print(url!)
self.fburl = imageURL
print(self.fburl!)
}
let checkemail = fbDetails["email"] as? String
if(checkemail != nil)
{
print(" check email not nil ", checkemail as Any)
self.fbemail = (fbDetails["email"] as? String)
self.fbid = (fbDetails["id"] as? String)
self.fbname = (fbDetails["name"] as? String)
self.GandfLogin(name: self.fbname!, email: self.fbemail!, post_image: (self.fburl!))
}
else
{
print(" check email nil ",checkemail ?? String.self)
self.fbid = (fbDetails["id"] as? String)
self.fbname = (fbDetails["name"] as? String)
self.GandfLogin(name: self.fbname!, email: self.fbid!, post_image: (self.fburl!))
}
}
else
{
print(error?.localizedDescription ?? "Not found")
}
})
}
}
Use soft unwraps instead of ! in most cases
Because it can lead to crashes if Facebook does not send data which you a looking for back
Do it this way:
guard let fbDetails = result as NSDictionary else {
//Show error to user or something else
return
}
Related
How do I print out the image from
print((result! as AnyObject).value(forKey: "picture.data.url") as? Any)
I know that the following prints out the data and url but I just need the URL section.
print((result! as AnyObject).value(forKey: "picture") as? Any)
any advise?
I am using FacebookLogin SDK
NOTE: You can create the image URL on your own if you have the userId,
let facebookProfileUrl = "http://graph.facebook.com/\(userID)/picture?type=large"
Here is how you can get id,name,email and profile picture url from facebook login. I use this code in my app and it works.
func fetchFacebookFields() {
LoginManager().logIn(permissions: ["email","public_profile"], from: nil) {
(result, error) -> Void in
if let error = error {
print(error.localizedDescription)
return
}
guard let result = result else { return }
if result.isCancelled { return }
else {
GraphRequest(graphPath: "me", parameters: ["fields" : "first_name, last_name, email"]).start() {
(connection, result, error) in
if let error = error {
print(error.localizedDescription)
return
}
if
let fields = result as? [String:Any],
let userID = fields["id"] as? String,
let firstName = fields["first_name"] as? String,
let lastName = fields["last_name"] as? String,
let email = fields["email"] as? String
{
let facebookProfileUrl = "http://graph.facebook.com/\(userID)/picture?type=large"
print("firstName -> \(firstName)")
print("lastName -> \(lastName)")
print("email -> \(email)")
print("facebookProfileUrl -> \(facebookProfileUrl)")
APPDELEGATEOBJ.makeRootVC(vcName : "MainTabBarVC")
}
}
}
}
}
hello i need some help i've been searching hours about this subject i tried a lot of thing but i couldn't do it.
Here is my code
let facebookReadPermissions = ["public_profile", "email"]
func getFBUserData() {
if((FBSDKAccessToken.current()) != nil){
self.getFBUserDataSecondStep()
} else {
FBSDKLoginManager().logIn(withReadPermissions: self.facebookReadPermissions, from: self) { (result, error) in
if error != nil {
FBSDKLoginManager().logOut()
} else if (result?.isCancelled)! {
FBSDKLoginManager().logOut()
} else {
self.showLoadingAlert()
let grantedPermissions = result?.grantedPermissions.map( {"\($0)"} )
for permission in self.facebookReadPermissions {
if (grantedPermissions?.contains(permission))! {
print("permission: \(permission)")
// CONSOLE WRITING HERE LIKE THIS
// permission: public_profile
// permission: email
}
}
if (result?.grantedPermissions.contains("email"))! {
print("result is: \(result?.description ?? "nil")")
// result is: <FBSDKLoginManagerLoginResult: 0x1c0441920> ( console )
self.getFBUserDataSecondStep()
} else {
FBSDKLoginManager().logOut()
}
}
}
}
}
func getFBUserDataSecondStep(){
FBSDKGraphRequest(graphPath: "/me", parameters: ["fields": "id, name, first_name, last_name, email"]).start(completionHandler: { (connection, result, error) -> Void in
if (error == nil){
if let dict = result as? Dictionary<String, Any> {
print(result)
// COMING WITH LIKE THIS
//"first_name" = Esn;
//id = 10156020817443470;
//"last_name" = "\U00c7ak\U0131ralar";
//name = "Esn Banu\U015f \U00c7ak\U0131ralar";
//--// Where is email ?
var email = ""
var firstName = ""
var lastName = ""
var facebookId = ""
var facebookToken = ""
if let controlEmail = dict["email"] {
email = controlEmail as! String
}
if let controlFirstName = dict["first_name"] {
firstName = controlFirstName as! String
}
if let controlLastName = dict["last_name"] {
lastName = controlLastName as! String
}
if let controlFacebookId = FBSDKAccessToken.current().userID {
facebookId = controlFacebookId
}
if let controlFacebookToken = FBSDKAccessToken.current().tokenString {
facebookToken = controlFacebookToken
}
loginWithFacebook(email: email, firstName: firstName, lastName: lastName, facebookId: facebookId, accessToken: facebookToken, finishedClosured: { (state) in
if state {
let mainPage = self.mainStoryBoard.instantiateViewController(withIdentifier: "SWRevealViewController")
self.removeLoadingAlert()
self.passPage(page: mainPage)
return
}
self.removeLoadingAlert()
self.alert(message: "Giris Basarisiz")
return
})
}
} else {
print(error?.localizedDescription)
}
})
}
i need go get email of person to register user to my application. But email doesn't come whatever i tried. How can i fix this issue and also if i try with my personel account its ok no problem but another user it can be problem.
Note : This is in swift 4.0
//giving permission
func getpermission(){
let fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
// fbLoginManager.loginBehavior = FBSDKLoginBehavior.web
fbLoginManager.logIn(withReadPermissions: ["email"], from: self) { (result, error) in
if (error == nil){
let fbloginresult : FBSDKLoginManagerLoginResult = result!
if fbloginresult.grantedPermissions != nil {
if(fbloginresult.grantedPermissions.contains("email"))
{
self.getFBUserData()
fbLoginManager.logOut()
}
}
}
}
}
// Get all details from here
func getFBUserData(){
var fbId : String = ""
var fbEmail : String = ""
var fbName : String = ""
var fbPickUrl : String = ""
if((FBSDKAccessToken.current()) != nil){
FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).start(completionHandler: { (connection, result, error) -> Void in
if (error == nil){
//everything works print the user data
print("Result111:\(String(describing: result)) "as Any)
}
let dict = result as! NSDictionary
print("FB Email1st:\(dict)")
fbId = dict["id"] as! String
fbName = dict["name"] as! String
fbEmail = dict["email"] as! String
//get user picture url from dictionary
fbPickUrl = (((dict["picture"] as? [String: Any])?["data"] as? [String:Any])?["url"] as? String)!
print("FB ID: \(fbId)\n FB Email:\(fbEmail) \n FbName:\(fbName) \n FBProfileUrl:\(fbPickUrl)\n")
})
}
}
let loginManager = FBSDKLoginManager()
loginManager.logIn(withReadPermissions: ["user_about_me", "email" , "user_birthday","user_hometown"], from: self) { (loginResult, error) in
if error != nil
{
self.showalert(strMessage: (error?.localizedDescription)!)
}
else
{
if loginResult?.grantedPermissions == nil
{
self.showalert(strMessage: "Login Permissions not granted")
return
}
if (loginResult?.grantedPermissions.contains("email"))!
{
if (loginResult?.grantedPermissions.contains("user_birthday"))!
{
self.getFBUserData()
}
else
{
self.getFBUserData()
}
}
}
}
}
func getFBUserData()
{
FBSDKGraphRequest.init(graphPath: "me?fields=id,name,email,first_name,last_name,cover,picture.type(large),gender,birthday,hometown", parameters: nil).start(completionHandler: { (connection , result , error ) in
if(error == nil){
DispatchQueue.main.async {
let dictionary = result as! NSDictionary
print(dictionary)
print("Name : \(dictionary.value(forKey: "name")!)")
print("FB ID : \(dictionary.value(forKey: "id")!)")
self.FaceBookID = dictionary.value(forKey: "id") as? String
}
}else{
self.showalert(strMessage: "Somthig Went Wrong..!")
}
})
I am having some trouble in my code. I gave the permission of "user_photos" in "loginwithreadpermission" but still not getting the users album. I also tried this "fbuserid/albums" but this is also not working for me. Please help me what I am doing wrong.
This is my Login Code:
#IBAction func facebookLogin(sender: AnyObject)
{
let facebookLogin = FBSDKLoginManager()
facebookLogin.logOut()
facebookLogin.logInWithReadPermissions(["email" , "user_photos"], fromViewController: nil) { (facebookResult, facebookError) in
if facebookError != nil {
print("Login Failed. Error: \(facebookError)")
}
else {
if !(facebookResult.isCancelled)
{
let accessToken = FBSDKAccessToken.currentAccessToken().tokenString
if accessToken != nil
{
token = accessToken
let credential = FIRFacebookAuthProvider.credentialWithAccessToken(accessToken)
print("1")
FIRAuth.auth()?.signInWithCredential(credential)
{
(user, error) in
if error != nil
{
print("Error Firebase: \(error)")
}
else
{
if self.userEmails.contains(user!.email!)
{
print("User Already Exist")
NSUserDefaults.standardUserDefaults().setValue(user?.uid, forKey: KEY_UID)
USER_UID = (user?.uid)!
print("id:\(USER_UID)")
LOGIN_FLAG = 1
FaceBookFlag = 1
self.performSegueWithIdentifier("fbLogin", sender: nil)
}
else if user!.email != nil
{
print("Creating a User Data in FB")
var request = FBSDKGraphRequest(graphPath:"me", parameters: ["fields":"email,first_name,age_range"]);
request.startWithCompletionHandler({ (connection, result, error) in
if error == nil
{
print("res: \(result)")
if let dob = result.valueForKey("age_range") as? [String: AnyObject]
{
print("dd: \(dob["min"]!)")
self.dateOfBirth = String(dob["min"]!)
print("dob: \(dob) , date: \(self.dateOfBirth)")
print(" date: \(self.dateOfBirth!)")
}
}
else
{
print("error:: \(error)")
}
let displayName = user?.displayName!.componentsSeparatedByString(" ")
let firstName = displayName![0]
let lastName = displayName![1]
print("url: \(user?.photoURL)")
let profilePicUrl = user?.photoURL
let picture = String(profilePicUrl!)
let userEmail = user!.email!
let _user = ["username": "\(firstName+lastName)","emailAddress": "\(userEmail)", "dateOfBirth": "\(self.dateOfBirth!)"]
ref.child("users").child(user!.uid).setValue(_user)
ref.child("users").child(user!.uid).child("images").setValue([picture])
NSUserDefaults.standardUserDefaults().setValue(user?.uid, forKey: KEY_UID)
USER_UID = (user?.uid)!
LOGIN_FLAG = 1
FaceBookFlag = 1
//Segue to reveal view controller
self.performSegueWithIdentifier("fbLogin", sender: nil)
})
}
}
}
}
}
}
}
}
And This is my Code where I am requesting to give me the albums of current user :
func getAlbums()
{
//for sake of running i hardcoded the FBuserId.
let fbid = "758111074330935"
//169682503464671/photos
let graphRequest = FBSDKGraphRequest(graphPath: "/\(fbid)/albums", parameters: ["fields":"photos,picture"] , HTTPMethod: "GET")
graphRequest.startWithCompletionHandler { (connection, result, error) in
if error != nil
{
print(error)
}
else
{
print("rr:\(result)")
let value = result.valueForKey("data")
print("value:\(value) ... \(result["data"])")
if let graphData = result.valueForKey("data") as? [AnyObject]
{
print("array of Any")
for obj in graphData
{
print("id: \(obj.valueForKey("id")!)")
let id = String(obj.valueForKey("id")!)
self.albumsId.append(id)
//Also save the album link here to.
}
}
}
You have a wrong set of fields for this type of request.
Check this doc to verify the fields that are available: https://developers.facebook.com/docs/graph-api/reference/v2.7/album
In particular, I'm getting the following error (which is self-explained):
{
"error": {
"message": "(#100) Unknown fields: email,first_name.",
"type": "OAuthException",
"code": 100,
"fbtrace_id": "G0POfi9dWkb"
}
}
I got my app onto the App Store. Everything was working fine on my end, and apparently on the reviewers end.
After the app went live, some users reported crashing immediately after they log in with Facebook. Here's the code for where I think it's crashing (run right after users log in with Facebook):
import UIKit
import FBSDKCoreKit
import FBSDKLoginKit
protocol getUserDataDelegate {
func gotData()
}
public var userEmailForMixpanel = ""
public var userNameForInvites = ""
class GetUserData: NSObject {
var facebookid:String = ""
var userEmail:String = ""
var userFirstName:String = ""
var userLastName: String = ""
var userGender:String = ""
var userBirthday:String = ""
var delegate = getUserDataDelegate?()
func returnUserData() {
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, email, first_name, last_name, gender, birthday"])
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
if ((error) != nil)
{
print("Error: \(error)")
}
else
{
self.facebookid = (result.valueForKey("id") as? String)!
self.userEmail = (result.valueForKey("email") as? String)!
self.userFirstName = (result.valueForKey("first_name") as? String)!
self.userLastName = (result.valueForKey("last_name") as? String)!
self.userGender = (result.valueForKey("gender") as? String)!
//self.userBirthday = (result.valueForKey("birthday") as? String)!
userEmailForMixpanel = self.userEmail
userNameForInvites = self.userFirstName
NSUserDefaults.standardUserDefaults().setValue(userEmailForMixpanel, forKey: "userEmail")
NSUserDefaults.standardUserDefaults().setValue(userNameForInvites, forKey: "userName")
NSUserDefaults.standardUserDefaults().synchronize()
Mixpanel.sharedInstanceWithToken("abdc")
let mixpanel = Mixpanel.sharedInstance()
mixpanel.registerSuperProperties(["Gender":self.userGender])
print(self.facebookid)
print(self.userEmail)
print(self.userFirstName)
print(self.userLastName)
print(self.userGender)
//print(self.userBirthday)
self.checkIfUserExists()
}
})
}
func checkIfUserExists() {
showTutorial = true
let url:NSURL = NSURL(string: "url")!
let task:NSURLSessionDataTask = NSURLSession.sharedSession().dataTaskWithURL(url) { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
let userTokenDataDictionary:NSDictionary = (try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)) as! NSDictionary
if userTokenDataDictionary ["token"] != nil {
userAccessToken = (userTokenDataDictionary["token"] as? String)!
NSUserDefaults.standardUserDefaults().setValue(userAccessToken, forKey: "userAccessToken")
NSUserDefaults.standardUserDefaults().synchronize()
print("Token for Existing User:\(userAccessToken)")
self.finishedGettingData()
}
if userTokenDataDictionary ["error"] != nil {
userAccessToken = (userTokenDataDictionary["error"] as? String)!
print(userAccessToken)
print("User needs to be created")
self.createNewUserFromFacebook()
}
}
task.resume()
}
func createNewUserFromFacebook() {
let url:NSURL = NSURL(string: "url")!
print(url)
let task:NSURLSessionDataTask = NSURLSession.sharedSession().dataTaskWithURL(url) { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
let userTokenDataDictionary:NSDictionary = (try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)) as! NSDictionary
if userTokenDataDictionary ["token"] != nil {
userAccessToken = (userTokenDataDictionary["token"] as? String)!
NSUserDefaults.standardUserDefaults().setValue(userAccessToken, forKey: "userAccessToken")
NSUserDefaults.standardUserDefaults().synchronize()
}
if userTokenDataDictionary ["error"] != nil {
userAccessToken = (userTokenDataDictionary["error"] as? String)!
print(userAccessToken)
}
print("Token for New User:\(userAccessToken)")
self.finishedGettingData()
}
task.resume()
}
func checkIfUserHasUsedListenerApp() {
let accessToken = NSUserDefaults.standardUserDefaults().stringForKey("userAccessToken")!
let url:NSURL = NSURL(string: "url")!
print(url)
let task:NSURLSessionDataTask = NSURLSession.sharedSession().dataTaskWithURL(url) { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
let adDataDict:NSDictionary = (try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)) as! NSDictionary
if adDataDict ["used_ListenerApp"] != nil {
let responseCode = adDataDict.valueForKey("used_ListenerApp") as! Bool
print(responseCode)
if responseCode == false {
Mixpanel.sharedInstanceWithToken("abc")
let mixpanel = Mixpanel.sharedInstance()
mixpanel.track("New User Signed Up", properties: ["distinct_id":userEmailForMixpanel])
}
if responseCode == true {
return
}
}
}
task.resume()
}
func finishedGettingData() {
self.checkIfUserHasUsedListenerApp()
Mixpanel.sharedInstanceWithToken("abc")
let mixpanel = Mixpanel.sharedInstance()
mixpanel.track("User Logged In", properties: ["distinct_id":userEmailForMixpanel])
if let actualdelegate = self.delegate {
actualdelegate.gotData()
}
}
}
It's only crashing for some users, not all. I even tried creating a loop that generates a bunch of user data to run it through this code, and I couldn't replicate the crash.
Any advice would be appreciated a lot.
UPDATE
It looks like it has to do with Facebook not returning an email address. I'll keep looking though.
I figured it out. Part of the problem was that Facebook wasn't returning an email address for some users, so I checked for that and if it didn't return an email, I created one with their Facebook ID to get them through the login process (fbid#facebook.mywebsite.com).
Another part of the problem was that some users had logged into my website using an email address that was also assigned to their Facebook account, and tried logging in with Facebook on the app. I fixed this by having it merge their Facebook info with their existing account during the authorization process if an existing account is found.
I have a log in system in my app swift 2.0 integrated with Facebook, I'm able to get some user informations and profile_picture.
I'm wondering how to get the cover Image from the User logged :
let requestParameters = ["fields": "id, email, first_name, last_name, name, gender, cover"]
let userDetails = FBSDKGraphRequest(graphPath: "me", parameters: requestParameters)
userDetails.startWithCompletionHandler { (connection, result, error:NSError!) -> Void in
if(error != nil)
{
print("\(error.localizedDescription)")
return
}
if(result != nil)
{
let userId:String = result["id"] as! String
let userFirstName:String? = result["first_name"] as? String
let userLastName:String? = result["last_name"] as? String
let userEmail:String? = result["email"] as? String
let userName:String? = result["name"] as? String
let userGender:String? = result["gender"] as? String
let userCover:UIImage? = result["cover"] as? UIImage
print(requestParameters)
print(userDetails)
print(userCover)
print("\(userEmail)")
let myUser:PFUser = PFUser.currentUser()!
// Save first name
if(userFirstName != nil)
{
myUser.setObject(userFirstName!, forKey: "firstNameColumn")
}
//Save last name
if(userLastName != nil)
{
myUser.setObject(userLastName!, forKey: "lastNameColumn")
}
// Save email address
if(userEmail != nil)
{
myUser.setObject(userEmail!, forKey: "email")
}
// Save email address
if(userGender != nil)
{
if (userGender == "male"){
myUser.setObject("Masculino", forKey: "genderColumn")
} else {
myUser.setObject("Feminino", forKey: "genderColumn")
}
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
// Get Facebook profile picture
let userProfile = "https://graph.facebook.com/" + userId + "/picture?type=large"
let profilePictureUrl = NSURL(string: userProfile)
let profilePictureData = NSData(contentsOfURL: profilePictureUrl!)
if(profilePictureData != nil)
{
let profileFileObject = PFFile(data:profilePictureData!)
myUser.setObject(profileFileObject!, forKey: "photoUserColumn")
}
myUser.saveInBackgroundWithBlock({ (success:Bool, error:NSError?) -> Void in
if(success)
{
print("User details are now updated")
}
})
}
This code its not working just for the cover Image.
Any ideas?
Here's a working example using fb sdk in swift. I posted this answer in the other question as well but because this answer came up first for me on google I thought it'll be nice to put it here as well.
I needed to get the cover photo of a page so in the graphPath I used page id. This parameter can be easily changed to fit users / events / etc...
let request = FBSDKGraphRequest(graphPath: "\\(page.id)?fields=cover", parameters: [
"access_token": "your_access_token"
], HTTPMethod: "GET")
request.startWithCompletionHandler({(connection , result , error) in
if ((error) != nil) {
print("Error in fetching cover photo for \\(page.id): \(error)", terminator: "")
}
else {
if let data = result["cover"] as? NSDictionary {
self.fetchImageFromUrl(data["source"] as! String, cb: {(image: UIImage) -> Void in
//do something with image
})
}
})
func fetchImageFromUrl(url: String, cb: (UIImage) -> Void) {
let urlObj = NSURL(string: url)!
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
let data = NSData(contentsOfURL: urlObj)
dispatch_async(dispatch_get_main_queue(), {
let image = UIImage(data: data!)!
cb(image)
});
}
}
P.S - I'm a newbie in swift / ios so this code might not be the best. Comments will be appreciated.
It can be useful.
let emailRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"email,name, id,cover"], tokenString: result?.token.tokenString, version: nil, httpMethod: "GET")
_ = emailRequest?.start(completionHandler: { (nil, resultParameters, error) in
if(error == nil) {
if let cover = (params?["cover"] as? NSDictionary)["source"]{
var coverUrl = cover as? String
}
}
})