iOS twitter API loadings more than 20 followers/following/tweets - ios

I have a simple twitter client that I am using to display a users tweets, followers, and following.
For some reason the count parameter for user tweets is being ignored and it is always loading only 20 results.
Here is the code:
- (void)getUserTweets {
// 1. Create a variable for twitter
NSURL *feedURL = [NSURL URLWithString:#"https://api.twitter.com/1.1/statuses/user_timeline.json"];
// 2. Get AppDelegate reference
AppDelegate *appDelegate =[[UIApplication sharedApplication] delegate];
// 3. Create NSDictionary for the TWR parameters
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys: self.usernameToLoad, #"screen_name", #"true", #"include_user_entities", #"100", #"count", nil];
// 4. Create TWRequest, with parameters, URL & specify GET method
//TWRequest *twitterFeed = [[TWRequest alloc] initWithURL:feedURL parameters:parameters requestMethod:TWRequestMethodGET];
SLRequest *twitterFeed = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:feedURL parameters:params];
// 5. Specify twitter request's account to our app delegate's
twitterFeed.account = appDelegate.userAccount;
// Making the request
[twitterFeed performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
// Check if we reached the reate limit
if ([urlResponse statusCode] == 429) {
NSLog(#"Rate limit reached");
return;
}
// Check if there was an error
if (error) {
NSLog(#"Error: %#", error.localizedDescription);
return;
}
// Check if there is some response data
if (responseData) {
NSError *error = nil;
self.userTweets = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];
}
});
}];
}
This will always return only 20 results, even if I set the count to something low like 1 or 2. Am I doing something wrong in defining my parameters?
Also, I am trying to load the users followers and following but I want to load a total of 200 if each, but again it is only loading 20.
From what the twitter API reads, It supplies automatic pagination and using the cursor parameter I can iterate through to load all of the data I want.
I am having a hard time figuring out exactly how this works. Here is my code for following (followers is identical with the exception of it calling a different API string)
- (void)getFriends {
// 1. Create a variable for twitter
NSURL *feedURL = [NSURL URLWithString:#"https://api.twitter.com/1.1/friends/list.json"];
// 2. Get AppDelegate reference
AppDelegate *appDelegate =[[UIApplication sharedApplication] delegate];
// 3. Create NSDictionary for the TWR parameters
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys: self.usernameToLoad, #"screen_name", #"true", #"include_user_entities", nil];
// 4. Create TWRequest, with parameters, URL & specify GET method
//TWRequest *twitterFeed = [[TWRequest alloc] initWithURL:feedURL parameters:parameters requestMethod:TWRequestMethodGET];
SLRequest *twitterFeed = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:feedURL parameters:parameters];
// 5. Specify twitter request's account to our app delegate's
twitterFeed.account = appDelegate.userAccount;
// Making the request
[twitterFeed performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
// Check if we reached the reate limit
if ([urlResponse statusCode] == 429) {
NSLog(#"Rate limit reached");
return;
}
// Check if there was an error
if (error) {
NSLog(#"Error: %#", error.localizedDescription);
return;
}
// Check if there is some response data
if (responseData) {
NSError *error = nil;
NSDictionary *TWData = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];
self.userFriends = [TWData objectForKey:#"users"];
}
});
}];
}
I am not sure how to properly loop through because the twitter api returns the cursor value I need to go to the next data.
Any help would be great, I might just be missing some logic I can't quite put my finger on.
Thanks in advance!

Results are given in multiple "pages" of results can be navigated through using the next_cursor value in subsequent requests.
https://dev.twitter.com/docs/misc/cursoring

Fine, I too had the same problem in paging the tweet feeds, It never used to update "max_id" parameter, because its value was "NSNumber", Then i changed to to NSString then it worked perfectly fine for me, Cross check once again weather any objects other than NSString are used in the request

Related

IOS get Twitter current Top Trends

I want to get Twitter current trends. I tired https://dev.twitter.com/docs/api/get-trendscurrent but no data does not come. My code is here:
-(void) getTwitterTopTrends{
// 1. Create a variable for twitter
NSURL *feedURL = [NSURL URLWithString:#"http://api.twitter.com/1/trends/current.json"];
// 2. Create TWRequest, with parameters, URL & specify GET method
SLRequest *twitterFeed = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:feedURL parameters:nil];
twitterFeed.account = _twitterAccount;
// Making the request
[twitterFeed performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
// Check if we reached the reate limit
if (responseData) {
NSError *error = nil;
NSDictionary *TWData = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];
NSArray* results = TWData [#"trends"];
}
});
}];
}
What is my wrong.
API version 1 is phased out. Try version 1.1 here: https://dev.twitter.com/docs/api/1.1/overview

Search for Mentions of Topic with Twitter API

I'm looking to search for any of the following things, whichever seems to work the best:
Regular mentions of a topic ABC (ABC)
Hashtag mentions of a topic ABC (#ABC)
# mentions of a topic ABC (#ABC)
How do I use the API to search this? Is there a specific way to form the URL to search for any one of these? For example, I'm currently using https://api.twitter.com/1.1/statuses/user_timeline.json with a specified account.
EDIT: for example, I want to be able to get just the tweets that are shown on this page: https://twitter.com/search?q=%23FiveWordTechHorrors How do I do this from a developer point of view?
NSString *url = [NSString stringWithFormat:#"http://api.twitter.com/1.1/search/tweets.json?q=%#&result_type=recent&count=%i", toBeSearched, count];
url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
SLRequest *twitterInfoRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:[NSURL URLWithString:url] parameters:nil];
[twitterInfoRequest setAccount:twitterAccount];
[twitterInfoRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if ([urlResponse statusCode] == 429) {
//Rate Limit Reached
} else if (error) {
// Check if there was an error
}
// Check if there is some response data
if (responseData) {
NSError *error = nil;
NSArray *result = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];
// Do Whatever you want to do, the result is an array of 'tweet objects'
}
}];

iOS Twitter api deleting favorites gives error code: 34

I have an application that lets you view your favorited tweets, and it also lets you remove them from favorites if you don't want it anymore.
I cannot for the life of me figure out why I am getting this error:
2013-10-13 17:33:57.306 MyApp[6233:a0b] {
errors = (
{
code = 34;
message = "Sorry, that page does not exist";
}
);
}
Here is my code that is calling the request:
#define TW_API_DESTROY_FAVORITE #"https://api.twitter.com/1.1/favorites/destroy.json"
- (void)deleteFavoriteWithID:(NSString *)tweetID atIndex:(int) index {
NSURL *theURL = [NSURL URLWithString:TW_API_DESTROY_FAVORITE];
// Get AppDelegate reference
AppDelegate *appDelegate =[[UIApplication sharedApplication] delegate];
NSMutableDictionary *favoriteParameters = [[NSMutableDictionary alloc] init];
[favoriteParameters setObject:tweetID forKey:#"id"];
// Create TWRequest, with parameters, URL & specify GET method
SLRequest *twitterFeed = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:theURL parameters:favoriteParameters];
// Specify twitter request's account to our app delegate's
twitterFeed.account = appDelegate.userAccount;
// Making the request
[twitterFeed performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
// Check if we reached the reate limit
if ([urlResponse statusCode] == 429) {
NSLog(#"Rate limit reached");
return;
}
// Check if there was an error
if (error) {
NSLog(#"Error: %#", error.localizedDescription);
return;
}
// Check if there is some response data
if (responseData) {
NSError *jsonError = nil;
id feedData = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&jsonError];
if (!jsonError) {
NSLog(#"%#", feedData);
} else {
// Alert the user of an error
});
}
}
});
}];
}
For whatever reason it is just NOT accepting this. Elsewhere in the app, I am using the EXACT same code and it works fine, but for whatever reason this will not fire properly.
Any ideas? Thanks!

iOS Twitter SLRequest returning url domain error -1012

I am attempting to perform reverse oauth to get twitter access tokens for a server.
I have figured out how to submit the request and receive a response, but when I do, it gives me this error:
Error: The operation couldn’t be completed. (NSURLErrorDomain error -1012.)
I looked this up, and it says that it means the user has canceled the request. I am not sure how this is possible, and I cannot figure out how to fix it.
Here is my code:
NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];
NSNumber *timeStampObj = [NSNumber numberWithDouble: timeStamp];
NSString *oauth_nonce = [self genRandStringLength:32];
NSString *oauth_timestamp = [timeStampObj stringValue];
NSURL *feedURL = [NSURL URLWithString:#"https://api.twitter.com/oauth/request_token"];
NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys: #"my key here", #"oauth_consumer_key", oauth_nonce, #"oauth_nonce", #"HMAC-SHA1", #"oauth_signature_method", oauth_timestamp, #"oauth_timestamp", #"1.0", #"oauth_version", #"reverse_auth", #"x_auth_mode", nil];
SLRequest *twitterFeed = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:feedURL parameters:parameters];
twitterFeed.account = self.userAccount;
// Making the request
[twitterFeed performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
// Check if we reached the reate limit
if ([urlResponse statusCode] == 429) {
NSLog(#"Rate limit reached");
return;
}
// Check if there was an error
if (error) {
NSLog(#"The Error is: %#", error.localizedDescription);
return;
}
// Check if there is some response data
if (responseData) {
NSLog(#"%#", responseData);
}
});
}];
There must be something simple I am missing, and this is keeping me from finishing a project. Any help would be great, thanks!
Error code -1012 can be due to an authentication challenge. In my case, a Twitter account existed in Settings, but was not logged in for some reason. Once I entered the password for the account, everything worked perfectly.
I got this problem when I sent a request to https://api.twitter.com/oauth/request_token with an extra nonce and signature in the header. Specifically, the following code gave me a 1012, but the next chunk of code succeeded. This code is adapted from Sean Cook's Reverse Twitter Auth example.
/**
* The first stage of Reverse Auth.
*
* In this step, we sign and send a request to Twitter to obtain an
* Authorization: header which we will use in Step 2.
*
* #param completion The block to call when finished. Can be called on any thread.
*/
- (void)_step1WithCompletion:(TWAPIHandler)completion
{
NSURL *url = [NSURL URLWithString:TW_OAUTH_URL_REQUEST_TOKEN];
NSDictionary *dict = #{TW_X_AUTH_MODE_KEY: TW_X_AUTH_MODE_REVERSE_AUTH,
TW_OAUTH_NONCE:[self nonce],
TW_SIGNATURE_METHOD: TW_SIGNATURE_METHOD_VALUE,
};
TWSignedRequest *step1Request = [[TWSignedRequest alloc] initWithURL:url parameters:dict requestMethod:TWSignedRequestMethodPOST];
TWDLog(#"Step 1: Sending a request to %#\nparameters %#\n", url, dict);
[step1Request performRequestWithHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
completion(data, error);
});
}
The following works. Note the change in the dict.
/**
* The first stage of Reverse Auth.
*
* In this step, we sign and send a request to Twitter to obtain an
* Authorization: header which we will use in Step 2.
*
* #param completion The block to call when finished. Can be called on any thread.
*/
- (void)_step1WithCompletion:(TWAPIHandler)completion
{
NSURL *url = [NSURL URLWithString:TW_OAUTH_URL_REQUEST_TOKEN];
NSDictionary *dict = #{TW_X_AUTH_MODE_KEY: TW_X_AUTH_MODE_REVERSE_AUTH};
TWSignedRequest *step1Request = [[TWSignedRequest alloc] initWithURL:url parameters:dict requestMethod:TWSignedRequestMethodPOST];
TWDLog(#"Step 1: Sending a request to %#\nparameters %#\n", url, dict);
[step1Request performRequestWithHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
completion(data, error);
});
}

My code for paging through Twitter friends using recursion not working - iOS

I'm trying to page through a user's twitter friends using cursors. Since you get 20 at a time along with a next cursor, I thought perhaps recursion was the best way to handle this. However, I believe because I'm using completion handler blocks, it isn't working correctly. I keep getting just two pages of friends (40), and it returns.
- (void)fetchTwitterFriendsForCrush:(Crush*)crush
fromCursor:(NSString*)cursor
usingManagedObjectContext:(NSManagedObjectContext*)moc
withSender:(id) sender
usingCompletionHandler:(void(^)())completionHandler
{
// twitter returns "0" when there are no more pages to receive
if (([cursor isEqualToString:#"0"]) || (cursor == nil)) {
completionHandler();
return;
}
NSString *urlString =
[NSString stringWithFormat:#"https://api.twitter.com/1.1/friends/list.json?cursor%#skip_status=1", cursor];
NSURL *requestURL = [NSURL URLWithString:urlString];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter
requestMethod:SLRequestMethodGET
URL:requestURL
parameters:nil];
request.account = self.twitterAccount;
[request performRequestWithHandler:
^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if (error) {
NSLog(#"Error getting twitter friends = %#", error);
}
if (responseData) {
NSError *jsonError;
NSString *nextCursor = nil;
NSMutableArray *friendsArray = [NSMutableArray arrayWithCapacity:100];
NSDictionary *friendsDictionary =
[NSJSONSerialization JSONObjectWithData:responseData
options:0
error:&jsonError];
if ([friendsDictionary valueForKey:#"next_cursor_str"]) {
nextCursor = [friendsDictionary valueForKey:#"next_cursor_str"];
}
if ([friendsDictionary valueForKey:#"users"]) {
[friendsArray addObjectsFromArray:[friendsDictionary valueForKey:#"users"]];
}
for (NSDictionary *singleFriend in friendsArray) {
NSString *twitterID = [singleFriend valueForKey:#"id_str"];
NSString *name = [singleFriend valueForKey:#"name"];
NSString *screenName = [singleFriend valueForKey:#"screen_name"];
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(mainQueue, ^(void) {
// update model
TwitterFriend *newTwitterFriend =
[TwitterFriend twitterFriendWithTwitterID:twitterID
forCrush:crush
usingManagedObjectContext:moc];
newTwitterFriend.name = name;
newTwitterFriend.screenName = screenName;
});
}
[self fetchTwitterFriendsForCrush:crush
fromCursor:nextCursor
usingManagedObjectContext:moc
withSender:self
usingCompletionHandler:nil];
}
}];
}
And the method that calls it:
[self.twitterNetwork fetchTwitterFriendsForCrush:self.crush fromCursor:#"-1" usingManagedObjectContext:self.managedObjectContext withSender:self usingCompletionHandler:^{
//
[self reloadData];
}];
UPDATE: It appears that I'm receiving the same next_cursor data on every request. Has anyone experienced this? Or do you see anything in this code that would cause that?
I found that a more complex way is better. You may use https://api.twitter.com/1.1/friends/ids.json? to get your friends ids list. Then using 1.1/users/lookup.json you may get the full info for users. I wrote a small helper to drill down user friends with SLRequest (#iOS6) https://github.com/ArchieGoodwin/NWTwitterHelper

Resources