简体   繁体   English

Facebook iOS SDK 和 swift:如何获取用户的个人资料图片

[英]Facebook iOS SDK and swift: how get user's profile picture

i have integrated Facebook sdk in Xcode 6 (with swift).我已经在 Xcode 6(快速)中集成了 Facebook sdk。 During the login i request the public_profile permission:在登录期间,我请求 public_profile 权限:

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?它不是 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;
}

PS: xxx for privacy PS:xxx隐私

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:个人资料图片实际上是公开的,您只需将用户 ID 添加到 Facebook 指定的个人资料图片网址,例如:

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 .这个特定的 url 地址应该返回用户个人资料图片的“大”版本,但文档中提供了更多的照片选项。

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 approachSwift 3 的方法

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斯威夫特 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
    }
})

With Facebook SDK 4.0, you can use:使用 Facebook SDK 4.0,您可以使用:

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:目标-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]);
     }}];

Swift 4 approach :-斯威夫特 4 方法:-

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
            }
        }
    })
}

if you want get bigger picture , just replace "type = large" to width=XX&height=XX如果您想获得更大的图片,只需将“type = large”替换为 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]); } 
}];

@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...) @Brandon Gao 解决方案给了我一个 200X200 的缩略图......为了获得更大的尺寸,我使用了FBSDKProfile来获得一个具有尺寸的路径,这也更加模块化而不是硬编码(尽管我确实必须输入graph.facebook。 COM部分...)

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... :\\不知怎的,我没有得到 1080X1080 的图像,FB 给了我一个 1117X1117...:\\

For swift this is the simple way for get the url of the photo with and specific size:对于 swift,这是获取具有特定大小的照片 url 的简单方法:

    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)")
        }
    })

}

For Swift 5对于 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您将在 json 中得到结果

{
  "first_name": "",
  "last_name": "",
  "picture": {
    "data": {
      "height": 50,
      "is_silhouette": false,
      "url": "",
      "width": 50
    }
  },
  "id": ""
}

According to the json response, catch the result根据json响应,捕获结果

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您还可以通过在 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.查看 Graph API Explorer 了解更多字段。

you can use this code For Swift 3.0 to get the user information您可以使用此代码 For Swift 3.0 来获取用户信息

  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")
}
})
}
}

Thank you @Lyndsey Scott.谢谢@Lyndsey Scott。 For Kingfisher, please add enable request http to .plist file.对于 Kingfisher,请将启用请求 http 添加到 .plist 文件。

<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.然后将用户的图片配置文件设置为 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM