In Swift how do you parse the result of a fbk graph request? I have a nested dictionary and casting to [String: String] does not work. I have casted to NSDictionary which works for level 1 but anything nested started complaining about optionals and casting. I see from the changeling that FBGraphObject has been deprecated, so what is the correct approach now in SDK 4?
My data looks like
{
data = {
"is_silhouette" = 0;
url = "...";
};
}
I can do
var data = photoRes["data"] as? NSDictionary
to get
Optional({
"is_silhouette" = 0;
url = "...;
})
I'm not sure how to parse that object...
EDIT For now I have it working with
var data = photoRes["data"] as? NSDictionary
var urlStr = data!["url"] as? String
if urlStr != nil {
let url = NSURL(fileURLWithPath: urlStr!)
//my code...
}
But this is a complicated approach especially if the result coming back is highly nested. Is there a better way to go about this?
Create a dictionary :
class ViewController: UIViewController {
var dict : NSDictionary!
}
Fetching the data :
if((FBSDKAccessToken.currentAccessToken()) != nil){
FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).startWithCompletionHandler({ (connection, result, error) -> Void in
if (error == nil){
self.dict = result as NSDictionary
println(self.dict)
NSLog(self.dict.objectForKey("picture")?.objectForKey("data")?.objectForKey("url") as String)
}
})
}
Output should be :
{
email = "ashishkakkad8#gmail.com";
"first_name" = Ashish;
id = 910855688971343;
"last_name" = Kakkad;
name = "Ashish Kakkad";
picture = {
data = {
"is_silhouette" = 0;
url = "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-xfa1/v/t1.0-1/s200x200/22501_915701971820048_9046303472199214595_n.jpg?oh=f3b3564f1450c13332b3067a135cad5d&oe=55C71792&__gda__=1443571904_c4667dcb08d85682edfd77a90ee9c3ab";
};
};
}
2015-05-25 22:12:34.015 SwiftFB[2713:7830] https://fbcdn-profile-a.akamaihd.net/hprofile-ak-xfa1/v/t1.0-1/s200x200/22501_915701971820048_9046303472199214595_n.jpg?oh=f3b3564f1450c13332b3067a135cad5d&oe=55C71792&__gda__=1443571904_c4667dcb08d85682edfd77a90ee9c3ab
This mess worked for me. I am using SWIFT 3.01 and FB Swift SDK
if let responseDictionary = response.dictionaryValue {
print(responseDictionary["name"] ?? "")
let a = responseDictionary["picture"] as! NSDictionary
let b = a["data"] as! NSDictionary
let c = b["url"]
print(c ?? "")
Related
I'm using facebook-api to fetch user's friends. The code is as follows:
let params = ["fields": "id"]
let request = FBSDKGraphRequest(graphPath: "me/friends", parameters: params)
request.startWithCompletionHandler { (connection : FBSDKGraphRequestConnection!, result : AnyObject!, error : NSError!) -> Void in
if error != nil {
let errorMessage = error.localizedDescription
print(errorMessage)
/* Handle error */
}
else if result.isKindOfClass(NSDictionary){
/* handle response */
let defaults = NSUserDefaults.standardUserDefaults()
let resultdict = result as! NSDictionary
let data : NSArray = resultdict.objectForKey("data") as! NSArray
for i in 0..<data.count {
let valueDict : NSDictionary = data[i] as! NSDictionary
let id = valueDict.objectForKey("id") as! String
print("the id value is \(id)")
}
let friends = resultdict.objectForKey("data") as! NSArray
print("Found \(friends.count) friends")
print(friends)
defaults.setObject(friends, forKey: "fb_friends")
defaults.synchronize()
}
}
The resultDict contains:
{
data = (
{
id = 1662200084096651;
}
);
paging = {
cursors = {
after = QVFIUmFsa0JGazI4amNEcFczT0NRQzdiNshusdsDSHFDHFDDSm02UzNudV9ZATS1ESk5iUEQ5T2syNGDSw4yegdxbdf4WGZA3;
before = QVFIUmFsa0JGazI4amNEcFczT0NRQzdiNURGQTgdsgdsHFDSHTRTNU9DSm02UzNudV9ZATS1ESk5iUEQ5T2syNkRjQW8xc1drGgdsGREHRTcXE4WGZA3;
};
};
summary = {
"total_count" = 762;
};
}
The print above prints (for 1 fb friend):
(
{
id = 1020XXXXXX305XXX;
}
)
I want to pass this to my server, so I thought about doing:
var emptyParams = ["":""]
emptyParams["friends"] = (defaults.objectForKey("fb_friends") as! NSArray).componentsJoinedByString(",")
but then instead of params:
friends: 1020XXXXXX305XXX
I have:
"friends": {
id = 10206503694305180;
}
I want to skip the id and send it as an array, because on my server I have:
var friends = req.body.friends;
for(var i=0; i<friends.length; i++) {
console.log(friends[i]);
query = query.or([{ 'fb_friend': friends[i] }]);
}
how should my modify my swift code so that it creates a correct request?
From what I understand of your code, fb_friends have type of [[String:String]] and you want convert it to [String]?
You can use .map to get "id" from the dictionary.
let friends = (defaults.objectForKey("fb_friends") as! NSArray)
.map{$0["id"]!}
.joinWithSeparator(",")
let params = [
"friends": friends
]
This is my code. Help me to fetch work and institute details from my facebook account. Is i am doing something wrong?
if result.token != nil {
let profileReq = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "email, first_name,last_name,id,work,education"])
let connection = FBSDKGraphRequestConnection()
connection.addRequest(profileReq, completionHandler: { (connection, result, error) -> Void in
if error == nil {
print("Graph Request Result: \(result)")
if let email = result.valueForKey("email") as? String {
//For first name
let first_name = result.valueForKey("first_name") as! String
//For last name
let last_name = result.valueForKey("last_name") as! String
//For ID
let fb_id = result.valueForKey("id") as! String
//For Profile Picture
let profile_pic = "http://graph.facebook.com/" + fb_id + "/picture?type=large"
//For work details as Array
let wrkAr = NSMutableArray()
if let workAr = result.objectForKey("work") as? NSArray {
for i in 0..<workAr.count {
let obj = workAr.objectAtIndex(i) as! NSDictionary
var name = ""
if let employer = obj.objectForKey("employer") as? NSDictionary {
name = employer.valueForKey("name") as! String
}
var pos = ""
if let position = obj.objectForKey("position") as? NSDictionary {
pos = position.valueForKey("name") as! String
}
name = name + "_" + pos + "_" + "no"
wrkAr.addObject(name)
}
}
//For Education details as Array
let eduAr = NSMutableArray()
if let educationAr = result.objectForKey("education") as? NSArray {
for i in 0..<educationAr.count {
let obj = educationAr.objectAtIndex(i) as! NSDictionary
var name = ""
if let school = obj.objectForKey("school") as? NSDictionary {
name = school.valueForKey("name") as! String
}
name = name + "_"
eduAr.addObject(name)
}
}
Work and Education details permissions need to be reviewed by Facebook before you can get those details from the user profile. As per the docs:
user_work_history
user_education_history
If your app requests this permission Facebook will have to review how
your app uses it.
Basically you have to log into developers.facebook.com and request those permissions to be reviewed by Facebook for that specific app. Facebook will review your privacy policy and terms of use before giving you their approval. Only after that you will be able to retrieve that information from your users.
I would defensively validate the incoming value though as many people leave that empty on their Facebook profiles. Make sure you are accounting for empty/undefined values for those to 2 fields.
I am trying to get all my taggable_friends profil picture in swift. With my code, I can obtain my taggable_friends' name, but I don't know how I can get their profil picture... Any idea how? Thanks!!!
var fbRequest = FBSDKGraphRequest(graphPath:"/me/taggable_friends", parameters: nil);
fbRequest.startWithCompletionHandler { (connection : FBSDKGraphRequestConnection!, result : AnyObject!, error : NSError!) -> Void in
if error == nil {
var resultdict = result as! NSDictionary
var data : NSArray = resultdict.objectForKey("data") as! NSArray
for i in 0..<data.count {
let valueDict : NSDictionary = data[i] as! NSDictionary
let id = valueDict.objectForKey("id") as! String
let name = valueDict.objectForKey("name") as! String
// let url = valueDict.objectForKey("url") as! String -- is not working
I already saw this topic: How can I retrieve friend's picture through FBRequest in swift but I still don't undersand how to do it...
Not sure if this is the most effective way to do this, but the code works:
func returnUserData()
{
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me/taggable_friends?", parameters: nil)
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
if ((error) != nil)
{
// Process error
println("Error: \(error)")
}
else
{
println("fetched user: \(result)")
var resultdict = result as! NSDictionary
var data : NSArray = resultdict.objectForKey("data") as! NSArray
for i in 0..<data.count {
let valueDict : NSDictionary = data[i] as! NSDictionary
let id = valueDict.objectForKey("id") as! String
let name = valueDict.objectForKey("name") as! String
let pictureDict = valueDict.objectForKey("picture") as! NSDictionary
let pictureData = pictureDict.objectForKey("data") as! NSDictionary
let pictureURL = pictureData.objectForKey("url") as! String
println("Name: \(name) URL: \(pictureURL)")
}
}
})
}
Have a look at
https://developers.facebook.com/docs/graph-api/reference/user-taggable-friend/
The request should be something like this
graphPath:"/me/taggable_friends?fields=id,name,picture"
I am not an expert in programming, but I modified a code to get the user profile picture from Facebook SDK. The problem is I am getting a Question Mark in the image (profilePicture.image). Can anyone tell me what is going on here?
Also, I am not sure what how to call this function to get image in viewController? At present I am directly adding profilePicture.image inside the function.
func getProfPic(fid: String) -> UIImage? {
if (fid != "") {
var imgURLString = "http://graph.facebook.com/" + fid + "/picture?type=large" //type=normal
var imgURL = NSURL(string: imgURLString)
var imageData = NSData(contentsOfURL: imgURL!)
var image = UIImage(data: imageData!)
profilePicture.image = image // Returned image is Question mark
return image
}
return nil
}
Create a dictionary :
class ViewController: UIViewController {
var dict : NSDictionary!
}
Fetching the data :
if((FBSDKAccessToken.currentAccessToken()) != nil){
FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).startWithCompletionHandler({ (connection, result, error) -> Void in
if (error == nil){
self.dict = result as NSDictionary
println(self.dict)
NSLog(self.dict.objectForKey("picture")?.objectForKey("data")?.objectForKey("url") as String)
}
})
}
Output should be :
{
email = "ashishkakkad8#gmail.com";
"first_name" = Ashish;
id = 910855688971343;
"last_name" = Kakkad;
name = "Ashish Kakkad";
picture = {
data = {
"is_silhouette" = 0;
url = "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-xfa1/v/t1.0-1/s200x200/22501_915701971820048_9046303472199214595_n.jpg?oh=f3b3564f1450c13332b3067a135cad5d&oe=55C71792&__gda__=1443571904_c4667dcb08d85682edfd77a90ee9c3ab";
};
};
}
2015-05-25 22:12:34.015 SwiftFB[2713:7830] https://fbcdn-profile-a.akamaihd.net/hprofile-ak-xfa1/v/t1.0-1/s200x200/22501_915701971820048_9046303472199214595_n.jpg?oh=f3b3564f1450c13332b3067a135cad5d&oe=55C71792&__gda__=1443571904_c4667dcb08d85682edfd77a90ee9c3ab
Convert Image from URL
if let url = NSURL(string: "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-xfa1/v/t1.0-1/s200x200/22501_915701971820048_9046303472199214595_n.jpg?oh=f3b3564f1450c13332b3067a135cad5d&oe=55C71792&__gda__=1443571904_c4667dcb08d85682edfd77a90ee9c3ab") {
if let data = NSData(contentsOfURL: url){
yourImageview.image = UIImage(data: data)
}
}
I am trying to fetch albums photo from facebook using FBSDK 4.x, and I get the result as json. Then I try to access its properties like this 'result?["data"]', and it always return nil. See below code:
func fetchAlbum(){
print(FBSDKAccessToken.currentAccessToken())
let graphRequest: FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me?fields=albums", parameters: nil);
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
if let gotError = error{
println(gotError.description);
}
else{
print("fetched data: \(result)")
if let graphData = result["data"] as? [FBSDKShareOpenGraphObject]{
var albums:[AlbumModel] = [AlbumModel]();
for obj:FBSDKShareOpenGraphObject in graphData {
let desc = obj.description;
print(desc);
let name = obj.valueForKey("name") as! String;
print(name);
if(name == "ETC"){
let test="";
}
let id = obj.valueForKey("id") as! String;
var cover = "";
if let existsCoverPhoto : AnyObject = obj.valueForKey("cover_photo"){
let coverLink = existsCoverPhoto as! String;
cover = "/\(coverLink)/photos";
}
//print(coverLink);
let link = "/\(id)/photos";
let model = AlbumModel(name: name, link: link, cover:cover);
albums.append(model);
}
NSNotificationCenter.defaultCenter().postNotificationName("albumNotification", object: nil, userInfo: ["data":albums]);
}else{
print("--------------------------")
}
}
})
}
By this code above could anyone help me?