I want to post a tweet to Twitter when user taps a button in the application. I don't want to use the TWTweetComposeViewController so that the user again need to tap the Send button. I want to post tweet on tap on a button inside the application. (Using iOS Twitter Framework)
Is there any way to do this ?
Thanks
Use below code to do post image and text without showing ViewContoller . This is called silent Post.
- (void) shareOnTwitterWithMessage:(NSString *)message {
ACAccountStore *twitterAccountStore = [[ACAccountStore alloc]init];
ACAccountType *TWaccountType= [twitterAccountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[twitterAccountStore requestAccessToAccountsWithType:TWaccountType options:nil completion:
^(BOOL granted, NSError *e) {
if (granted) {
NSArray *accounts = [twitterAccountStore accountsWithAccountType:TWaccountType];
twitterAccounts = [accounts lastObject];
NSDictionary *dataDict = #{#"status": message};
[self performSelectorInBackground:#selector(postToTwitter:) withObject:dataDict];
}
else {
return ;
}
}];
}
- (void)postToTwitter:(NSDictionary *)dataDict{
NSURL *requestURL = [NSURL URLWithString:#"https://api.twitter.com/1.1/statuses/update_with_media.json"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:requestURL parameters:dataDict];
NSData *imageData = UIImagePNGRepresentation([UIImage imageNamed:#"icon#2x.png"]);
[request addMultipartData:imageData
withName:#"media[]"
type:#"image/jpeg"
filename:#"image.jpg"];
request.account = twitterAccounts;
[request performRequestWithHandler:^(NSData *data, NSHTTPURLResponse *response, NSError *error) {
if(!error){
NSDictionary *list =[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
if(![list objectForKey:#"errors"]){
if([list objectForKey:#"error"]!=nil){
//Delegate For Fail
return ;
}
}
}
}];
}
Try this:
NSString *statusesShowEndpoint = #"https://api.twitter.com/1.1/statuses/update.json";
NSDictionary *params = #{#"status": #"Hello, my first autopost tweet..."};
NSError *clientError;
NSURLRequest *request = [[[Twitter sharedInstance] APIClient]
URLRequestWithMethod:#"POST"
URL:statusesShowEndpoint
parameters:params
error:&clientError];
if (request) {
[[[Twitter sharedInstance] APIClient]
sendTwitterRequest:request
completion:^(NSURLResponse *response,
NSData *data,
NSError *connectionError) {
if (data) {
// handle the response data e.g.
NSError *jsonError;
NSDictionary *dicResponse = [NSJSONSerialization
JSONObjectWithData:data
options:0
error:&jsonError];
NSLog(#"%#",[dicResponse description]);
}
else {
NSLog(#"Error code: %ld | Error description: %#", (long)[connectionError code], [connectionError localizedDescription]);
}
}];
}
else {
NSLog(#"Error: %#", clientError);
}
Related
I need to get a Twitter feed of a public account. I am able to get my own Twitter feed using the following code:
-(void) testTwitter {
{
ACAccountStore *accountStore = [[ACAccountStore alloc]init];
if (accountStore != nil)
{
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
if (accountType != nil)
{
[accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error)
{
if (granted)
{
//Succesful Access
NSArray *twitterAccounts = [accountStore accountsWithAccountType:accountType];
if (twitterAccounts != nil)
{
ACAccount *currentAccount = [twitterAccounts objectAtIndex:0];
if (currentAccount != nil)
{
NSString *paraString = [NSString stringWithFormat:#"qlx_corp"];
NSDictionary *parameters = [NSDictionary dictionaryWithObject:paraString forKey:#"username"];
NSString *requestString = #"https://api.twitter.com/1.1/statuses/user_timeline.json";
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:[NSURL URLWithString:requestString] parameters:parameters];
[request setAccount:currentAccount];
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error)
{
if ((error == nil) && ([urlResponse statusCode] == 200))
{
NSArray *twitterFeed = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil];
NSDictionary *firstPost = [twitterFeed objectAtIndex:0];
NSLog(#"firstPost = %#", [firstPost description]);
}
else {
NSLog(#"error: %#",error);
}
}];
}
}
}
else
{
//Access Denied
NSLog(#"access denied");
}
}];
}
}
}
}
But when I substitute the following code for getting another account besides my own, I get this error:
code = 215;
message = "Bad Authentication data.";
And this is the code I substituted for a Successful Access (noted in the comments in posted code):
NSURL* url = [NSURL URLWithString:#"https://api.twitter.com/1.1/statuses/user_timeline.json"];
NSDictionary* params = #{#"count" : #"10", #"screen_name" : #"qlx_corp"};
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter
requestMethod:SLRequestMethodGET
URL:url parameters:params];
[request performRequestWithHandler:^(NSData *responseData,
NSHTTPURLResponse *urlResponse, NSError *error) {
if (!error) {
NSError *jsonError;
NSArray *responseJSON = [NSJSONSerialization
JSONObjectWithData:responseData
options:NSJSONReadingAllowFragments
error:&jsonError];
NSLog(#"response json: %#",responseJSON);
// Show the content of the responseJSON in a view.
}
}];
What am I doing wrong that I am getting this error message and not the public twitter feed that I am requesting. My app asks for permission for Twitter use and it has been granted, so what could be the problem?
I ended up using the Twitter API, since now they support an application only mode that does not require user authentication to display a public Twitter feed. Refer to this link for some more information: Twitter OAuth and accessToken to GET statuses/user_timeline in Objective-C
I tried the below code for getting email of the person who logged in iOS Settings Facebook.
Please help me how to get email from SLRequest.
- (void) getMyDetails {
if (! _accountStore) {
_accountStore = [[ACAccountStore alloc] init];
}
if (! _facebookAccountType) {
_facebookAccountType = [_accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
}
NSDictionary *options = #{ ACFacebookAppIdKey: FB_APP_ID };
[_accountStore requestAccessToAccountsWithType: _facebookAccountType
options: options
completion: ^(BOOL granted, NSError *error) {
if (granted) {
NSArray *accounts = [_accountStore accountsWithAccountType:_facebookAccountType];
_facebookAccount = [accounts lastObject];
NSURL *url = [NSURL URLWithString:#"https://graph.facebook.com/me"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET
URL:url
parameters:nil];
request.account = _facebookAccount;
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:responseData
options:NSJSONReadingMutableContainers
error:nil];
NSLog(#"id: %#", responseDictionary[#"id"]);
}];
}
}];
}
Here is the code tested on iOS 8 that returns email. The solution doesn't require Facebook SDK, although the system grants access to Facebook account only if a user logged in with Facebook in Settings app.
// Required includes
#import Accounts;
#import Social;
// Getting email
ACAccountStore *theStore = [ACAccountStore new];
ACAccountType *theFBAccountType = [theStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSDictionary *theOptions = #{
ACFacebookAppIdKey : #"YOUR_APP_ID",
ACFacebookPermissionsKey : #[#"email"]
};
[theStore requestAccessToAccountsWithType:theFBAccountType options:theOptions completion:^(BOOL granted, NSError *error) {
if (granted) {
ACAccount *theFBAccount = [theStore accountsWithAccountType:theFBAccountType].lastObject;
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET
URL:[NSURL URLWithString:#"https://graph.facebook.com/me"]
parameters:#{#"fields" : #[#"email"]}];
request.account = theFBAccount;
[request performRequestWithHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error == nil && ((NSHTTPURLResponse *)response).statusCode == 200) {
NSError *deserializationError;
NSDictionary *userData = [NSJSONSerialization JSONObjectWithData:data options:0 error:&deserializationError];
if (userData != nil && deserializationError == nil) {
NSString *email = userData[#"email"];
NSLog(#"%#", email);
}
}
}];
}
}];
You can get email id by below mentioned way.
Call Facebook graph API by the help of access token that you got from Account store
And yes, to get email id from Facebook, you need to provide "email" permission while requesting access token, without the permission you won't be able to get email parameter
Here is my code
NSString *FB_EncodedToken = [APP_CONSTANT.facebookToken stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
AFHTTPRequestOperationManager *opearation = [AFHTTPRequestOperationManager manager];
opearation.requestSerializer = [AFHTTPRequestSerializer serializer];
opearation.responseSerializer = [AFJSONResponseSerializer serializer];
NSString *strUrl = [NSString stringWithFormat:#"https://graph.facebook.com/me?"];
NSDictionary *param = [NSDictionary dictionaryWithObjectsAndKeys:FB_EncodedToken,#"access_token", nil];
[opearation GET:strUrl parameters:param success:^(AFHTTPRequestOperation *operation, id responseObject) {
DLogs(#"Description %#",responseObject);
//Lets pasre the JSON data fetched from facebook
[self parseUserDetail:responseObject];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
DLogs(#"Error description %#",error.description);
self.completionHandler(error);
}];
Then parse the data
-(void)parseUserDetail:(NSDictionary *)dict
{
FBProfileBO *profile = [[FBProfileBO alloc] init];
profile.userFirstName = [dict objectForKey:#"first_name"];
profile.userLastName = [dict objectForKey:#"last_name"];
profile.userEmail = [dict objectForKey:#"email"];
profile.userName = [dict objectForKey:#"name"];
profile.userDOB = [dict objectForKey:#""];
profile.facebookId = [dict objectForKey:#"id"];
//Call back methods
self.completionHandler(profile);
profile = nil;
}
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"
Could someone give me some pointers on how to integrate this? my goal is to get list of friends who installed my app (fb app). initially I need to login user to my app first and list friends who have / haven't installed the app.
PS : I don't want to use Facebook SDK. I had nightmares in the past due to facebook did countless time changing the sdk.
===========
UPDATE
I've successfully login and list my facebook friends. But now problem to list my friend who have the app and list picture as well. I tried this :
URL : https://graph.facebook.com/me/friends?friends?fields=id,name,installed,picture
which give me OAuthException : An active access token must be used to query information about the current user. problem.
I tried also in API Graph, it works without mentioned error.
if I try only me/friends works perfectly, it will list down all my friends.
First import Social, Account, SystemConfiguration framework in your project.
Then use this code on your.m file
-(void)facebook
{
self.accountStore = [[ACAccountStore alloc]init];
ACAccountType *FBaccountType= [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSString *key = #"XXXXXXXXXXXXX";//get your key form creating new app in facebook app section
NSDictionary *dictFB = [NSDictionary dictionaryWithObjectsAndKeys:key,ACFacebookAppIdKey,#[#"email"],ACFacebookPermissionsKey, nil];
[self.accountStore requestAccessToAccountsWithType:FBaccountType options:dictFB completion:
^(BOOL granted, NSError *e) {
if (granted)
{
NSArray *accounts = [self.accountStore accountsWithAccountType:FBaccountType];
//it will always be the last object with single sign on
self.facebookAccount = [accounts lastObject];
ACAccountCredential *facebookCredential = [self.facebookAccount credential];
NSString *accessToken = [facebookCredential oauthToken];
NSLog(#"Facebook Access Token: %#", accessToken);
NSLog(#"facebook account =%#",self.facebookAccount);
[self get];
[self getFBFriends];
isFacebookAvailable = 1;
} else
{
//Fail gracefully...
NSLog(#"error getting permission yupeeeeeee %#",e);
sleep(10);
NSLog(#"awake from sleep");
isFacebookAvailable = 0;
}
}];
}
-(void)get
{
NSURL *requestURL = [NSURL URLWithString:#"https://graph.facebook.com/me"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:requestURL parameters:nil];
request.account = self.facebookAccount;
[request performRequestWithHandler:^(NSData *data, NSHTTPURLResponse *response, NSError *error) {
if(!error)
{
NSDictionary *list =[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSLog(#"Dictionary contains: %#", list );
fbID = [NSString stringWithFormat:#"%#", [list objectForKey:#"id"]];
globalFBID = fbID;
gender = [NSString stringWithFormat:#"%#", [list objectForKey:#"gender"]];
playerGender = [NSString stringWithFormat:#"%#", gender];
NSLog(#"Gender : %#", playerGender);
self.globalmailID = [NSString stringWithFormat:#"%#",[list objectForKey:#"email"]];
NSLog(#"global mail ID : %#",globalmailID);
fbname = [NSString stringWithFormat:#"%#",[list objectForKey:#"name"]];
NSLog(#"faceboooookkkk name %#",fbname);
if([list objectForKey:#"error"]!=nil)
{
[self attemptRenewCredentials];
}
dispatch_async(dispatch_get_main_queue(),^{
});
}
else
{
//handle error gracefully
NSLog(#"error from get%#",error);
//attempt to revalidate credentials
}
}];
self.accountStore = [[ACAccountStore alloc]init];
ACAccountType *FBaccountType= [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSString *key = #"451805654875339";
NSDictionary *dictFB = [NSDictionary dictionaryWithObjectsAndKeys:key,ACFacebookAppIdKey,#[#"friends_videos"],ACFacebookPermissionsKey, nil];
[self.accountStore requestAccessToAccountsWithType:FBaccountType options:dictFB completion:
^(BOOL granted, NSError *e) {}];
}
-(void)getFBFriends
{
NSURL *requestURL = [NSURL URLWithString:#"https://graph.facebook.com/me/friends"];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:requestURL parameters:nil];
request.account = self.facebookAccount;
[request performRequestWithHandler:^(NSData *data, NSHTTPURLResponse *response, NSError *error) {
if(!error)
{
NSDictionary *friendslist =[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
for (id facebookFriendList in [friendslist objectForKey:#"data"])
{
NSDictionary *friendList = (NSDictionary *)facebookFriendList;
[facebookFriendIDArray addObject:[friendList objectForKey:#"id"]];
}
if([friendslist objectForKey:#"error"]!=nil)
{
[self attemptRenewCredentials];
}
dispatch_async(dispatch_get_main_queue(),^{
});
}
else
{
//handle error gracefully
NSLog(#"error from get%#",error);
//attempt to revalidate credentials
}
}];
self.accountStore = [[ACAccountStore alloc]init];
ACAccountType *FBaccountType= [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSString *key = #"451805654875339";
NSDictionary *dictFB = [NSDictionary dictionaryWithObjectsAndKeys:key,ACFacebookAppIdKey,#[#"friends_videos"],ACFacebookPermissionsKey, nil];
[self.accountStore requestAccessToAccountsWithType:FBaccountType options:dictFB completion:
^(BOOL granted, NSError *e) {}];
}
-(void)accountChanged:(NSNotification *)notification
{
[self attemptRenewCredentials];
}
-(void)attemptRenewCredentials
{
[self.accountStore renewCredentialsForAccount:(ACAccount *)self.facebookAccount completion:^(ACAccountCredentialRenewResult renewResult, NSError *error){
if(!error)
{
switch (renewResult) {
case ACAccountCredentialRenewResultRenewed:
NSLog(#"Good to go");
[self get];
break;
case ACAccountCredentialRenewResultRejected:
NSLog(#"User declined permission");
break;
case ACAccountCredentialRenewResultFailed:
NSLog(#"non-user-initiated cancel, you may attempt to retry");
break;
default:
break;
}
}
else{
//handle error gracefully
NSLog(#"error from renew credentials%#",error);
}
}];
}
I finally got it, apparently you cannot append inside the URL. you need to pass the fields in parameter inside SLRequest
NSURL *requestURL = [NSURL URLWithString:#"https://graph.facebook.com/me/friends"];
NSDictionary *param=[NSDictionary dictionaryWithObjectsAndKeys:#"picture,id,name,installed",#"fields", nil];
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET
URL:requestURL
parameters:param];
I'm developing a Twitter Feed View for an iOS App. I found TWRequest and it works exactly like that which i was looking for. But: i get an Notice: "TWRequest is deprecated: first deprecated in iOS 6.0". What should I use instead?
On iOS 6 you should use the Social.framework. This has a class named SLRequest.
You use it almost in the same way as the deprecated TWRequest, but you need to specify that it's a twitter request as opposed to a facebook request.
The entire Twitter.framework became deprecated as of iOS 6, since Apple added Facebook and Weibo (a Chinese social network) to iOS 6, they grouped all social classes into the new Social.framework.
Note you must specify the service type for Twitter/Facebook, Example:
SLRequest *aRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter
requestMethod:SLRequestMethodPOST
URL:myurl
parameters:myparams];
Be sure to check out the documentation.
Here is a complete code to upload text + image to your Twitter Account using Twitter api
UIImage *img = [UIImage imageNamed:#"twitterImage.png"];
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[account requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {
if (granted == YES) {
// Populate array with all available Twitter accounts
NSArray *arrayOfAccounts = [account accountsWithAccountType:accountType];
if ([arrayOfAccounts count] > 0) {
ACAccount *acct = [arrayOfAccounts objectAtIndex:0];
NSDictionary *message = #{#"status": #"From my app"};
NSURL *requestURL = [NSURL URLWithString:#"https://upload.twitter.com/1/statuses/update_with_media.json"];
SLRequest *postRequest = [SLRequest
requestForServiceType:SLServiceTypeTwitter
requestMethod:SLRequestMethodPOST
URL:requestURL parameters:message];
NSData *data = UIImagePNGRepresentation(img);
[postRequest addMultipartData:data withName:#"media" type:#"image/png" filename:#"TestImage"];
postRequest.account = acct;
[postRequest performRequestWithHandler:
^(NSData *responseData, NSHTTPURLResponse
*urlResponse, NSError *error)
{
if (error) {
NSLog(#"%#",error.description);
}
else {
NSLog(#"Upload Sucess !");
}
}];
}
}
}];
In case you plan on integrating TwitterKit by Twitter to perform the tweets via your custom twitter app then this might help you.
https://stackoverflow.com/a/28602749/1740354
Another alternative is to use Twitter API. You should have Twitter framework for that.
Then do following code:
NSString *statusesShowEndpoint = #"https://api.twitter.com/1.1/statuses/update.json";
NSDictionary *params = #{#"status": #"Hello, my first autopost tweet..."};
NSError *clientError;
NSURLRequest *request = [[[Twitter sharedInstance] APIClient]
URLRequestWithMethod:#"POST"
URL:statusesShowEndpoint
parameters:params
error:&clientError];
if (request) {
[[[Twitter sharedInstance] APIClient]
sendTwitterRequest:request
completion:^(NSURLResponse *response,
NSData *data,
NSError *connectionError) {
if (data) {
// handle the response data e.g.
NSError *jsonError;
NSDictionary *dicResponse = [NSJSONSerialization
JSONObjectWithData:data
options:0
error:&jsonError];
NSLog(#"%#",[dicResponse description]);
}
else {
NSLog(#"Error code: %ld | Error description: %#", (long)[connectionError code], [connectionError localizedDescription]);
}
}];
}
else {
NSLog(#"Error: %#", clientError);
}