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