twtrtwitter twitterkit start sharedinstance kit objective-c ios recursion twitter objective-c-blocks

objective c - twitterkit - Usar Object-C bloques recursivamente con iOS API de Twitter



twtrtwitter (2)

Para ampliar la respuesta de @Eimantas, su controlador de solicitudes espera una firma de bloque específica, por lo que necesita una forma diferente de manejar el número de página.

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

Así que estoy tratando de usar la API de Twitter incorporada en iOS 5 para recuperar una lista de todos los seguidores de un usuario determinado. En toda la documentación de ejemplo que puedo encontrar, las solicitudes se hacen a la API pasando bloques en línea para que se ejecuten cuando la solicitud retorna, lo cual está bien para la mayoría de las cosas más simples, PERO cuando intento obtener ~ 1000 seguidores, y el la solicitud los devuelve paginado en tamaños ~ 100, estoy atascado en cómo volver a llamar repetitivamente a la solicitud utilizando la ''siguiente dirección de paginación'' devuelta y procesada dentro del bloque de finalización. Aquí está el código:

- (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, me gustaría tener alguna manera de escuchar para que se devuelvan estos datos, verificar el valor de la siguiente página y, si existe, reutilizar el bloque de código y anexar los datos devueltos. Yo, seguro que debe haber una forma de "mejores prácticas" para lograr esto, ¡cualquier ayuda sería muy apreciada!


Para usar cualquier bloque recursivamente, primero debe declararlo y definirlo más adelante. Prueba esto:

__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);