iOS: fetch Facebook friends with pagination using

2019-08-11 06:56发布

问题:

I am trying to fetch 'taggable_friends' list from Facebook, where there may be more than 1000 taggable friends, so Facebook paginates the results. Here is the method.

-(void)getsFbTaggableFriends:(NSString *)nextCursor dicFBFriends:(NSMutableArray *) dicFriends failure:(void (^) (NSError *error))failureHandler
{
    NSString *qry = @"/me/taggable_friends";
    NSMutableDictionary *parameters;

    if (nextCursor == nil) {
        parameters = nil;
    }
    else {
        parameters = [[NSMutableDictionary alloc] init];
        [parameters setValue:nextCursor forKey:@"next"];
    }


    [FBRequestConnection startWithGraphPath:qry
                                 parameters:parameters
                                 HTTPMethod:@"GET"
                          completionHandler:^(
                                              FBRequestConnection *connection,
                                              id result,
                                              NSError *error
                                              ) {
                              if (error) {
                                  NSLog(@"%@", [error localizedDescription]);

                              }else {
                                  /* handle the result */
                                  NSMutableDictionary *mDicResult = [[NSMutableDictionary alloc]initWithDictionary:result];

                                  for (NSDictionary * fbItem in [mDicResult valueForKey:@"data"])
                                  {
                                      [dicFriends addObject:fbItem];
                                  }
                                  // if 'next' value is found, then call recursively

                                  if ([[mDicResult valueForKey:@"paging"] objectForKey:@"next"] != nil) {

                                      NSString *nextCursor = mDicResult[@"paging"][@"next"];
                                      NSLog(@"next:%@", [nextCursor substringFromIndex:27]);

                                      [self getsFbTaggableFriends:nextCursor dicFBFriends:dicFriends failure:^(NSError *error) {
                                          failureHandler(error);
                                      }];
                                  }
                              }
                          }];
}

Problem: I get first 1000 records in the 'result' object and the value of the 'next' key is passed as the "parameters" parameter for the recursive call. However, the second iteration doesn't paginate & keeps returning the same 1000 records.

I also tried using the nextCursor value as the startWithGraphPath parameter for the second call instead. It resulted in a different response object with keys like og_object, share, id instead of data & paging.

Please help to properly obtain the taggable friends page by page, as long as 'next' value is present in the response object. Thank you.

回答1:

Use the returned next endpoint (Graph path portion, including the cursor) as the new Graph path for the subsequent request, instead putting it as the parameter.



回答2:

I have come across all the answers. Most of the answers are suggesting either URL based pagination or recursively calling function. We can do this from Facebook SDK itself.

      var friendsParams = "taggable_friends"

     // Save the after cursor in your data model
    if let nextPageCursor = user?.friendsNextPages?.after {
        friendsParams += ".limit(10)" + ".after(" + nextPageCursor + ")"
    } else {
        self.user?.friends.removeAll()
    }
    let requiredParams = friendsParams + "{id, name, first_name, last_name, picture.width(200).height(200)}"
    let params = ["fields": requiredParams]
    let _ = FBSDKGraphRequest(graphPath: "me", parameters: params).start { connection, response, error in
        if connection?.urlResponse.statusCode == 200 {
            print("\(response)")
           // Update the UI and next page (after) cursor
        } else {
            print("Not able to fetch \(error)")
        }
    }

You can also find the example project here