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