Swift FacebookSDK Graphrequest Completion Handler not called - ios

if i implement the following function directly on the viewController everything works fine. (this is not complete, but it works for the picture)
func getFBData() {
if((FBSDKAccessToken.currentAccessToken()) != nil){
FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, email, first_name, last_name, picture"]).startWithCompletionHandler({ (connection, result, error) -> Void in
if (error == nil){
let email = result.valueForKey("email") as? String
let fbid = result.valueForKey("id") as! String
let fname = result.valueForKey("first_name") as! String
let lname = result.valueForKey("last_name") as! String
let facebookProfileUrl = "http://graph.facebook.com/\(fbid)/picture?type=large"
let url = NSURL(string: facebookProfileUrl)
if let data = NSData(contentsOfURL: url!) {
self.imgProfile.image = UIImage(data: data)
}
}
})
}
}
But instead i tried to keep all the facebook related stuff separated in a FacebookController.swift class.
class func getUserData() -> [String: String] {
var dict: [String: String]?
let token = FBSDKAccessToken.currentAccessToken()
let graphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, email, name, first_name, last_name, picture"])
if((token) != nil) {
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
if (error == nil) {
let fbid = result.valueForKey("id") as! String
let name = result.valueForKey("name") as? String
let fname = result.valueForKey("first_name") as! String
let lname = result.valueForKey("last_name") as! String
let email = result.valueForKey("email") as? String
let pictureURL = "http://graph.facebook.com/\(fbid)/picture?type=large"
dict = ["id": fbid, "name": name!, "fname": fname, "lname": lname, "email": email!, "picture": pictureURL]
print(dict)
} else {
print("ok")
print("\(error)")
}
})
}
return dict!
}
The User is logged in and all the permissions are granted, but when i try to call FacebookController().getUserData() it returns dict, which is nil. I already figured that this is because the completionHandler of the graphRequest never gets called.
Can anybody help?

Related

Unable to get user info after update to FB API

ERROR MESSAGE:
Invalid Scopes: user_birthday, user_photos, user_gender. This message
is only shown to developers
After Facebook update in their api I get invalid scope messages for user_birthday, user_photos, user_gender. I haven't submitted my app for a login review, however, as an admin of the app I shouldn't be having any errors related to permissions. What could I possibly be doing wrong?
FBSDKLoginManager().logIn(withReadPermissions: ["email", "public_profile", "user_birthday", "user_photos", "user_gender"], from: self) { (result, err) in
print("open facebook safari")
if (err != nil) {
print("Fb Login Failed", err ?? "")
self.dismiss(animated: true, completion: nil)
}
self.handleFirebase()
}
FBSDKGraphRequest(graphPath: "/me", parameters: ["fields": "id, name, first_name, last_name, gender, birthday, picture.width(400).height(400)"]).start(completionHandler: { (connection, result, error) in
if let error = error {
print(error.localizedDescription)
} else {
if let userData = result as? NSDictionary {
self.firstName = userData.object(forKey: "first_name") as? String
self.gender = userData.object(forKey: "gender") as? String
self.birthday = userData.object(forKey: "birthday") as? String ?? ""
let pictureDictionary = userData.object(forKey: "picture") as! NSDictionary
let pictureSubDictionary = pictureDictionary.object(forKey: "data") as! NSDictionary
self.userProfileUrl = pictureSubDictionary.object(forKey: "url") as! String
}
}

Read response from Facebook Graph Request in Swift 4

I'm trying to add a Facebook friend list to my Swift iOS app using the Graph API.
I'm struggling to work out how to actually access the data that's being send back from Facebook.
The response I get looks like this:
success(FacebookCore.GraphResponse(rawResponse: Optional({
"first_name" = Jamie;
id = 1626917907360895;
"last_name" = McAllister;
name = "Jamie McAllister";
picture = {
data = {
height = 50;
"is_silhouette" = 0;
url = "https://scontent.xx.fbcdn.net/v/t1.0-1/p50x50/12994335_1101318013254223_4481895970110564364_n.jpg?oh=d10209f113213981e4417e7f6f3f82d8&oe=5A91F135";
width = 50;
};
};
})))
My graph Request is just /me for now as I'm the only registered user. But all the fields in the response are what I will be requesting from the friends list
The graph request looks like this:
var graph = GraphRequest.init(graphPath: "me")
graph.parameters = ["fields": "id, first_name, last_name, middle_name, name, email, picture"]
graph.start({ (response, data) in
print("======GRAPH=====")
print(data)
})
So, I want to be able to take the GraphResponse, make it an Array and assign it to a variable. I am completely stumped by this one.
Hope this Helps
Swift 4.2
func getFbId(){
if(AccessToken.current != nil){
let req = GraphRequest(graphPath: "me", parameters: ["fields": "email,first_name,last_name,gender,picture"], accessToken: AccessToken.current, httpMethod: GraphRequestHTTPMethod(rawValue: "GET")!)
req.start({ (connection, result) in
switch result {
case .failed(let error):
print(error)
case .success(let graphResponse):
if let responseDictionary = graphResponse.dictionaryValue {
print(responseDictionary)
let firstNameFB = responseDictionary["first_name"] as? String
let lastNameFB = responseDictionary["last_name"] as? String
let socialIdFB = responseDictionary["id"] as? String
let genderFB = responseDictionary["gender"] as? String
let pictureUrlFB = responseDictionary["picture"] as? [String:Any]
let photoData = pictureUrlFB!["data"] as? [String:Any]
let photoUrl = photoData!["url"] as? String
print(firstNameFB, lastNameFB, socialIdFB, genderFB, photoUrl)
}
}
})
}
}
The Graph request start completion block has changed to requiring 3 arguments instead of 2.
So you will have something like this (NOTICE THERE ARE NOW 3 ITEMS PASSED IN THE START BLOCK [connection, result, and error]):
let params = ["fields" : "email, first_name, id, picture"]
let graphRequest = GraphRequest(graphPath: "me", parameters: params)
graphRequest.start{
(connection, result, error in
if error == nil {
if let responseDictionary = result as? NSDictionary {
UserProfile.userName = responseDictionary["first_name"] as? String ?? "User"
UserProfile.userID = responseDictionary["id"] as! String
var pictureUrl = ""
if let picture = responseDictionary["picture"] as? NSDictionary, let data = picture["data"] as? NSDictionary, let url = data["url"] as? String {
pictureUrl = url
}
}
}else{
print("error in graph request:", error)
}
To read response from Facebook Graph Request use the below line of codes
let info = data as! [String : AnyObject]
if info["name"] as? String != nil {
self.usernameLbl.text = info["name"] as! String
}
Hope this will help you

Getting user data through Facebook Graph API in Swift 3

Hi to my fellow developers
Just a simple question. How can I get the data of user through Facebook Graph API after login in app?
There's a sample in Facebook Documentation, but its not working.
let permisions = ["public_profile" ,"email" ,"user_birthday"]
let fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
fbLoginManager.logInWithReadPermissions(permisions, fromViewController: vc) { (result, error) -> Void in
if (error == nil) {
if result.isCancelled {
//do error handling for canceled
} else {
let fbLoginResult : FBSDKLoginManagerLoginResult = result
let facebookToken = fbLoginResult.token.tokenString
FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).startWithCompletionHandler({ (connection, result, error) -> Void in
if (error != nil){
// handle error
}
let email = result.valueForKey("email") as? String ?? ""
let firstName = result.valueForKey("first_name") as? String ?? ""
let lastName = result.valueForKey("last_name") as? String ?? ""
// do stuffs with email or first name or last name
})
this is swift version 2.3 but with little modification it will convert to swift 3

Facebook iOS SDK and Swift: how to get user's hometown?

I am working with iOS 9.2 & Swift 2.1 & FBSDKVersion: 4.7.0.
I tried with Graph API Explorer, at that time I am getting the desired output.
The converted code is in Objective-C and I changed it to Swift.
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "/me", parameters: ["fields": "hometown"], HTTPMethod: "GET")
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
if ((error) != nil){
print("Error: \(error)")
}
else{
print("fetched details: \(result)")
})
See below example and add hometown option into "fields" parameter of FBSDKGraphRequest object and also change:
func fetchUserProfile()
{
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"id, email, name, picture.width(480).height(480)"])
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
if ((error) != nil)
{
print("Error took place: \(error)")
}
else
{
print("Print entire fetched result: \(result)")
let id : NSString = result.valueForKey("id") as! String
print("User ID is: \(id)")
if let userName = result.valueForKey("name") as? String
{
self.userFullName.text = userName
}
if let profilePictureObj = result.valueForKey("picture") as? NSDictionary
{
let data = profilePictureObj.valueForKey("data") as! NSDictionary
let pictureUrlString = data.valueForKey("url") as! String
let pictureUrl = NSURL(string: pictureUrlString)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
let imageData = NSData(contentsOfURL: pictureUrl!)
dispatch_async(dispatch_get_main_queue()) {
if let imageData = imageData
{
let userProfileImage = UIImage(data: imageData)
self.userProfileImage.image = userProfileImage
self.userProfileImage.contentMode = UIViewContentMode.ScaleAspectFit
}
}
}
}
}
})
}
Also refer to this link
Fetching user details from Facebook in iOS

FBSDKLog: starting with Graph API v2.4, GET requests for /me/permissions should contain an explicit "fields" parameter

Does anyone know why I am getting this error? I have a fields parameter set. I am new to swift and coding and any help would be appreciated.
let graphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, gender"])
// start the request:
graphRequest.startWithCompletionHandler({
// void in means that it will return nothing upon completion
(connection, result, error) -> Void in
// do an error check
if error != nil {
print(error)
} else if let result = result {
PFUser.currentUser()?["gender"] = result["gender"]
PFUser.currentUser()?["name"] = result["name"]
PFUser.currentUser()?.save()
// use the user's FB id to get their public profile. First make their id a string:
let userId = result["id"] as! String
// next go to the internet and get their photo from FB:
let facebookProfilePictureUrl = "https://graph.facebook.com/" + userId + "/picture?type=large"
There is a way i which you will get the object "me" and after that you can fetch each and every value of that
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: nil)
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
if (error) != nil {
NSLog("Error: \(error)")
ActivityIndicatorWithLabel.shared.hideProgressView()
view.makeToast(message: "We are unable to connect to Facebook. Please try after sometime")
}else{
self.facebookData(result)
}
})
In this result we get all the details of the user
Here is a way to fetch from this
func facebookData(result: AnyObject){
NSLog("Sending Login from facebook call")
var missingFields:[String] = []
userSocialDetailsGlobal.loginType = "facebook"
userSocialDetailsGlobal.socialId = result.valueForKey("id") as! String
userSocialDetailsGlobal.firstName = result.valueForKey("first_name") as! String
userSocialDetailsGlobal.lastName = result.valueForKey("last_name") as! String
userSocialDetailsGlobal.socialToken = FBSDKAccessToken.currentAccessToken().tokenString
}
struct userSocialDetailsGlobal {
static var socialId: String = String()
static var firstName: String = String()
static var lastName: String = String()
static var loginType: String = String()
static var socialToken: String = String()
}

Resources