2012-06-06 12 views
5

Quindi sto cercando di utilizzare l'API di Twitter integrata in iOS 5 per recuperare un elenco di tutti i follower per un determinato utente. In tutta la documentazione di esempio che posso trovare, le richieste vengono fatte all'API che passa i blocchi inline da eseguire quando la richiesta ritorna, il che va bene per la maggior parte delle cose più semplici, MA quando sto cercando di ottenere ~ 1000 follower, e il la richiesta li sta restituendo in formato ~ 100, sono bloccato su come ricorsivamente richiamare la richiesta usando il 'prossimo indirizzo di paging' restituito ed elaborato all'interno del blocco di completamento. Ecco il codice:Utilizzo di blocchi oggettivi in ​​modo ricorsivo con API Twitter iOS

- (void)getTwitterFollowers { 
    // First, we need to obtain the account instance for the user's Twitter account 
    ACAccountStore *store = [[ACAccountStore alloc] init]; 
    ACAccountType *twitterAccountType = 
    [store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter]; 

    // Request access from the user for access to his Twitter accounts 
    [store requestAccessToAccountsWithType:twitterAccountType 
        withCompletionHandler:^(BOOL granted, NSError *error) { 
     if (!granted) { 
      // The user rejected your request 
      NSLog(@"User rejected access to his account."); 
     } 
     else { 
      // Grab the available accounts 
      NSArray *twitterAccounts = 
      [store accountsWithAccountType:twitterAccountType]; 

      if ([twitterAccounts count] > 0) { 
       // Use the first account for simplicity 
       ACAccount *account = [twitterAccounts objectAtIndex:0]; 

       // Now make an authenticated request to our endpoint 
       NSMutableDictionary *params = [[NSMutableDictionary alloc] init]; 
       [params setObject:@"1" forKey:@"include_entities"]; 

       // The endpoint that we wish to call 
       NSURL *url = [NSURL URLWithString:@"http://api.twitter.com/1/followers.json"]; 

       // Build the request with our parameter 
       request = [[TWRequest alloc] initWithURL:url 
              parameters:params 
             requestMethod:TWRequestMethodGET]; 

       [params release]; 

       // Attach the account object to this request 
       [request setAccount:account]; 

       [request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) { 
        if (!responseData) { 
         // inspect the contents of error 
         FullLog(@"%@", error); 
        } 
        else { 
         NSError *jsonError; 
         followers = [NSJSONSerialization JSONObjectWithData:responseData 
                    options:NSJSONReadingMutableLeaves 
                    error:&jsonError];    
         if (followers != nil) {       
          // THE DATA RETURNED HERE CONTAINS THE NEXT PAGE VALUE NEEDED TO REQUEST THE NEXT 100 FOLLOWERS, 
          //WHAT IS THE BEST WAY TO USE THIS?? 
          FullLog(@"%@", followers); 
         } 
         else { 
          // inspect the contents of jsonError 
          FullLog(@"%@", jsonError); 
         } 
        } 
       }];   
      } // if ([twitterAccounts count] > 0) 
     } // if (granted) 
    }]; 
    [store release]; 
} 

Idealmente mi piacerebbe un modo di ascoltare per questi dati viene restituito, controllare per un valore pagina successiva e se esiste, riutilizzare il blocco di codice e aggiungere restituiti i dati. I ', sicuro che ci deve essere un modo' best-practice 'per raggiungere questo obiettivo, qualsiasi aiuto sarebbe molto apprezzato!

+0

offtopic: è il "follower" che si utilizza nella richiesta performRequestWithHandler Method a iVar? – CarlJ

+0

sì, è un 'NSArray' –

+0

e dove lo hai definito? – CarlJ

risposta

3

Per espandere sulla risposta @Eimantas', il vostro gestore della richiesta è in attesa di una firma blocco specifico, quindi è necessario un modo diverso di gestire il numero di pagina.

-(void)getTwitterFollowers { 
    // set up request... 
    __block int page = 0; 
    __block void (^requestHandler)(NSData*, NSHTTPURLResponse*, NSError*) = null; 
    __block TWRequest* request = [[TWRequest alloc] initWithURL:url 
                parameters:params 
                requestMethod:TWRequestMethodGET]; 
    requestHandler = [^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) { 
     followers = [NSJSONSerialization JSONObjectWithData:responseData 
              options:NSJSONReadingMutableLeaves 
              error:&jsonError];    
     if (followers != nil) {       
      // process followers 
      page++; 
      NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary:request.parameters]; 
      // update params with page number 
      request = [[TWRequest alloc] initWithURL:url 
              parameters:params 
             requestMethod:TWRequestMethodGET]; 
      [request performRequestWithHandler:requestHandler]; 
     } 
    } copy]; 

    // now call the block for the first page 
    [request performRequestWithHandler:requestHandler]; 
} 
5

Per utilizzare qualsiasi blocco in modo ricorsivo, è necessario prima dichiararlo e definirlo in un secondo momento. Prova questo:

__block void (^requestPageBlock)(NSInteger pageNumber) = NULL; 

requestPageBlock = [^(NSInteger pageNumber) { 
    // do request with some calculations 
    if (nextPageExists) { 
     requestPageBlock(pageNumber + 1); 
    } 
} copy]; 

// now call the block for the first page 
requestPageBlock(0); 
+3

Non devi dichiarare prima. Ma credo che sia necessario specificare la variabile di blocco come __block e copiare il blocco nello stack prima di fare riferimento ricorsivamente a se stesso. Altrimenti riceverai un EXC_BAD_ACCESS. Quindi .. '__block void (^ request) (NSUInteger) = [^ (pagina NSUInteger) {..... code ......} copy];' –

+1

Hai ragione! Grazie per la correzione. – Eimantas

+2

Nessun problema. Ho passato un po 'di tempo a capirlo. Inoltre, sii molto attento se fai riferimento a un altro blocco all'interno di un blocco ricorsivo. Non lo fai nel tuo esempio, ma è un piccolo passo e può portare a perdite di memoria .... vedi qui: http://stackoverflow.com/a/8896766/1147934 –