我试图得到我的朋友的名字和id与图形API v2.0,但数据返回空:
{
"data": [
]
}
当我使用v1.0时,以下请求一切正常:
FBRequest* friendsRequest = [FBRequest requestForMyFriends];
[friendsRequest startWithCompletionHandler: ^(FBRequestConnection *connection,
NSDictionary* result,
NSError *error) {
NSArray* friends = [result objectForKey:@"data"];
NSLog(@"Found: %i friends", friends.count);
for (NSDictionary<FBGraphUser>* friend in friends) {
NSLog(@"I have a friend named %@ with id %@", friend.name, friend.id);
}
}];
但是现在我找不到朋友了!
正如Simon提到的,这在新的Facebook API中是不可能的。从技术上讲,你可以通过浏览器自动化来实现。
this is against Facebook policy, so depending on the country where you live, this may not be legal
you'll have to use your credentials / ask user for credentials and possibly store them (storing passwords even symmetrically encrypted is not a good idea)
when Facebook changes their API, you'll have to update the browser automation code as well (if you can't force updates of your application, you should put browser automation piece out as a webservice)
this is bypassing the OAuth concept
on the other hand, my feeling is that I'm owning my data including the list of my friends and Facebook shouldn't restrict me from accessing those via the API
使用WatiN的示例实现:
class FacebookUser
{
public string Name { get; set; }
public long Id { get; set; }
}
public IList<FacebookUser> GetFacebookFriends(string email, string password, int? maxTimeoutInMilliseconds)
{
var users = new List<FacebookUser>();
Settings.Instance.MakeNewIeInstanceVisible = false;
using (var browser = new IE("https://www.facebook.com"))
{
try
{
browser.TextField(Find.ByName("email")).Value = email;
browser.TextField(Find.ByName("pass")).Value = password;
browser.Form(Find.ById("login_form")).Submit();
browser.WaitForComplete();
}
catch (ElementNotFoundException)
{
// We're already logged in
}
browser.GoTo("https://www.facebook.com/friends");
var watch = new Stopwatch();
watch.Start();
Link previousLastLink = null;
while (maxTimeoutInMilliseconds.HasValue && watch.Elapsed.TotalMilliseconds < maxTimeoutInMilliseconds.Value)
{
var lastLink = browser.Links.Where(l => l.GetAttributeValue("data-hovercard") != null
&& l.GetAttributeValue("data-hovercard").Contains("user.php")
&& l.Text != null
).LastOrDefault();
if (lastLink == null || previousLastLink == lastLink)
{
break;
}
var ieElement = lastLink.NativeElement as IEElement;
if (ieElement != null)
{
var htmlElement = ieElement.AsHtmlElement;
htmlElement.scrollIntoView();
browser.WaitForComplete();
}
previousLastLink = lastLink;
}
var links = browser.Links.Where(l => l.GetAttributeValue("data-hovercard") != null
&& l.GetAttributeValue("data-hovercard").Contains("user.php")
&& l.Text != null
).ToList();
var idRegex = new Regex("id=(?<id>([0-9]+))");
foreach (var link in links)
{
string hovercard = link.GetAttributeValue("data-hovercard");
var match = idRegex.Match(hovercard);
long id = 0;
if (match.Success)
{
id = long.Parse(match.Groups["id"].Value);
}
users.Add(new FacebookUser
{
Name = link.Text,
Id = id
});
}
}
return users;
}
该方法的原型实现(使用c# /WatiN)参见https://github.com/svejdo1/ShadowApi。它还允许动态更新Facebook连接器,检索您的联系人列表。
在Swift 4.2和Xcode 10.1中:
如果你想从Facebook获得好友列表,你需要在Facebook上提交应用进行审查。请参阅一些登录权限:
登录权限
以下是两个步骤:
1)首先你的应用状态必须在Live中
2)从Facebook获得所需的权限。
1)启用我们的应用状态
进入应用程序页面,选择你的应用程序
https://developers.facebook.com/apps/
在“仪表板”的右上方选择状态。
提交隐私政策URL
选择类别
现在我们的应用程序处于Live状态。
完成了第一步。
2)提交应用进行审核:
首先发送所需的请求。
例如:user_friends, user_videos, user_posts等。
其次,转到当前请求页面
例如:user_events
提交所有详细资料
像这样提交所有请求(user_friends, user_events, user_videos, user_posts等)。
最后提交应用进行审查。
如果你的评论被Facebook接受,你现在就有资格阅读联系人等等。
在Facebook SDK Graph API v2.0或以上版本中,您必须在登录Facebook时向每个用户请求user_friends权限,因为默认情况下,user_friends不再包含在每次登录中;我们必须加上这个。
每个用户必须授予user_friends权限,以便出现在对/me/friends的响应中。
let fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
fbLoginManager.loginBehavior = FBSDKLoginBehavior.web
fbLoginManager.logIn(withReadPermissions: ["email","user_friends","public_profile"], from: self) { (result, error) in
if (error == nil) {
let fbloginresult : FBSDKLoginManagerLoginResult = result!
if fbloginresult.grantedPermissions != nil {
if (fbloginresult.grantedPermissions.contains("email")) {
// Do the stuff
}
else {
}
}
else {
}
}
}
所以在Facebook登录时,它会提示一个包含所有权限的屏幕:
如果用户按下继续按钮,权限将被设置。当您使用Graph API访问好友列表时,您的好友将如上所述登录应用程序
if ((FBSDKAccessToken.current()) != nil) {
FBSDKGraphRequest(graphPath: "/me/friends", parameters: ["fields" : "id,name"]).start(completionHandler: { (connection, result, error) -> Void in
if (error == nil) {
print(result!)
}
})
}
输出将包含在通过Facebook登录应用程序时授予user_friends权限的用户。
{
data = (
{
id = xxxxxxxxxx;
name = "xxxxxxxx";
}
);
paging = {
cursors = {
after = xxxxxx;
before = xxxxxxx;
};
};
summary = {
"total_count" = 8;
};
}
在2.0版的Graph API中,调用/me/friends会返回此人同样使用该应用程序的朋友。
此外,在v2.0中,必须向每个用户请求user_friends权限。默认情况下,User_friends不再包含在每次登录中。每个用户必须授予user_friends权限,以便出现在对/me/friends的响应中。有关更详细的信息,请参阅Facebook升级指南,或查看下面的摘要。
如果你想访问未使用应用程序的好友列表,有两个选项:
If you want to let your people tag their friends in stories that they publish to Facebook using your App, you can use the /me/taggable_friends API. Use of this endpoint requires review by Facebook and should only be used for the case where you're rendering a list of friends in order to let the user tag them in a post.
If your App is a Game AND your Game supports Facebook Canvas, you can use the /me/invitable_friends endpoint in order to render a custom invite dialog, then pass the tokens returned by this API to the standard Requests Dialog.
在其他情况下,应用程序不再能够检索用户的朋友的完整列表(只有那些特别授权你的应用程序使用user_friends权限的朋友)。Facebook已经证实这是“故意的”。
对于想要允许人们邀请朋友使用应用程序的应用程序,你仍然可以使用Web上的发送对话框或iOS和Android上的新消息对话框。
更新:Facebook发布了一个关于这些变化的常见问题解答:https://developers.facebook.com/docs/apps/faq,其中解释了所有可供开发者邀请好友等的选项。