Facebook iOS SDK 和 swift:如何获取用户的头像

Posted

技术标签:

【中文标题】Facebook iOS SDK 和 swift:如何获取用户的头像【英文标题】:Facebook iOS SDK and swift: how get user's profile picture 【发布时间】:2015-01-25 00:41:58 【问题描述】:

我已经在 Xcode 6 中集成了 Facebook sdk(使用 swift)。 在登录期间,我请求 public_profile 权限:

FBSession.openActiveSessionWithReadPermissions(["public_profile"], allowLoginUI: true, completionHandler: 
...
...

所以我请求用户的信息:

FBRequestConnection.startForMeWithCompletionHandler  (connection, user, error) -> Void in
...
...

为什么用户对象不包含头像?如何获取用户个人资料图片?它不是 public_profile 的一部分?

我得到以下信息:

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 保护隐私

【问题讨论】:

对于 xcode 8.3.3 和 swift-4(beta) 使用:***.com/a/45462114/1168602 【参考方案1】:

头像实际上是公开的,您只需将用户ID添加到Facebook指定的头像url地址即可,例如:

var userID = user["id"] as NSString     
var facebookProfileUrl = "http://graph.facebook.com/\(userID)/picture?type=large"

这个特定的 url 地址应该返回用户个人资料图片的“大”版本,但还有几个可用的照片选项in the docs。

【讨论】:

嗨。晚了几个月,但是,我可以问一下……文档中的哪些照片选项可用?我似乎在 Graph API 2.4 上找不到它们:developers.facebook.com/docs/graph-api/reference/v2.4/user/… @AlejandroIván 我链接到的文档页面现在说“本文档指的是 Graph API 的过时版本。请使用最新版本。Graph API Version v2.2”,所以这些照片选项可能是在 2.4 中不再可用。 我就是这么想的。令人惊讶的是,即使没有“正式”记录,使用type=large 或其他(我正在使用width=150&height=150)似乎也可以正常工作。谢谢! 这个答案为我指明了正确的方向。所以,为了完成我的功能,我添加了这个: if let data = NSData(contentsOfURL: facebookProfileUrl!) imageProfile.image = UIImage(data: data) 谢谢@LyndseyScott 感谢@LyndseyScott - 对于将来使用此功能的人,不要忘记使用“https”而不是“http”来消除 Apple 安全投诉 :)【参考方案2】:

如果您想在与其他用户信息相同的请求中获取图片,您可以在一个图形请求中完成所有操作。这有点乱,但它比提出另一个请求要好。

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

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

【讨论】:

【参考方案3】:

使用 Facebook SDK 4.0,您可以使用:

斯威夫特:

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

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

【讨论】:

这为我指明了获取其他用户信息的正确方向,请参阅:***.com/questions/31314124/… id/picture?type=normal&redirect=false 对我很有用,谢谢。 redirect=false 创造了奇迹【参考方案4】:

Swift 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-else 语句是错误的。 if error == nil 应该是这样,您也应该更改代码。 @emresancaktar 它是正确的。 if error != nil 会打印错误。【参考方案5】:

如果你想获得更大的图片,只需将“type = large”替换为width=XX&height=XX

但你能得到的最大的图片是原图

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]);  
];

【讨论】:

【参考方案6】:

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

虽然我没有得到 1080X1080 的图像,但 FB 给了我一个 1117X1117...:\

【讨论】:

不错的解决方案,但我需要先加载配置文件:FBSDKProfile.loadCurrentProfileWithCompletion【参考方案7】:

对于 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)")
        
    )


【讨论】:

【参考方案8】:

对于 Swift 5

首先添加你需要的字段

let params = ["fields": "first_name, last_name, email, picture"]

创建图表请求

let graphRequest = GraphRequest(graphPath: "me", parameters: params, tokenString: token.tokenString, version: nil, httpMethod: .get)
graphRequest.start  (connection, result, error) in 

你会得到json格式的结果


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

根据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)")
                    
                
            
        
    

您还可以通过在参数中发送所需的宽度来获取自定义宽度的配置文件图像

let params = ["fields": "first_name, last_name, email, picture.width(480)"]

这就是整个代码的样子

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

查看 Graph API Explorer 了解更多字段。

【讨论】:

【参考方案9】:

您可以使用此代码 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")

)


【讨论】:

【参考方案10】:

谢谢@Lyndsey Scott。 对于 Kingfisher,请在 .plist 文件中添加启用请求 http。

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

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

【讨论】:

以上是关于Facebook iOS SDK 和 swift:如何获取用户的头像的主要内容,如果未能解决你的问题,请参考以下文章

使用 SWIFT 在 iOS SDK for Facebook 上使用 FBSDKGraphRequest

无法从 Swift 中的 Facebook iOS SDK 捕获城市和国家/地区值

带有iOS swift的Facebook SDK未在UIWebView中打开[重复]

我如何从 facebook 公开资料 Facebook IOS Swift SDK 中获取性别

iOS 8 中的 Facebook SDK 与 Swift/Xcode beta 5 返回 accessToken 但更新后没有用户 ID

ios facebook swift sdk 共享对话框永远不会返回成功