Reputation: 4107
i have integrated Facebook sdk in Xcode 6 (with swift). During the login i request the public_profile permission:
FBSession.openActiveSessionWithReadPermissions(["public_profile"], allowLoginUI: true, completionHandler: {
...
...
So i request the user's information:
FBRequestConnection.startForMeWithCompletionHandler { (connection, user, error) -> Void in
...
...
Why the user object doesn't contain the profile picture? How can i get the user profile picture? It's not part of the public_profile?
I get the following information:
2015-01-25 01:25:18.858 Test[767:23804] {
"first_name" = xxx;
gender = xxx;
id = xxxxxxxxx;
"last_name" = xxxxxx;
link = "https://www.facebook.com/app_scoped_user_id/xxxxxxxxx/";
locale = "xxxxx";
name = "xxxxxxx xxxxxxx";
timezone = 1;
"updated_time" = "2013-12-21T18:45:29+0000";
verified = 1;
}
P.S: xxx for privacy
Upvotes: 28
Views: 50514
Reputation: 467
Swift 4 approach :-
private func fetchUserData() {
let graphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"id, email, name, picture.width(480).height(480)"])
graphRequest?.start(completionHandler: { (connection, result, error) in
if error != nil {
print("Error",error!.localizedDescription)
}
else{
print(result!)
let field = result! as? [String:Any]
self.userNameLabel.text = field!["name"] as? String
if let imageURL = ((field!["picture"] as? [String: Any])?["data"] as? [String: Any])?["url"] as? String {
print(imageURL)
let url = URL(string: imageURL)
let data = NSData(contentsOf: url!)
let image = UIImage(data: data! as Data)
self.profileImageView.image = image
}
}
})
}
Upvotes: 14
Reputation: 651
For Swift 5
First add the fields that you need
let params = ["fields": "first_name, last_name, email, picture"]
Create the graph request
let graphRequest = GraphRequest(graphPath: "me", parameters: params, tokenString: token.tokenString, version: nil, httpMethod: .get)
graphRequest.start { (connection, result, error) in }
You will get the result in json
{
"first_name": "",
"last_name": "",
"picture": {
"data": {
"height": 50,
"is_silhouette": false,
"url": "",
"width": 50
}
},
"id": ""
}
According to the json response, catch the result
if let error = error {
print("Facebook graph request error: \(error)")
} else {
print("Facebook graph request successful!")
guard let json = result as? NSDictionary else { return }
if let id = json["id"] as? String {
print("\(id)")
}
if let email = json["email"] as? String {
print("\(email)")
}
if let firstName = json["first_name"] as? String {
print("\(firstName)")
}
if let lastName = json["last_name"] as? String {
print("\(lastName)")
}
if let profilePicObj = json["picture"] as? [String:Any] {
if let profilePicData = profilePicObj["data"] as? [String:Any] {
print("\(profilePicData)")
if let profilePic = profilePicData["url"] as? String {
print("\(profilePic)")
}
}
}
}
}
You can also get custom width profile image by sending the required width in the params
let params = ["fields": "first_name, last_name, email, picture.width(480)"]
This is how the whole code would like
if let token = AccessToken.current {
let params = ["fields": "first_name, last_name, email, picture.width(480)"]
let graphRequest = GraphRequest(graphPath: "me", parameters: params,
tokenString: token.tokenString, version: nil, httpMethod: .get)
graphRequest.start { (connection, result, error) in
if let error = error {
print("Facebook graph request error: \(error)")
} else {
print("Facebook graph request successful!")
guard let json = result as? NSDictionary else { return }
if let id = json["id"] as? String {
print("\(id)")
}
if let email = json["email"] as? String {
print("\(email)")
}
if let firstName = json["first_name"] as? String {
print("\(firstName)")
}
if let lastName = json["last_name"] as? String {
print("\(lastName)")
}
if let profilePicObj = json["picture"] as? [String:Any] {
if let profilePicData = profilePicObj["data"] as? [String:Any] {
print("\(profilePicData)")
if let profilePic = profilePicData["url"] as? String {
print("\(profilePic)")
}
}
}
}
}
}
Check out Graph API Explorer for more fields.
Upvotes: 3
Reputation: 563
Thank you @Lyndsey Scott. For Kingfisher, please add enable request http to .plist file.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>http://graph.facebook.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
Then set your user's picture profile to ImageView.
let facebookId = "xxxxxxx"
let facebookProfile: String = "http://graph.facebook.com/\(facebookId)/picture?type=large"
let url: URL = URL(string: facebookProfile)!
myImageView.kf.setImage(with: url)
Upvotes: 0
Reputation: 625
you can use this code For Swift 3.0 to get the user information
func getFbId(){
if(FBSDKAccessToken.current() != nil){
FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id,name , first_name, last_name , email,picture.type(large)"]).start(completionHandler: { (connection, result, error) in
guard let Info = result as? [String: Any] else { return }
if let imageURL = ((Info["picture"] as? [String: Any])?["data"] as? [String: Any])?["url"] as? String {
//Download image from imageURL
}
if(error == nil){
print("result")
}
})
}
}
Upvotes: 0
Reputation: 1482
If you want to get the picture in the same request as the rest of the users information you can do it all in one graph request. It's a little messy but it beats making another request.
A more Swift 3 approach
let request = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, email, picture.type(large)"])
let _ = request?.start(completionHandler: { (connection, result, error) in
guard let userInfo = result as? [String: Any] else { return } //handle the error
//The url is nested 3 layers deep into the result so it's pretty messy
if let imageURL = ((userInfo["picture"] as? [String: Any])?["data"] as? [String: Any])?["url"] as? String {
//Download image from imageURL
}
})
Swift 2
let request = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, email, picture.type(large)"])
request.startWithCompletionHandler({ (connection, result, error) in
let info = result as! NSDictionary
if let imageURL = info.valueForKey("picture")?.valueForKey("data")?.valueForKey("url") as? String {
//Download image from imageURL
}
})
Upvotes: 53
Reputation: 583
For swift this is the simple way for get the url of the photo with and specific size:
let params: [NSObject : AnyObject] = ["redirect": false, "height": 800, "width": 800, "type": "large"]
let pictureRequest = FBSDKGraphRequest(graphPath: "me/picture", parameters: params, HTTPMethod: "GET")
pictureRequest.startWithCompletionHandler({
(connection, result, error: NSError!) -> Void in
if error == nil {
print("\(result)")
let dictionary = result as? NSDictionary
let data = dictionary?.objectForKey("data")
let urlPic = (data?.objectForKey("url"))! as! String
print(urlPic)
} else {
print("\(error)")
}
})
}
Upvotes: 4
Reputation: 1025
if you want get bigger picture , just replace "type = large" to width=XX&height=XX
but the biggest picture you can get is original picture
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
initWithGraphPath:@"me/picture?width=1080&height=1080&redirect=false"
parameters:nil
HTTPMethod:@"GET"];
[request startWithCompletionHandler:^(
FBSDKGraphRequestConnection *connection,
id result,
NSError *error) {
if (!error)
{
NSLog(@"result = %@",result);
NSDictionary *dictionary = (NSDictionary *)result;
NSDictionary *data = [dictionary objectForKey:@"data"];
NSString *photoUrl = (NSString *)[data objectForKey:@"url"];
}
else
{
NSLog(@"result = %@",[error description]); }
}];
Upvotes: 7
Reputation: 613
With Facebook SDK 4.0, you can use:
Swift:
let pictureRequest = FBSDKGraphRequest(graphPath: "me/picture?type=large&redirect=false", parameters: nil)
pictureRequest.startWithCompletionHandler({
(connection, result, error: NSError!) -> Void in
if error == nil {
println("\(result)")
} else {
println("\(error)")
}
})
Objective-C:
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
initWithGraphPath:[NSString stringWithFormat:@"me/picture?type=large&redirect=false"]
parameters:nil
HTTPMethod:@"GET"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection,
id result,
NSError *error) {
if (!error){
NSLog(@"result: %@",result);}
else {
NSLog(@"result: %@",[error description]);
}}];
Upvotes: 25
Reputation: 9975
@Brandon Gao solution gave me a 200X200 thumbnail...
To get a bigger size I used FBSDKProfile
to get a path with size, that is also more modular and not hard-coded (although I did have to type in the graph.facebook.com part...)
let size = CGSize(width: 1080, height: 1080)
let path = FBSDKProfile.currentProfile().imagePathForPictureMode(.Normal, size: size)
let url = "https://graph.facebook.com/\(path)"
Alamofire.request(.GET, url, parameters: nil, encoding: ParameterEncoding.URL).response {
(request, response, data, error) -> Void in
if let imageData = data as? NSData,
let image = UIImage(data: imageData) {
self.buttonImage.setImage(image, forState: .Normal)
}
}
Somehow I didn't get a 1080X1080 image though, FB gave me a 1117X1117... :\
Upvotes: 4
Reputation: 37300
The profile picture is in fact public and you can simply by adding the user id to Facebook's designated profile picture url address, ex:
var userID = user["id"] as NSString
var facebookProfileUrl = "http://graph.facebook.com/\(userID)/picture?type=large"
This particular url address should return the "large" version of the user's profile picture, but several more photo options are available in the docs.
Upvotes: 64