2

我正在研究iOS應用的一項功能,該功能將使其用戶能夠從他們的Facebook圖庫中選擇一張照片。處理Facebook用戶照片的分頁

我已經有了最初的請求來讓照片工作 - 它確實會返回少量的照片以及指向下一批和上一批的鏈接。我的問題是我不知道處理這個分頁的正確方法是什麼;我花了很長時間嘗試谷歌它或在Facebook的文檔中找到答案,但它只是垃圾(即沒有任何幫助)。

你可以看看應該處理這個請求的方法,並向我解釋如何將其餘照片添加到用戶的FacebookPhotos可變數組?

NSMutableArray *usersFacebookPhotos; 

- (void) getUserPhotoAlbumsWithSuccess:(void (^) (bool))successHandler failure:(void (^) (NSError *error))failureHandler { 

    usersFacebookPhotos = (NSMutableArray *)[[NSArray alloc] init]; 

    FBRequest *fbRequest = [FBRequest requestWithGraphPath:@"me?fields=photos.fields(picture,source)" parameters:nil HTTPMethod:@"GET"]; 
    [fbRequest startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) { 

     if (!error) { 

      NSLog(@"got the initial batch"); 
      // process the next batch of photos here 
     } 
     else { 

      NSLog(@"error: %@", error); 
     } 
    }]; 
} 

哦,是的 - 我嘗試使用grabKit但決定不花更多的時間試圖將其設置 - 我也跟着信中的說明,但它仍然會引發錯誤。

回答

0

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

見http://stackoverflow.com/questions/29909534/ios-fetch-facebook-friends-with-pagination-using-next/43365360#43365360 –

0

對於Facebook的分頁我會建議使用蘋果機類的

使用nextPageURL變量緩存從JSON響應下一個URL並指定在下次API請求的URL字符串,如果nextPageURL不是零和使用下面的代碼:

if (self.nextPageURL) { 
    // urlString is the first time formulated url string 
    urlString = self.nextPageURL; 
} 
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]]; 
[NSURLConnection sendAsynchronousRequest:request queue:networkQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { 
    if (error) { 
     DDLogVerbose(@"FACEBOOK:Connection error occured: %@",error.description); 
    }else{ 
     isRequestProcessing = NO; 
     NSDictionary *resultData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil]; 
     DDLogVerbose(@"parsed data is %@",resultData); 
     self.nextPageURL = resultData[@"paging"][@"next"]; 

     // do your customisation of resultData here. 
     } 
    } 
}]; 
3

我用遞歸函數調用爲了解決這個問題,我設置了一個10的下限來測試功能。

-(void)facebookCall { 
    [self getFBFriends:@"me/friends?fields=name,picture.type(large)&limit=10"]; 
} 

-(void)getFBFriends:(NSString*)url { 
    [FBRequestConnection startWithGraphPath:url 
         completionHandler:^(FBRequestConnection *connection, id result, NSError *error) { 
          if (!error) { 
           [self parseFBResult:result]; 

           NSDictionary *paging = [result objectForKey:@"paging"]; 
           NSString *next = [paging objectForKey:@"next"]; 

           // skip the beginning of the url https://graph.facebook.com/ 
           // there's probably a more elegant way of doing this 

           NSLog(@"next:%@", [next substringFromIndex:27]); 

           [self getFBFriends:[next substringFromIndex:27]]; 

          } else { 
           NSLog(@"An error occurred getting friends: %@", [error localizedDescription]); 
          } 
         }]; 
} 

-(void)parseFBResult:(id)result { 

    NSLog(@"My friends: %@", result); 

    NSArray *data = [result objectForKey:@"data"]; 
    int j = 0; 
    for(NSDictionary *friend in data){ 
     NSDictionary *picture = [friend objectForKey:@"picture"]; 
     NSDictionary *picData = [picture objectForKey:@"data"]; 
     NSLog(@"User:%@, picture URL: %@", [friend objectForKey:@"name"], [picData objectForKey:@"url"]); 
     j++; 
    } 
    NSLog(@"No of friends is: %d", j); 

} 
+0

看到更播放由規則在這裏回答:http://stackoverflow.com/a/12223324/850608 – Elsint