FBSDKGraphRequest to sign up Parse users is "ambiguous?" - swift

The FBSDKGraphRequest connection handler used in the SignUpViewController of a tutorial app is now outdated. I updated it to a point where it won't error until I try to place the Parse code after the user successfully signs up. Once I put in the Parse code (to sign the user up using the FB SDK results), I get the errors "Type of expression is ambiguous without more context".
Here's what I have so far:
let graphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, gender, email"])
graphRequest.startWithCompletionHandler ({ connection, result, error in
if error != nil {
//onError()
print(error)
return
} else {
let fbResult = result as! Dictionary<String, AnyObject>
print("FbResult \(fbResult)")
PFUser.currentUser()?["gender"] = result["gender"]
PFUser.currentUser()?["name"] = result["name"]
try PFUser.currentUser()?.save()
let userId = result["id"] as! String
let facebookProfilePictureUrl = "https://graph.facebook.com/" + userId + "/picture?type=large"
if let fbpicUrl = NSURL(string: facebookProfilePictureUrl) {
if let data = NSData(contentsOfURL: fbpicUrl) {
self.profilePic.image = UIImage(data: data)
let imageFile:PFFile = PFFile(data: data)!
PFUser.currentUser()?["image"] = imageFile
try PFUser.currentUser()?.save()
}
})
For some reason XCode hates anything after the "print fbresult" line. Here's a pastebin of the working code before the Parse code:
http://pastebin.com/dUyEvYmr
How can I update this to accept the Parse code?
Thanks!!
PS: I can confirm that I have the latest Parse and FB SDK. I'm running the latest version of XCode (7.2.1).

I came across with the same problem when going through the udemy swift class too.
My solution was:
if let fbResult = {
...
let name : NSString = (fbResult.valueForKey("name") as? NSString)!
let gender : NSString = (fbResult.valueForKey("gender") as? NSString)!
...
}
Hope it works for you!

Related

Facebook Graph API: Swift SDK not working: GraphRequest

I've been trying to follow Facebooks documentation exactly but can't understand why my code doesn't work, even though it is exactly as in the docs. I am already signing into Facebook on my app, but I need to get the profile data.
Here is my function.
func fetchFacebookUser() {
let connection = GraphRequestConnection()
connection.add(GraphRequest(graphPath: "/me")) { httpResponse, result in
switch result {
case .success(let response):
print("Graph Request Succeeded: \(response)")
case .failed(let error):
print("Graph Request Failed: \(error)")
}
}
connection.start()
}
You'll notice it is exactly like the documentation:
https://developers.facebook.com/docs/swift/graph
But I can't even build the project because I get this error in Xcode:
Contextual closure type '(GraphRequestConnection?, Any?, Error?) -> Void' expects 3 arguments, but 2 were used in closure body
Insert ',<#arg#> '
It has the 'Fix' button but that just breaks the whole thing and Xcode (red warning) complains that none of the cases in the switch statement exist.
I have searched everywhere, the closest solution I got was this SO post: Facebook GraphRequest for Swift 5 and Facebook SDK 5
But that had no answers :(
I'm sure someone has called the Graph API using Swift? What am I missing here?
However i implement facebook login my app which works fine.
On button click I called facebook login using LoginManager.
#IBAction func continueWithFacebook(_ sender: Any) {
let fbLoginManager : LoginManager = LoginManager()
fbLoginManager.logIn(permissions: ["email"], from: self) { (result, error) -> Void in
if (error == nil){
let fbloginresult : LoginManagerLoginResult = result!
if (result?.isCancelled)!{
return
}
if(fbloginresult.grantedPermissions.contains("email")) {
self.getFBUserData()
}
}
}
}
After that I get the data of user using GraphAP
func getFBUserData() {
if((AccessToken.current) != nil){
GraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).start(completionHandler: { (connection, result, error) -> Void in
if (error == nil){
guard let userDict = result as? [String:Any] else {
return
}
if let picture = userDict["picture"] as? [String:Any] ,
let imgData = picture["data"] as? [String:Any] ,
let imgUrl = imgData["url"] as? String {
self.uURLString = imgUrl
/*let url = URL(string: imgUrl)*/
print(imgData)
}
if let n = userDict["name"] as? String {
self.name = n
}
if let e = userDict["email"] as? String {
self.email = e
}
self.socialLogIn()
}
})
}
}
Add in your pod file -
pod 'FBSDKCoreKit' and
pod 'FBSDKLoginKit'
Try using like this you will get your derided result.
Happy Coding

Requesting Facebook friends count in Swift 3

I'm trying to get the user Facebook friends count in Swift 3, but I found some problems:
First of all, I created this code based on Facebook Documention:
func getNumberOfFriends() {
let parameters = ["fields": "summary"]
FBSDKGraphRequest(graphPath: "me/friends", parameters: parameters, httpMethod: "GET").start { (connection, result, error) in
let userInformations = User.instance
if let error = error {
print("erro: \(error.localizedDescription)")
return
}
if let result = result as? [String: AnyObject] {
if let summary = result["summary"] as? NSDictionary {
if let total_count = summary["total_count"] as? Int {
userInformations.numberOfFriends = total_count
self.getFriendsCountDelegate?.didGetFriendsCount(error:false)
}
}
}
}
}
The problem is that I'm receiving an empty data response. I think the problem could be a strange thing I found in my Login: I'm requesting these permissions:
var loginButton = FBSDKLoginButton()
self.loginButton.readPermissions = ["public_profile", "user_friends", "email", "user_posts"]
self.loginButton.publishPermissions = ["publish_actions"]
but when I check those permissions, I found that I don't have it! I only have "public_profile" and "publish_actions".
When I check my FacebookApp Page, I see that it seems ok:
All permissions are ok on my Facebook App Page
Does somebody could help me? I don't know what else should I do!
Thank you

Get Facebook profile picture from URL

I want to upload the profile picture from Facebook to Firebase. I tried this answer: Upload Facebook image URL to Firebase Storage
However, Swift is giving me errors on the third line of code of that answer. The code is:
let dictionary = result as? NSDictionary
let data = dictionary?.object(forKey: "data")
let urlPic = (data?.objectForKey("url"))! as! String
Swift is telling me: Cannot call value of non-function type 'Any?!' after I changed the code to what Swift keeps suggesting me:
let urlPic = ((data as AnyObject).object(ForKey: "url"))! as! String
What is the code to use when I want to retrieve the profile picture from Facebook? My goal is to also store it into Firebase, but that will come after I get the profile picture first.
The answer is in Swift 1.2
I took reference here and implemented also
You can do this:
// accessToken is your Facebook id
func returnUserProfileImage(accessToken: NSString)
{
var userID = accessToken as NSString
var facebookProfileUrl = NSURL(string: "http://graph.facebook.com/\(userID)/picture?type=large")
if let data = NSData(contentsOfURL: facebookProfileUrl!) {
imageProfile.image = UIImage(data: data)
}
}
This is the way I got Facebook id:
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
{
println("fetched user: \(result)")
if let id: NSString = result.valueForKey("id") as? NSString {
println("ID is: \(id)")
self.returnUserProfileImage(id)
} else {
println("ID es null")
}
}
})
}

Pulling Facebook profile pic with parse using Swift

I'm trying to pull the username and profile picture for my apps profile page. I'm using Parse and the Facebook SDK.
I have a UILabel and a UIView connected as outlets.
When I try to set the profileImageView, it gives me the error "Value of type 'UIImageView' has no member 'setImageWithURL'" Is this an upgrade with Swift?
Here is my code...
func setProfilePicture() {
FBSDKGraphRequest(graphPath: "me", parameters: nil).startWithCompletionHandler({ (connection, result, error) -> Void in
if let dict = result as? Dictionary<String, AnyObject> {
let name: String = dict["name"] as! String
let facebookID: String = dict["id"] as! String
let pictureUrl = "https://graph.facebook.com/\(facebookID)/picture?type=large&return_ssl_resources=1"
self.profileImageView.setImageWithURL(NSURL(string: pictureUrl)!)
self.nameLabel.text = name
PFUser.currentUser()!.setValue(name, forKey: "name")
PFUser.currentUser()!.saveInBackground()
}
})
}
if let url = NSURL(string: "https://graph.facebook.com/\(facebookID)/picture?type=large&return_ssl_resources=1") {
if let data = NSData(contentsOfURL: url){
self.profileImageView.contentMode = UIViewContentMode.ScaleAspectFit
self.profileImageView.image = UIImage(data: data)
}
}
Try creating a function, fbProfilePicURL, that takes a Facebook ID and returns the profile picture URL as an NSURL, then change
self.profileImageView.setImageWithURL(NSURL(string: pictureUrl)!)
to
self.profileImageView.setImageWithURL(NSURL.fbProfilePicURL(facebookID))
Not 100% sure on this, but let me know if it works.

Can't pinpoint FBSDKGraphRequest crash

I'm using FB Login, and my app is crashing every now and then within that method. It works fine for me, but not for some other users. In this function, I'm setting user data in Parse with data received from the FBSDKGraphRequest.
// Sends FB Graph Request and sets user attributes in Parse
func setUserData() {
var user = PFUser.currentUser()!
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: nil)
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
if ((error) != nil)
{
println("Set user values error: \(error)")
}
else
{
firstName = result.valueForKey("first_name") as! NSString
lastName = result.valueForKey("last_name") as! NSString
user["name"] = "\(firstName) \(lastName)"
NSUserDefaults.standardUserDefaults().setObject("\(firstName) \(lastName)", forKey: "name")
id = result.valueForKey("id") as! NSString
user["fbID"] = id
gender = result.valueForKey("gender") as! NSString
user["gender"] = gender
email = result.valueForKey("email") as! NSString
user["email"] = email
user["score"] = 100
user.saveInBackgroundWithBlock({ (success, error) -> Void in
if success {
objID = user.objectId!
}
})
self.performSegueWithIdentifier("segue", sender: self)
}
})
}
Now, in Crashlytics, I'm getting EXC_BREAKPOINT, but can't figure out exactly where the crash is coming from or what to do about it. Looks like it may be coming from Facebook's side? Any help would be appreciated.
I've had the same issue. I forgot to put the permissions on the FBSDKLoginButton:
facebookLoginButton.readPermissions = ["public_profile", "email", "user_friends"];
Maybe you forgot it too?