Это в основном основано на моих исследованиях, проведенных с использованием метода проб и ошибок, поскольку документация от Facebook не была вообще полезной. Я рад узнать о лучшем способе сделать это :)
Затем мы можем использовать вызовы из Graph Explorer, в коде шаблона:
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 Graph принимает и ответы в формате JSON.
Получение альбомов и фотографий пользователя - проблема пагинацией
После того, как пользователь вошел в их сессии обрабатывается за кулисами в API Facebook, так что нет необходимости беспокоиться о том, что мы можем просто выполнить которые мы хотим.
Чтобы получить данные альбомы для пользователя, поместите эту строку в Graph Проводник:
me?fields=albums.fields(count,id)
Это задаст Fb для подсчета фотографий в каждом альбоме и их идентификаторы. Обратите внимание, что 1-й уровень ответа JSON содержит идентификатор пользователя, а также массив «альбомов», который содержит массив данных. Это массив фактических альбомов, которые нас интересуют.
Имея Идентификаторы каждого альбома мы можем исследовать их фотографии. Ниже вызов будет получать ссылки на источник фото каждого альбома и его миниатюры:
<album_id>?fields=photos.fields(source,picture)
где фактический идентификатор альбома, чьи фотографии вы хотите получить.
Первоначальная проблема заключается в том, что, поскольку в альбоме может быть много фотографий, попытка получить их за один раз - это, вероятно, плохая идея - вот почему разработчики Facebook ввели эти разбиения на страницы. Это означает, что вы можете установить лимит количества данных фотографий, которые вы получаете за один вызов, и затем используете «курсор» для следующих/предыдущих партий, которые вы хотите получить, с указанными курсорами, предоставленными вам в каждый звонок. Основная проблема связана с такими разбитыми на страницы данными. Если мы посмотрим на данные, возвращенные в нашем предыдущем вызове, мы увидим, что существует раздел «подкачки» с «курсорами» (который содержит «до» и «после») и «следующий». Ключ «next» - это ссылка, которая очень похожа на нашу строку вызовов, используемую в Graph Explorer, и заканчивается курсором «после»; мы могли бы подумать, то, что можно просто добавить «после» курсор нашего вызова строки
<album_id>?fields=photos.fields(source,picture)&after=<after_cursor>
и корма, что в Graph Explorer. Неа! По какой-то причине это не сработает, как ожидалось - оно по-прежнему направляет нас к первой партии, а не к следующей. Тем не менее, «следующая» ссылка все еще работает, поэтому можно использовать ее части вместо вызова, который мы сделали в Graph Explorer. Таким образом, вызов, чтобы получить фотографии:
<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 –