iOS Twitter api deleting favorites gives error code: 34 - twitter

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!

Related

Twitter share with SLRequest

This is Sam.Currently I am devloping twitter share in my application.I need to implement that without ComposeController.I need to integrate with SLRequest from social framework.
The Code which i using is as below as
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *twitterAccountType =[accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[accountStore requestAccessToAccountsWithType:twitterAccountType options:NULL completion:^(BOOL granted, NSError *error) {
if (granted) {
NSLog(#"Creating Request");
// Step 2: Create a request
NSArray *twitterAccounts =[accountStore accountsWithAccountType:twitterAccountType];
NSURL *url = [NSURL URLWithString:#"https://api.twitter.com/1.0/statuses/update.json"];
NSDictionary *params = #{#"screen_name" : #"naheshsamy",#"include_rts" : #"0",#"trim_user" : #"1",#"count" : #"1"};
SLRequest *request =
[SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:url parameters:params];
// Attach an account to the request
[request setAccount:[twitterAccounts lastObject]];
NSLog(#"Request %#",request);
// Step 3: Execute the request
[request performRequestWithHandler: ^(NSData *responseData,NSHTTPURLResponse *urlResponse,NSError *error) {
if (responseData) {
if (urlResponse.statusCode >= 200 && urlResponse.statusCode < 300) {
NSError *jsonError;
NSDictionary *timelineData = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:&jsonError];
if (timelineData) {
NSLog(#"Timeline Response: %#\n", timelineData);
}
else {
// Our JSON deserialization went awry
NSLog(#"JSON Error: %#", [jsonError localizedDescription]);
}
}
else {
// The server did not respond ... were we rate-limited?
NSLog(#"The response status code is %d %# %#",urlResponse.statusCode,urlResponse.suggestedFilename,error);
}
}
}];
}
else {
// Access was not granted, or an error occurred
NSLog(#"%#", [error localizedDescription]);
}
}];
I am always getting status 400 error..
Any help will be appreciated.
Regards,
Sam.P
The code seems similar to what I have used.
They do have warned that version 1.0 of the API is no longer supported and may not function. Try changing to 1.1 and see if it solves your problem.
#"https://api.twitter.com/1.1/statuses/update.json"

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

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

return nsmutablearray from twitter account block

I am trying to make a function which returns a list of twitter users but I am not able to make the function return a nsmutablearray. Here it is the code I execute
-(NSMutableArray*) getTwitterUsersInPosition: (Position*) position
{
// Request access to the Twitter accounts
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error){
if (granted) {
NSArray *accounts = [accountStore accountsWithAccountType:accountType];
// Check if the users has setup at least one Twitter account
if (accounts.count > 0)
{
ACAccount *twitterAccount = [accounts objectAtIndex:0];
// Creating a request to get the info about a user on Twitter
NSArray *keys = [NSArray arrayWithObjects:#"geocode", #"count", nil];
NSArray *objects = [NSArray arrayWithObjects:#"37.781157,-122.398720,100mi", #"2", nil];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:objects
forKeys:keys];
SLRequest *twitterInfoRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:[NSURL URLWithString:#"https://api.twitter.com/1.1/search/tweets.json"] parameters:dictionary];
[twitterInfoRequest setAccount:twitterAccount];
// Making the request
[twitterInfoRequest performRequestWithHandler: ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
// Check if we reached the rate 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;
NSArray *TWData = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];
NSMutableArray *usersArray= [[NSMutableArray alloc] init];
NSMutableArray* statuses= [(NSDictionary *) TWData objectForKey:#"statuses"];
for (NSDictionary* dict in statuses )
{
NSString* user = [[dict objectForKey:#"user"] objectForKey:#"screen_name"];
NSLog(#"%#",user);
[usersArray addObject:user];
}
return userArray; //Here it says "Return type 'NSMutabelArray *' must match previous type 'void' when block literal has unspecified return type
}
});
}];
}
} else {
NSLog(#"No access granted");
}
}];
}
Thanks for your help.
Your method can NOT have a return type because the value you want to return is obtained asynchronously and isn't available until after the method has completed.
You need to rewrite your method so that it returns the data:
To a delegate
Via a block
Into an instance variable and triggers some update
Via a notification
Basically some mechanism that allows you to deal with the asynchronous response. Please don't make the call synchronous.
In the middle of your code you simply write return without a value (as if your method has return type of void):
if ([urlResponse statusCode] == 429) {
NSLog(#"Rate limit reached");
return;
}
// Check if there was an error
if (error) {
NSLog(#"Error: %#", error.localizedDescription);
return;
Change it to return nil and the code should compile.

iOS: Post to Twitter causes error - Obtaining the web lock from a thread other than the main thread

I'm making an app where I want to post to twitter (without a modal view). I'm quite new to the Social.framework so I'm having some issues. More specifically I get the error:
Obtaining the web lock from a thread other than the main thread or the web thread. UIKit should not be called from a secondary thread.
And I'm not sure what's causing this error.
My Twitter method looks like this:
- (void)postToTwitter
{
ACAccountType *twitterType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
SLRequestHandler requestHandler =
^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if (responseData) {
NSInteger statusCode = urlResponse.statusCode;
if (statusCode >= 200 && statusCode < 300) {
NSDictionary *postResponseData =
[NSJSONSerialization JSONObjectWithData:responseData
options:NSJSONReadingMutableContainers
error:NULL];
NSLog(#"[SUCCESS!] Created Tweet with ID: %#", postResponseData[#"id_str"]);
}
else {
NSLog(#"[ERROR] Server responded: status code %d %#", statusCode,
[NSHTTPURLResponse localizedStringForStatusCode:statusCode]);
}
}
else {
NSLog(#"[ERROR] An error occurred while posting: %#", [error localizedDescription]);
}
};
ACAccountStoreRequestAccessCompletionHandler accountStoreHandler =
^(BOOL granted, NSError *error) {
if (granted) {
NSArray *accounts = [self.accountStore accountsWithAccountType:twitterType];
NSURL *url = [NSURL URLWithString:#"https://api.twitter.com"
#"/1.1/statuses/update_with_media.json"];
NSDictionary *params = #{#"status" : self.postTextField.text};
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter
requestMethod:SLRequestMethodPOST
URL:url
parameters:params];
[request setAccount:[accounts lastObject]];
[request performRequestWithHandler:requestHandler];
}
else {
NSLog(#"[ERROR] An error occurred while asking for user authorization: %#",
[error localizedDescription]);
}
};
[self.accountStore requestAccessToAccountsWithType:twitterType
options:NULL
completion:accountStoreHandler];
}
Much like the example from here: https://dev.twitter.com/docs/ios/posting-images-using-twrequest
Can anyone see any issues with the code, or could it be something else that is causing the error?
Note: It seems like none of the NSLogs is getting called.

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