【问题标题】:iOS Facebook Graph API Use "next" or "previous" Url for Pagination Using SDKiOS Facebook Graph API 使用“下一个”或“上一个”Url 使用 SDK 进行分页
【发布时间】:2014-07-01 15:37:29
【问题描述】:

我不太确定在对结果进行分页时想要利用图形 api 返回的“下一个”或“上一个”URL 时的最佳方法或正确的 SDK 调用。我已经查看了 FBRequest 和 FBRequestConnection 的文档,但没有任何方法或调用可以作为我问题的明显解决方案。任何人有一个或可以提出一个建议,将我指向正确的方向?

【问题讨论】:

    标签: ios facebook-graph-api facebook-ios-sdk


    【解决方案1】:

    Nikolay 的解决方案非常完美。这是它的 Swift 版本

    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)")
        }
    }
    

    【讨论】:

      【解决方案2】:

      要获得下一个链接,您必须这样做:

      我是这样解决的:

      添加标题

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

      和代码

      //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];
      }
      

      使用方法:

      获取好友列表使用如下技术:

      //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);
                        }];
      ];
      

      【讨论】:

        【解决方案3】:

        所以在寻找明显答案的过程中,我偶然发现了 github.com 上的 Facebook iOS SDK 源代码并找到了这个类:https://github.com/facebook/facebook-ios-sdk/blob/master/src/Network/FBGraphObjectPagingLoader.m

        在“- (void)followNextLink”方法中,我找到了解决方案:

         FBRequest *request = [[FBRequest alloc] initWithSession:self.session
                                                          graphPath:nil];
        
            FBRequestConnection *connection = [[FBRequestConnection alloc] init];
            [connection addRequest:request completionHandler:
             ^(FBRequestConnection *innerConnection, id result, NSError *error) {
                 _isResultFromCache = _isResultFromCache || innerConnection.isResultFromCache;
                 [innerConnection retain];
                 self.connection = nil;
                 [self requestCompleted:innerConnection result:result error:error];
                 [innerConnection release];
             }];
        
            // Override the URL using the one passed back in 'next'.
            NSURL *url = [NSURL URLWithString:self.nextLink];
            NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
            connection.urlRequest = urlRequest;
        
            self.nextLink = nil;
        
            self.connection = connection;
            [self.connection startWithCacheIdentity:self.cacheIdentity
                              skipRoundtripIfCached:self.skipRoundtripIfCached];
        

        上面有/有很多我不需要的代码,所以我能够(在SO OP 的帮助下)将其浓缩为:

        /* make the API call */
        FBRequest *request = [[FBRequest alloc] initWithSession:FBSession.activeSession graphPath:nil];
        FBRequestConnection *connection = [[FBRequestConnection alloc] init];
        [connection addRequest:request completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
        
            NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithDictionary:@{@"friends": [result objectForKey:@"data"], @"paging": [result objectForKey:@"paging"]}];
            NSLog(@"%@", dictionary);
            block(dictionary, error);
        }];
        
        // Override the URL using the one passed back in 'next|previous'.
        NSURL *url = [NSURL URLWithString:paginationUrl];
        NSMutableURLRequest* urlRequest = [NSMutableURLRequest requestWithURL:url];
        connection.urlRequest = urlRequest;
        
        [connection start];
        

        为了帮助可能需要更通用方法的其他人,我已将我的大部分 Facebook API 图调用编译成一个 gist,发现 @https://gist.github.com/tamitutor/c65c262d8343d433cf7f

        【讨论】:

        • 非常感谢!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-01-09
        • 1970-01-01
        • 1970-01-01
        • 2022-01-06
        • 1970-01-01
        • 1970-01-01
        • 2019-11-09
        相关资源
        最近更新 更多