Getting all tweets of a specific twitter account? - objective-c

I just want to fetch all tweets of an specific twitter account. I want to use below url but don't know how we can get user_id or screen_name of a twitter account, whose tweets we want to fetch.
Resource URL http://api.twitter.com/1/statuses/user_timeline.format Parameters Always specify either an user_id or screen_name when requesting a user timeline.
Does any one have any idea or source code or reference. Any help will be highly appreciable.
I am using following function for getting 200 tweets but it shows in NSLog
HTTP response status: 403 message
Function
- (IBAction)followOnTwitter:(id)sender
{
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[accountStore requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {
if(granted) {
// Get the list of Twitter accounts.
NSArray *accountsArray = [accountStore accountsWithAccountType:accountType];
// For the sake of brevity, we'll assume there is only one Twitter account present.
// You would ideally ask the user which account they want to tweet from, if there is more than one Twitter account present.
if ([accountsArray count] > 0) {
// Grab the initial Twitter account to tweet from.
ACAccount *twitterAccount = [accountsArray objectAtIndex:0];
NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] init];
[tempDict setValue:#"rohit40793982" forKey:#"screen_name"];
//[tempDict setValue:#"true" forKey:#"follow"];
// [tempDict setValue:#"683286" forKey:#"user_id "];
TWRequest *postRequest = [[TWRequest alloc] initWithURL:[NSURL URLWithString:#"http://api.twitter.com/1/statuses/user_timeline.format"]
parameters:tempDict
requestMethod:TWRequestMethodPOST];
[postRequest setAccount:twitterAccount];
[postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSLog(#"%#",urlResponse);
tweets = [NSJSONSerialization JSONObjectWithData:responseData
options:kNilOptions
error:&error];
NSString *output = [NSString stringWithFormat:#"HTTP response status: %i", [urlResponse statusCode]];
NSLog(#"%#", output);
[self performSelectorOnMainThread:#selector(displayText:) withObject:output waitUntilDone:NO];
}];
}
}
}];
}
I am not receiving array of all tweets.

Your mistake, I think, is with this line
http://api.twitter.com/1/statuses/user_timeline.format
the ".format" is the format you want the response. For example, if you want XML, use
https://api.twitter.com/1/statuses/user_timeline.xml
or for JSON, use
https://api.twitter.com/1/statuses/user_timeline.json
You will also need to append the screen_name as a query. For example, to get all of my tweets as JSON, use
https://api.twitter.com/1/statuses/user_timeline.xml?screen_name=edent

screen_name is basically, the account name. It's the name right after the '#'. Like WOW's screen_name is #Warcraft.
Oh and in fact the .format was the problem. You have to specify one of the 3: atom, json, or xml. (I think that getting the user timeline don't allow xml return, just read the API)
As I'm a Java programmer I'm afraid I can't help any further :/

Related

Facebook Graph API Fetching User's Profile Photo

I'm using the Facebook Graph API v2.0. The following call
[FBRequestConnection startWithGraphPath:#"/me/picture" completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSLog(#"%#", result);
} else {
NSLog(#"%#", [error userInfo]);
}
}];
results in this error:
{
NSLocalizedDescription = "Response is a non-text MIME type; endpoints that return images and other binary data should be fetched using NSURLRequest and NSURLConnection";
"com.facebook.sdk:ErrorSessionKey" = "<FBSession: 0x10f036250, state: FBSessionStateOpen, loginHandler: 0x100073a40, appID: 863523550341327, urlSchemeSuffix: , tokenCachingStrategy:<FBSessionTokenCachingStrategy: 0x10f0339c0>, expirationDate: 4001-01-01 00:00:00 +0000, refreshDate: 2014-07-27 17:20:14 +0000, attemptedRefreshDate: 0001-12-30 00:00:00 +0000, permissions:(\n installed,\n \"public_profile\",\n email,\n \"user_birthday\",\n \"user_location\",\n \"user_friends\"\n)>";
"com.facebook.sdk:HTTPStatusCode" = 0;
}
Does anyone know why this is happening? All I really need is a response containing a url to my profile picture. In 2012 and earlier, similar questions were asked but the API has changed since then. Please don't mark this as a duplicate unless you're actually sure that the question you redirect me to has a working solution. I've tried a couple of other alternatives such as starting the connection myself and using a graph path such as "/me?fields=picture" but they all result in the same error.
It seems my original call requests an image. To get a text based response that gives a url to the profile photo, the following worked for me:
[FBRequestConnection startWithGraphPath:#"me?fields=picture.height(500),picture.width(500)"completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if (error) {
}
}];
For the new Facebook Graph API I use:
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
initWithGraphPath:#"/me?fields=id,name,picture" //As many fields as you need
parameters:nil
HTTPMethod:#"GET"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection,
id result,
NSError *error) {
if (!error){
NSDictionary *picture = [(NSDictionary*)result objectForKey:#"picture"];
NSDictionary *data = [picture objectForKey:#"data"];
NSString *url = [data objectForKey:#"url"];
NSData *dataImage = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
}
}];
You can more info about user data here
Load profile picture with the help of this URL template
NSString *imgUrl = [NSString stringWithFormat:#"http://graph.facebook.com/%#/picture", user.id];

how to deactivate twitter account in iPhone app that used for Integration

I have app where I am doing the Twitter integration.
I am able to successfully tweets.
Now when I want to de-activate, I am using below.
SLRequest *postRequest1 = [SLRequest requestForServiceType:SLServiceTypeTwitter
requestMethod:SLRequestMethodPOST URL:
[NSURL URLWithString:#"https://api.twitter.com/1/account/end_session.json"]
parameters: [NSDictionary dictionaryWithObject:#"" forKey:#"status"]];
Problem is API with 1 is deprecated and I don't find this method in 1.1.
Is there any alternate for this?
Also what I notice is when I try to activate again, the permission is not asked. It directly send tweet. It ask tweet permission for the first time only. Not after de-activate -- Re-activate process. Is this is how Twitter behaves?
Edit 1
Code I use for all tweet is as below...
if ([self userHasAccessToTwitter]) {
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
// Request access from the user to access their Twitter account
[account requestAccessToAccountsWithType:accountType options:NULL completion:^(BOOL granted, NSError *error)
{
if (granted == YES)
{
///////////////////////////////////////////////
// SEND TEXT ONLY ///
///////////////////////////////////////////////
[[NSUserDefaults standardUserDefaults] setValue:#"yes" forKey:#"twitterLogin"];
[[NSUserDefaults standardUserDefaults] synchronize];
// Populate array with all available Twitter accounts
NSString *message1 = [NSString stringWithFormat:#"Hi! I am using twitter integration."];
NSArray *arrayOfAccounts = [account accountsWithAccountType:accountType];
if ([arrayOfAccounts count] > 0)
{
//use the first account available
ACAccount *acct = [arrayOfAccounts objectAtIndex:0];
SLRequest *postRequest1 = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:[NSURL URLWithString:#"http://api.twitter.com/1.1/statuses/update.json"] parameters: [NSDictionary dictionaryWithObject:message1 forKey:#"status"]];
[postRequest1 setAccount:acct];//set account
[postRequest1 performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if(error) {
NSLog(#"error == %#", error);
} else {
NSLog(#"good to go -1- %i", [urlResponse statusCode]);
}
}];
}
}
}];
}
end_session in API v1 never worked as it should anyway. Starting from 1.1 this method was removed and there's no alternative method. The user should decide if he wants to revoke your application access to his twitter account. The only thing you could do is to delete the auth_token.

How to process multiple SLRequest to get friends list in twitter?

I m using the following twitter api to get the friends list:
https://api.twitter.com/1.1/friends/list.json?
And using [SLRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) to get the response data, and perform UI Changes and model data changes in performRequestWithHandler block.
But a single request at the maximum retrieves only 20 friends.(if you set the cursor parameter in api to -1).
I can use the cursor parameter of the api to send request to get the next 20 friends and so on until the cursor value is 0.
cursor parameter can be set to the 'next_cursor' parameter in the response data of the previous request.
But i m not aware of how to call another SLRequest with in the performRequestWithHandler of the previous request, until the 'next_cursor' value in response data of previous request is 0.
Can anybody tell me how to get all the friends using SLRequest or using any other way.
Any help is appreciated.
Thank you.
u can call the next request in the request handler just after you get the response of twitter friends.
Sorry for not elaborating. I thought you would understand.
Here is the code.
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
// Request access from the user to access their Twitter account
[account requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error)
{
// Did user allow us access?
if (granted == YES)
{
// Populate array with all available Twitter accounts
NSArray *arrayOfAccounts = [account accountsWithAccountType:accountType];
// Sanity check
if ([arrayOfAccounts count] > 0)
{
[self postRequest];
}
}
}];
- (void)PostRequest
{
// Keep it simple, use the first account available
ACAccount *acct = [arrayOfAccounts objectAtIndex:0];
NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] init];
[tempDict setValue:#"Posting video" forKey:#"status"];
// Build a twitter request
SLRequest *postRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:[NSURL URLWithString:#"https://api.twitter.com/1.1/statuses/update.json"] parameters:tempDict];
[postRequest setAccount:acct];
[postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSLog(#"Twitter response, HTTP response: %i", [urlResponse statusCode]);
NSString *output = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"%#", output);
**// calling this again and again will help you with multiple post request.**
[self postRequest]
}];
}
Similar thing can be done for friend list too.
Hope I helped.

Objective C how to get a Facebook access token

I'm having some trouble pulling a Facebook access token from the web for a Facebook Feed App I'm writing. The problem isn't strictly related to gaining a Facebook token; this just frames the problem. When I go to https://graph.facebook.com/oauth/access_token?grant_type=client_credentials&client_id=[APP_ID]&client_secret=[APP_SECRET], I am returned a token on a page that simply says:
access_token=464483653570261|cY9NHFBWCDJ9hSQfswWFg0FDZvw
How can I parse that from the webpage into my app? I'm relatively new to Objective C (and I've only got a year of basic coding experience), so I tried to use part of a method that I found online to get a JSON feed, combined with a simple parsing method, but it didn't work. The code is as follows:
id getToken = [self objectWithUrl:[NSURL URLWithString:#"https://graph.facebook.com/
oauth/access_token?grant_type=client_credentials&
client_id=464483653570261&
client_secret=55bb8395ed0293bf37af695f6cdaa1fb"]];
NSString *fullToken = (NSString *)getToken;
NSLog(#"fullToken: %#", fullToken);
NSArray *components = [fullToken componentsSeparatedByString:#"="];
NSString *token = [components objectAtIndex:1];
NSLog(#"token: %#", token);
Both of my NSLogs say that the respective Strings point to (null). I'm not really certain what I'm doing wrong, and I haven't had much luck finding answers on the internet, as I'm not sure what to call what I'm trying to do. I'd appreciate any help, or alternate methods, that you might have.
By the look of it, the value you're getting isn't JSON, it's just a string.
Try something like this:
NSURL * url = [NSURL URLWithString:#"https://graph.facebook.com/
oauth/access_token?grant_type=client_credentials&
client_id=464483653570261&
client_secret=55bb8395ed0293bf37af695f6cdaa1fb"]];
NSString * fullToken = [NSString stringWithContentsOfUrl: url];
NSLog(#"fullToken: %#", fullToken);
NSArray *components = [fullToken componentsSeparatedByString:#"="];
NSString *token = [components objectAtIndex:1];
NSLog(#"token: %#", token);
There is a more simple way of getting User's access_token using the ACAccountStore & ACAccountType. Check the Full Code Below:
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSDictionary *FBOptions = [NSDictionary dictionaryWithObjectsAndKeys:FACEBOOK_APP_ID, ACFacebookAppIdKey,#[#"email"],ACFacebookPermissionsKey, nil];
[accountStore requestAccessToAccountsWithType:accountType options:FBOptions completion:
^(BOOL granted, NSError *error) {
if (granted) {
NSArray *facebookAccounts = [accountStore accountsWithAccountType:accountType];
FBAccount = [facebookAccounts firstObject];
NSLog(#"token :%#",[[FBAccount credential] oauthToken]);
} else {
NSLog(#"error getting permission %#",error);
if([error code]== ACErrorAccountNotFound){
NSLog(#"Account not found. Please setup your account in settings app");
}
else {
NSLog(#"Account access denied");
}
}
}];

Using objective-c blocks recursively with iOS Twitter API

So I'm trying to use the built in Twitter API in iOS 5 to retrieve a list of all the followers for a given user. In all the example documentation I can find, requests are made to the API passing inline blocks to be executed when the request returns, which is fine for most of the simpler stuff, BUT when I'm trying to get ~1000 followers, and the request is returning them paged in sizes ~100, I'm stuck on how to recursively call the request again using the 'next paging address' returned and processed inside the completion block. Here is the code:
- (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];
}
Ideally I'd like some way to listen for this data being returned, check for a next page value and if it exists, reuse the code block and append the data returned. I', sure there must be a 'best-practice' way to achieve this, any help would be much appreciated!
To use any block recursively you have to declare it first and define it later. Try this:
__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);
To expand on #Eimantas' answer, your request handler is expecting a specific block signature, so you need a different way to handle the page number.
-(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];
}