这主要是基于我使用试错法进行的研究,因为Facebook的文档根本没有帮助。我很高兴地知道这样做的更好的方法:)
然后,我们可以使用从图形管理器的模板代码的调用:
NSString *yourCall = @”YourGraphExplorerCall”;
FBRequest *fbRequest = [FBRequest requestWithGraphPath:yourCall parameters:nil HTTPMethod:@"GET"];
[fbRequest startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSDictionary *jsonResponse = (NSDictionary *) result;
// Do your stuff with the JSON response
}
else {
failureHandler(error);
}
}];
Facebook的图形接受和JSON回复。
获取用户的相册和照片 - 分页
的问题,一旦用户登录他们的会议通过Facebook的API在幕后进行处理,所以没有必要关心的是,我们可以只执行我们想要的具体请求。
要获得专辑数据用户,把这个字符串转换成图形浏览器:
me?fields=albums.fields(count,id)
这会问FB中的每张专辑及其ID照片的数量。请注意,JSON回复的第一级包含用户的ID以及包含“数据”阵列的“albums”数组 - 这是我们感兴趣的实际相册的阵列。
拥有我们可以探索他们的照片,每个相册的ID。下面的通话将获得链接到每一张专辑的图片来源及微型:
<album_id>?fields=photos.fields(source,picture)
哪里是你想获得其照片的相册的实际ID。
最初的问题是,由于专辑中可能有很多照片,试图让它们一次性完成可能是一个糟糕的主意 - 这就是为什么Facebook将这些调用引入分页的原因。这意味着您可以设置一次调用中获得的照片数据的数量限制,然后使用“光标”指定想要获取的下一批/上一批批次,并将所述光标放入每次通话。 主要问题是处理这样的分页数据。如果我们查看之前调用中返回的数据,我们可以看到“分页”部分包含“游标”(包含“之前”和“之后”)和“下一个”。 “下一个”键是一个链接,它看起来与我们在图形浏览器中使用的调用字符串非常相似 - 它以“之后”光标结束;我们能想到的,那么,它可能仅仅是“后”光标追加到我们的电话串
<album_id>?fields=photos.fields(source,picture)&after=<after_cursor>
和饲料是进入图形浏览器。不!出于某种原因,这不会按预期工作 - 它仍然指引我们到第一批,而不是下一批。 但是,“下一个”链接仍然有效,因此可以使用它的一部分而不是我们对图形浏览器的调用。因此,调用来获取照片:
<album_id>?fields=photos.fields(source,picture)
变为:
<album_id>/photos?fields=source%2Cpicture&limit=25
此外,它仍然有效=后&被追加后:
<album_id>/photos?fields=source%2Cpicture&limit=25&after=
因此它很容易简单地得到在批次的每个调用中的“next”的值并将其附加到上一个字符串以用于下一个调用。
这里的代码的最终版本的片段:
NSString *const FACEBOOK_GRAPH_LIST_ALBUMS = @"me?fields=albums.fields(count,id,name)";
NSString *const FACEBOOK_GRAPH_LIST_ALBUM_PHOTOS = @"/photos?fields=source%2Cpicture&limit=25&after=";
NSArray *currentUsersFacebookAlbums;
- (void) getUserPhotosWithSuccess:(void (^)())successHandler failure:(void (^) (NSError *error))failureHandler {
FBRequest *fbRequest = [FBRequest requestWithGraphPath:FACEBOOK_GRAPH_LIST_ALBUMS parameters:nil HTTPMethod:@"GET"];
[fbRequest startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSDictionary *jsonResponse = (NSDictionary *) result;
currentUsersFacebookAlbums = (NSArray *) [[jsonResponse valueForKey:@"albums"] valueForKey:@"data"];
for (NSDictionary *currentAlbum in currentUsersFacebookAlbums) {
NSString *albumId = [currentAlbum valueForKey:@"id"];
[self getCurrentUserFacebookPhotosWithAlbum:albumId afterCursor:nil failure:^(NSError *error) {
failureHandler(error);
}];
}
successHandler();
}
else {
failureHandler(error);
}
}];
}
- (void) getCurrentUserFacebookPhotosWithAlbum:(NSString *) albumId afterCursor:(NSString *) afterCursor failure:(void (^) (NSError *error))failureHandler {
if (afterCursor == nil) {
afterCursor = @"";
}
NSString *fbGraphCall = [NSString stringWithFormat:@"%@%@%@", albumId, FACEBOOK_GRAPH_LIST_ALBUM_PHOTOS, afterCursor];
FBRequest *fbRequest = [FBRequest requestWithGraphPath:fbGraphCall parameters:nil HTTPMethod:@"GET"];
[fbRequest startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSDictionary *jsonResponse = (NSDictionary *) result;
NSArray *currentPhotoBatch = (NSArray *) [jsonResponse valueForKey:@"data"];
// Go through the currently obtained batch and add them to the returned mutable array
for (NSDictionary *currentPhoto in currentPhotoBatch) {
[[CurrentUserDataHandler sharedInstance] addFacebookPhoto:currentPhoto];
}
// If there's a "next" link in the response, recur the method on the next batch...
if ([[jsonResponse valueForKey:@"paging"] objectForKey:@"next"] != nil) {
// ...by appending the "after" cursor to the call
NSString *afterCursor = [[[jsonResponse valueForKey:@"paging"] valueForKey:@"cursors"] valueForKey:@"after"];
[self getCurrentUserFacebookPhotosWithAlbum:albumId afterCursor:afterCursor failure:^(NSError *error) {
failureHandler(error);
}];
}
if ([[jsonResponse valueForKey:@"paging"] objectForKey:@"next"] != nil && [self isLastAlbum:albumId]) {
[[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_FACEBOOK_PHOTOS object:nil];
}
}
else {
failureHandler(error);
}
}];
}
- (bool) isLastAlbum:(NSString *) albumId {
for (NSDictionary *albumData in currentUsersFacebookAlbums) {
if ([albumId isEqualToString:[albumData valueForKey:@"id"]] && [currentUsersFacebookAlbums indexOfObject:albumData] == [currentUsersFacebookAlbums count] - 1) {
return YES;
}
}
return NO;
}
见http://stackoverflow.com/questions/29909534/ios-fetch-facebook-friends-with-pagination-using-next/43365360#43365360 –