這主要是基於我使用試錯法進行的研究,因爲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 –