Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Facebook Graph API Use "next" or "previous" Url for Pagination Using SDK

I am not quite sure the best approach or proper SDK call to make when wanting to utilize the "next" or "previous" URLs returned by the graph api when results are paginated. I've reviewed the documentation for FBRequest and FBRequestConnection but there weren't any methods or calls that jumped out at me as the obvious solution to my problem. Anyone have one or can make a suggestion that would point me in the right direction?

like image 836
TWright Avatar asked Dec 01 '22 01:12

TWright


2 Answers

Nikolay's solution is perfect. Here is its Swift Version

func makeFBRequestToPath(aPath:String, withParameters:Dictionary<String, AnyObject>, success successBlock: (Array<AnyObject>?) -> (), failure failureBlock: (NSError?) -> ())
{
    //create array to store results of multiple requests
    let recievedDataStorage:Array<AnyObject> = Array<AnyObject>()

    //run requests with array to store results in
    p_requestFromPath(aPath, parameters: withParameters, storage: recievedDataStorage, success: successBlock, failure: failureBlock)
}


func p_requestFromPath(path:String, parameters params:Dictionary<String, AnyObject>, var storage friends:Array<AnyObject>, success successBlock: (Array<AnyObject>?) -> (), failure failureBlock: (NSError?) -> ())
{
    //create requests with needed parameters


    let req = FBSDKGraphRequest(graphPath: path, parameters: params, tokenString: FBSDKAccessToken.currentAccessToken().tokenString, version: nil, HTTPMethod: "GET")
    req.startWithCompletionHandler({ (connection, result, error : NSError!) -> Void in
        if(error == nil)
        {
            print("result \(result)")

            let result:Dictionary<String, AnyObject> = result as! Dictionary<String, AnyObject>


            //add recieved data to array
            friends.append(result["data"]!)
            //then get parameters of link for the next page of data

            let nextCursor:String? = result["paging"]!["next"]! as? String

            if let _ = nextCursor
            {
                let paramsOfNextPage:Dictionary = FBSDKUtility.dictionaryWithQueryString(nextCursor!)

                if paramsOfNextPage.keys.count > 0
                {
                    self.p_requestFromPath(path, parameters: paramsOfNextPage as! Dictionary<String, AnyObject>, storage: friends, success:successBlock, failure: failureBlock)
                    //just exit out of the method body if next link was found
                    return
                }
            }

            successBlock(friends)
        }
        else
        {
            //if error pass it in a failure block and exit out of method
            print("error \(error)")
            failureBlock(error)
        }
    })
}


func getFBFriendsList()
{
    //For example retrieve friends list with limit of retrieving data items per request equal to 5
    let anyParametersYouWant:Dictionary = ["limit":2]
    makeFBRequestToPath("/me/friends/", withParameters: anyParametersYouWant, success: { (results:Array<AnyObject>?) -> () in
        print("Found friends are: \(results)")
        }) { (error:NSError?) -> () in
            print("Oops! Something went wrong \(error)")
    }
}
like image 79
msmq Avatar answered Dec 06 '22 08:12

msmq


To get the next link you have to make this:

I solved it this in this way:

add headers

#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKLoginKit/FBSDKLoginKit.h>

and code

//use this general method with any parameters you want. All requests will be handled correctly

- (void)makeFBRequestToPath:(NSString *)aPath withParameters:(NSDictionary *)parameters success:(void (^)(NSArray *))success failure:(void (^)(NSError *))failure
{
    //create array to store results of multiple requests
    NSMutableArray *recievedDataStorage = [NSMutableArray new];

    //run requests with array to store results in
    [self p_requestFriendsFromPath:aPath
                        parameters:parameters
                           storage:recievedDataStorage
                            succes:success
                           failure:failure];
}




 - (void)p_requestFromPath:(NSString *)path parameters:(NSDictionary *)params storage:(NSMutableArray *)friends succes:(void (^)(NSArray *))success failure:(void (^)(NSError *))failure
{
    //create requests with needed parameters
        FBSDKGraphRequest *fbRequest = [[FBSDKGraphRequest alloc]initWithGraphPath:path
                                                                         parameters:params
                                                                         HTTPMethod:nil];

    //then make a Facebook connection
    FBSDKGraphRequestConnection *connection = [FBSDKGraphRequestConnection new];
    [connection addRequest:fbRequest
         completionHandler:^(FBSDKGraphRequestConnection *connection, NSDictionary*result, NSError *error) {

             //if error pass it in a failure block and exit out of method
             if (error){
                 if(failure){
                    failure(error);
                 }
                 return ;
             }
             //add recieved data to array
             [friends addObjectsFromArray:result[@"data"];
             //then get parameters of link for the next page of data
             NSDictionary *paramsOfNextPage = [FBSDKUtility dictionaryWithQueryString:result[@"paging"][@"next"]];
             if (paramsOfNextPage.allKeys.count > 0){
                 [self p_requestFromPath:path
                              parameters:paramsOfNextPage
                                 storage:friends
                                  succes:success
                                 failure:failure];
                 //just exit out of the method body if next link was found
                 return;
             }
             if (success){
                success([friends copy]);
             }
         }];
     //do not forget to run connection
    [connection start];
}

How to use:

to get friends list use technique like as followig:

//For example retrieve friends list with limit of retrieving data items per request equal to 5

NSDictionary *anyParametersYouWant = @{@"limit":@5};
[self makeFBRequestToPath:@"me/taggable_friends/"
           withParameters:anyParametersYouWant
                  success:^(NSArray *results) {
                      NSLog(@"Found friends are:\n%@",results);    
                  }
                  failure:^[(NSError *) {
                      NSLog(@"Oops! Something went wrong(\n%@",error);
                  }];
];
like image 25
Nikolay Shubenkov Avatar answered Dec 06 '22 06:12

Nikolay Shubenkov