How can i send the URL to twitter friend in iOS.
I can send direct message but it does not allow me to send URL in it.
Here is my code for Posting Drirect message to Twitter Friend and its working.
-(void)postMessageToFriend:(NSString *)ID withMessage:(NSString *)message {
NotificatioName = notificationNameStr;
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error) {
if (granted && !error) {
NSArray *accountsListAry = [accountStore accountsWithAccountType:accountType];
int NoOfAccounts = [accountsListAry count];
if (NoOfAccounts >0) {
NSURL *url = [NSURL URLWithString:#"https://api.twitter.com/1.1/direct_messages/new.json"];
twitterAccount = [accountsListAry lastObject];
NSDictionary *p =#{#"status":#"Posted",#"screen_name":ID, #"text":message};
SLRequest *postRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:url parameters:p];
[postRequest setAccount:twitterAccount];
[postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResposnse, NSError *error){
if (error) {
NSLog(#"error : %#",error);
}else{
NSError *jsonError = nil;
NSString * responseStr = [[NSString alloc] initWithData:responseData encoding:NSJSONWritingPrettyPrinted];
NSArray *friendsdata =
[NSJSONSerialization JSONObjectWithData: [responseStr dataUsingEncoding:NSUTF8StringEncoding]
options: NSJSONReadingMutableContainers
error: &jsonError];
NSLog(#"response value is: %# %d ",friendsdata,[urlResposnse statusCode]);
}
}];
}
}
}];
}
But If i try to add URL in my message than its return me this error
{
errors = (
{
code = 226;
message = "This request looks like it might be automated. To protect our users from spam and other malicious activity, we can't complete this action right now. Please try again later.";
}
);
}
I think it has nothing to do with your code, but with Twitter. Apparently, they're not allowing to send links in direct messages. https://support.twitter.com/articles/14606-posting-or-deleting-direct-messages.
You can't do that even as a user from the official twitter client or from their website. AFAIK, it's a known issue and they're said to be working on it. But it's been long since they said that.
Your request is refused by Twitter because it is signed with OS X consumer tokens, as all instances of SLRequest are.
If you want to send URLs in direct messages, you have to sign your requests with the consumer tokens from an official Twitter client.
This cannot be done with SLRequest but can be done with third-party libraries such as STTwitter.
It is not a proper answer but stil i am sharing it. In my case I have to share the link of my app in the direct message. Message with url in the message text doesn't work but link of any twitter account can be shared with the message text. So I made a twitter acc for my app and give the link there.
Related
As a part of my project I need to show the list of tweets in iOS app. I tried with the below code but its returning the JSON. The same code is works fine with version 1. Now the twitter api version is 1.1 and one another warning I got that TWRequest is deprecated. This deprecation is not the issue of this even I got same thing with SLRequest. Here my problem is I need to fetch the JSON of Particular user tweets without authentication or with authentication
TWRequest *postequest=[[TWRequest alloc]initWithURL:[NSURL URLWithString:#"https://api.twitter.com/1.0/statuses/user_timeline.json?screen_name=coolCracker&count=2"] parameters:nil requestMethod:TWRequestMethodGET];
[postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSString *output;
if ([urlResponse statusCode]==200) {
NSError *err;
NSDictionary *PublicTimeline=[NSJSONSerialization JSONObjectWithData:responseData options:0 error:&err];
output=[NSString stringWithFormat:#"HTTP response status: %li\nPublic timeline:\n%#",(long)[urlResponse statusCode],PublicTimeline];
}
else
{
output=[NSString stringWithFormat:#"No feed HTTP response was: %li\n",(long)[urlResponse statusCode]];
}
[self performSelectorOnMainThread:#selector(displayResults:) withObject:output waitUntilDone:NO];
}];
-(void)displayResults:(NSString *)text
{
NSLog(#"tweets feed %#",text);
}
I used this in my work and it worked pretty well. Use STTwitter. Download STTwitter files here.
Place this in your view didload:
STTwitterAPI *twitter = [STTwitterAPI twitterAPIAppOnlyWithConsumerKey:#"your consumer key"
consumerSecret:#"your secret key"];
[twitter verifyCredentialsWithSuccessBlock:^(NSString *bearerToken) {
[twitter getUserTimelineWithScreenName:#"your twitter account name"
successBlock:^(NSArray *statuses) {
self.twitterFeedList = [NSMutableArray arrayWithArray:statuses];
[self->listView reloadData];
} errorBlock:^(NSError *error) {
NSLog(#"%#", error.debugDescription);
}];
} errorBlock:^(NSError *error) {
NSLog(#"%#", error.debugDescription);
}];
Hi Below code is working for me. Though TWRequest is deprecated it works for now. Later you can change it to SLRequest.
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *twitterType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
// Request access from the user to use their Twitter accounts.
[accountStore requestAccessToAccountsWithType:twitterType options:nil completion:^(BOOL granted, NSError *error) {
if (granted == YES){
//get accounts to use.
NSArray *accounts = [accountStore accountsWithAccountType:twitterType];
if ([accounts count] > 0) {
NSLog(#"account: %#", accounts);
ACAccount *loggedinaccount;
loggedinaccount = accounts[0];
// get tweets
TWRequest *postRequest=[[TWRequest alloc]initWithURL:[NSURL URLWithString:#"https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=HuntEthane&count=2"] parameters:nil requestMethod:TWRequestMethodGET];
[postRequest setAccount:loggedinaccount];
[postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSString *output;
if ([urlResponse statusCode]==200) {
NSError *err;
NSDictionary *PublicTimeline=[NSJSONSerialization JSONObjectWithData:responseData options:0 error:&err];
output=[NSString stringWithFormat:#"HTTP response status: %li\nPublic timeline:\n%#",(long)[urlResponse statusCode],PublicTimeline];
}
else
{
output=[NSString stringWithFormat:#"No feed HTTP response was: %li\n",(long)[urlResponse statusCode]];
}
[self performSelectorOnMainThread:#selector(displayResults:) withObject:output waitUntilDone:NO];
}];
}
}else{
// show alert to inser user_name and password to login on twitter
UIAlertView *alertTwitterAccount = [[UIAlertView alloc]
initWithTitle:#"Enter with your twitter account"
message:nil
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Login", nil];
[alertTwitterAccount setAlertViewStyle:UIAlertViewStyleLoginAndPasswordInput];
[[alertTwitterAccount textFieldAtIndex:0] setPlaceholder:#"User"];
[alertTwitterAccount setDelegate:self];
[alertTwitterAccount setTag:1];
[alertTwitterAccount show];
}
}];
Remember to add below frameworks to make this code work.
Twitter.FrameWork
Social.FrameWork
Accounts.Framework
Security.FrameWork
If you want to use SLRequest instead of TWRequest, replace request statement with below statement
SLRequest *postRequest = [SLRequest
requestForServiceType:SLServiceTypeTwitter
requestMethod:SLRequestMethodGET
URL:[NSURL URLWithString:#"https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=HuntEthane&count=2"]parameters:nil];
Moving forward the easiest way is adoption of Fabric.io from Tweeter as the development platform includes Tweeter embeds: https://get.fabric.io/native-social
"The easiest way to bring Twitter content into your app."
Honestly, I did not look into authentication part needed for Fabric.io.
Otherwise you need to follow and respect rules for accessing Twitter REST APIs or Streaming APIs, both well documented. OAuth authentication is required.
If you wish to avoid authentication in your app you can write a simple web REST API that will take care of authentication and serve (selected) tweets to your iOS app.
First, you’ll need to register an app with Twitter
Write down your Consumer Key and Consumer Secret
Write a simple server API (proxy) in your language of choice.
I personally prefer JavaScript on Node.js. Consider using libraries like express.js and oauth available on npm, but you can search npm for any other implemented Twitter proxy/API.
The code essentially consists of getting an OAuth Access token and then calling selected twitter APIs, and respecting ratelimits by caching results.
I'm new to iOS development so I'm not clear about how to go about this: with the username and password provided by the user, check if the credentials is a valid twitter account. Log the user in and retrieve the users followers, account information, timeline and tweets.
I know I haven't tried anything, but it's just because I have no clue where to start. I did some searching up on it and found something about OAuth. but most of the stuff out there is for iOS 5.
Have a look at the Social.framework (iOS6 and above). It manages authentication to several social networking sites, including twitter. Once the user has created an account and granted your app access to it, you can use SLRequest to perform authenticated twitter (or whatever) http requests without having to directly use Oauth.
First you get the ACAccount.
#import <Social/Social.h> // SLRequest
- (void)getTwitter {
ACAccountType *accountType = [_accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[_accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error) {
if (granted) {
// access granted, get account info
NSArray *accounts = [_accountStore accountsWithAccountType:accountType];
ACAccount *account = [accounts lastObject];
// yay, now you can use account for authenticated twitter requests
} else {
NSLog(#"Access not granted: %#\n", error);
}
}
];
}
Then you can start making authenticated requests, e.g. get account info
- (void)getTwitterAccount:(ACAccount *)account {
NSString *get = #"https://api.twitter.com/1.1/account/verify_credentials.json";
NSURL *url = [NSURL URLWithString:get];
NSDictionary *parms = #{ #"include_entities" : #"false", #"skip_status" : #"true" };
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:url parameters:parms ];
request.account = account;
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error){
if(!error) {
NSLog(#"response: %#\n", [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]);
} else {
NSLog(#"performRequestWithHandler error %#\n", error);
}
}];
}
See the Twitter API docs for timeline, tweets, etc.
I'm trying to get the feed of a public Facebook page using the Graph API and I can't figure out how to do so without prompting the user for permissions.
The following code works, but prompts the user for permissions:
- (void)doFacebookAuthCompletion:(void (^)(ACAccount* account))completion
{
ACAccountStore* accountStore = [[ACAccountStore alloc] init];
ACAccountType* accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
NSDictionary* fbOptions = #{
ACFacebookAppIdKey: #"<app-id-key>",
ACFacebookPermissionsKey: #[ #"email" ]
};
[accountStore requestAccessToAccountsWithType:accountType
options:fbOptions
completion:^(BOOL granted, NSError *error) {
if (granted) {
completion([[accountStore accountsWithAccountType:accountType] lastObject]);
} else {
NSLog(#"%#", [error localizedDescription]);
}
}];
}
- (void)updateFeed
{
[self doFacebookAuthCompletion:^(ACAccount* account) {
// What we want to get
NSURL* url = [NSURL URLWithString:#"https://graph.facebook.com/microsoft/feed"];
NSDictionary* parameters = #{ };
// The request
SLRequest* request = [SLRequest requestForServiceType:SLServiceTypeFacebook
requestMethod:SLRequestMethodGET
URL:url
parameters:parameters];
[request setAccount:account];
// Send it
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if (error) {
NSLog(#"%#", [error localizedDescription]);
} else {
NSString *dataString = [[NSString alloc] initWithData:responseData encoding:NSStringEncodingConversionAllowLossy];
NSLog(#"Response Data: %#", dataString);
}
}];
}];
}
I have even tried using the app token referenced at https://developers.facebook.com/docs/reference/api/page/ that is only safe to use server-side, but still didn't get anywhere. This code:
- (void)doFacebookAuthCompletion:(void (^)(ACAccount* account))completion
{
ACAccountStore* accountStore = [[ACAccountStore alloc] init];
ACAccountType* accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
ACAccount* account = [[ACAccount alloc] initWithAccountType:accountType];
account.credential = [[ACAccountCredential alloc] initWithOAuthToken:#"<app-token>" tokenSecret:#"<app-secret>"];
completion(account);
}
Gives the following output:
Response Data: {"error":{"message":"An access token is required to request this resource.","type":"OAuthException","code":104}}
While the Graph API Explorer works just fine when given the same <app-token> (it doesn't ask for the secret like - initWithOAuthToken:tokenSecret: does).
Even if this approach worked, it would not be safe to release.
I'm stuck now. Help, please?
I can't give a complete answer because I've never used iOS, but on the Facebook side of things, the Graph API won't let you obtain anything without some kind of token. Secure or not, the only way to do that is to use your app id and secret to generate a token which can then be used. You can get one using, for example:
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID&client_secret=YOUR_APP_SECRET&
grant_type=client_credentials
I'm making an iPhone app where I get all feeds of a certain user. Now I was wondering if it's possible to do a retweet when you push a button? I'm using the social framework. After some searching through the social framework API, I didn't found anything.
Apple's limited Twitter API doesn't seem to cover retweets.
To retweet in iOS you would need to use Twitter's API
It looks like you would need to send the POST request yourself and it would look something like
http://api.twitter.com/1/statuses/retweet/3962807808.json // Taken from API page.
I've also found this SO post, but there doesn't seem to be an accepted answer
How to implement RETWEET in ios 5?
Here's some sample code for retweeting from Cocoanetics
- (void)_retweetMessage:(TwitterMessage *)message
{
NSString *retweetString = [NSString stringWithFormat:#"http://api.twitter.com/1/statuses/retweet/%#.json", message.identifier];
NSURL *retweetURL = [NSURL URLWithString:retweetString];
TWRequest *request = [[TWRequest alloc] initWithURL:retweetURL parameters:nil requestMethod:TWRequestMethodPOST];
request.account = _usedAccount;
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if (responseData)
{
NSError *parseError = nil;
id json = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&parseError];
if (!json)
{
NSLog(#"Parse Error: %#", parseError);
}
else
{
NSLog(#"%#", json);
}
}
else
{
NSLog(#"Request Error: %#", [error localizedDescription]);
}
}];
}
EDIT: Keab42 pointed out the link is for the Twitter API which will be deprecated early next year. Here's the updated API page. https://dev.twitter.com/docs/api/1.1/get/statuses/retweets/%3Aid
Essentially what I want is for the app, once the user has allowed access to their Twitter account, to be able to tweet whatever the user has selected in a UITableView. Ideally I'd like to use the Twitter framework in iOS 5, but the main issue I'm having is the modal view controller for tweeting. Is this optional? Is it possible to tweet without it and if not, what do you suggest I do?
Thanks!
It's definitely possible to tweet without it, the following is in production iOS 5 apps. It even takes the user to the requisite section of preferences if they haven't registered an account.
- (void)postToTwitter
{
// Create an account store object.
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
// Create an account type that ensures Twitter accounts are retrieved.
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
// Request access from the user to use their Twitter accounts.
[accountStore requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {
if(granted) {
// Get the list of Twitter accounts.
NSArray *accountsArray = [accountStore accountsWithAccountType:accountType];
if ([accountsArray count] > 0) {
// Grab the initial Twitter account to tweet from.
ACAccount *twitterAccount = [accountsArray objectAtIndex:0];
TWRequest *postRequest = nil;
postRequest = [[TWRequest alloc] initWithURL:[NSURL URLWithString:#"http://api.twitter.com/1/statuses/update.json"] parameters:[NSDictionary dictionaryWithObject:[self stringToPost] forKey:#"status"] requestMethod:TWRequestMethodPOST];
// Set the account used to post the tweet.
[postRequest setAccount:twitterAccount];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
[postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^(void) {
if ([urlResponse statusCode] == 200) {
Alert(0, nil, #"Tweet Successful", #"Ok", nil);
}else {
Alert(0, nil, #"Tweet failed", #"Ok", nil);
}
});
}];
});
}
else
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"prefs:root=TWITTER"]];
}
}
}];
}
This would be an updated version using SLRequest instead of TWRequest, which was deprecated in iOS 6.
Note this needs the Social and Accounts framework to be added to your project...
- (void) postToTwitterInBackground {
// Create an account store object.
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
// Create an account type that ensures Twitter accounts are retrieved.
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
// Request access from the user to use their Twitter accounts.
[accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error) {
if(granted) {
// Get the list of Twitter accounts.
NSArray *accountsArray = [accountStore accountsWithAccountType:accountType];
if ([accountsArray count] > 0) {
// Grab the initial Twitter account to tweet from.
ACAccount *twitterAccount = [accountsArray objectAtIndex:0];
SLRequest *postRequest = nil;
// Post Text
NSDictionary *message = #{#"status": #"Tweeting from my iOS app!"};
// URL
NSURL *requestURL = [NSURL URLWithString:#"https://api.twitter.com/1.1/statuses/update.json"];
// Request
postRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:requestURL parameters:message];
// Set Account
postRequest.account = twitterAccount;
// Post
[postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSLog(#"Twitter HTTP response: %i", [urlResponse statusCode]);
}];
}
}
}];
}
Update: The TwitterKit in Fabric by Twitter is quite handy and if you aim to post from your Twitter app when the user tries to Tweet in your app then it might be a good option to consider.
(YES, this method will allow you to post to twitter without any dialog box or confirmation).
The TwitterKit will handle the permissions part and using the TWTRAPIClient we perform the tweet through the Twitter rest APIs.
//Needs to performed once in order to get permissions from the user to post via your twitter app.
[[Twitter sharedInstance]logInWithCompletion:^(TWTRSession *session, NSError *error) {
//Session details can be obtained here
//Get an instance of the TWTRAPIClient from the Twitter shared instance. (This is created using the credentials which was used to initialize twitter, the first time)
TWTRAPIClient *client = [[Twitter sharedInstance]APIClient];
//Build the request that you want to launch using the API and the text to be tweeted.
NSURLRequest *tweetRequest = [client URLRequestWithMethod:#"POST" URL:#"https://api.twitter.com/1.1/statuses/update.json" parameters:[NSDictionary dictionaryWithObjectsAndKeys:#"TEXT TO BE TWEETED", #"status", nil] error:&error];
//Perform this whenever you need to perform the tweet (REST API call)
[client sendTwitterRequest:tweetRequest completion:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
//Check for the response and update UI according if necessary.
}];
}];
Hope this helps.
The accepted answer is no longer valid due to several changes. This one works with iOS 10, Swift 3, and version 1.1 of Twitter's API.
** UPDATE **
This answer has been updated as the previous one relied upon a deprecated Twitter endpoint.
import Social
import Accounts
func postToTwitter() {
let accountStore = ACAccountStore()
let accountType = accountStore.accountType(withAccountTypeIdentifier: ACAccountTypeIdentifierTwitter)
accountStore.requestAccessToAccounts(with: accountType, options: nil) { (granted, error) in
if granted, let accounts = accountStore.accounts(with: accountType) {
// This will default to the first account if they have more than one
if let account = accounts.first as? ACAccount {
let requestURL = URL(string: "https://api.twitter.com/1.1/statuses/update.json")
let parameters = ["status" : "Tweet tweet"]
guard let request = SLRequest(forServiceType: SLServiceTypeTwitter, requestMethod: .POST, url: requestURL, parameters: parameters) else { return }
request.account = account
request.perform(handler: { (data, response, error) in
// Check to see if tweet was successful
})
} else {
// User does not have an available Twitter account
}
}
}
}
This is the API that is being used.