I am attempting to post to Twitter without user interaction (as this would force the user to hit 'Send' multiple times.).
The following is my code:
- (void) postToTwitterUsingTWRequest: (NSDictionary*) appDictionary {
NSString *trackName = [appDictionary objectForKey:#"trackName"];
NSString *trackId = [[appDictionary objectForKey:#"trackId"] description];
NSString *artworkUrl512 = [appDictionary objectForKey:#"artworkUrl512"];
NSMutableString *requestUrlString = [NSMutableString new];
[requestUrlString appendFormat:#"http://itunes.apple.com/%#",[[NSLocale currentLocale] objectForKey:NSLocaleCountryCode]];
[requestUrlString appendFormat:#"/app/%#", trackName];
[requestUrlString appendFormat:#"/id%#?mt=8", trackId];
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:
ACAccountTypeIdentifierTwitter];
[account requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error) {
if (granted == YES) {
NSArray *arrayOfAccounts = [account
accountsWithAccountType:accountType];
if ([arrayOfAccounts count] > 0)
{
ACAccount *twitterAccount = [arrayOfAccounts lastObject];
TWRequest *postRequest = [[TWRequest alloc] initWithURL:[NSURL URLWithString:#"https://upload.twitter.com/1/statuses/update_with_media.json"] parameters:nil requestMethod:TWRequestMethodPOST];
//NSData *tempData = [NSData dataWithContentsOfURL:[NSURL URLWithString: #"http://eborkdev.com/wp-content/uploads/2012/05/logo.png"]];
NSData *tempData = [NSData dataWithContentsOfURL:[NSURL URLWithString: artworkUrl512]];
[postRequest addMultiPartData:tempData withName:#"media" type:#"image/png"];
tempData = [[NSString stringWithFormat:#"%# was recommended using Tell A Friend (http://link_to_tell_a_friend.com). \n %#", trackName, requestUrlString] dataUsingEncoding:NSUTF8StringEncoding];
[postRequest addMultiPartData:tempData withName:#"status" type:#"text/plain"];
[postRequest setAccount:twitterAccount];
isPostingToTwitter = true;
[postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
isPostingToTwitter = false;
NSLog(#"Twitter HTTP response: %i", [urlResponse statusCode]);
}];
}
else {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"No Twitter accounts found. Please ensure that there are accounts present, and try again."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}
}];
}
I am looping through this in order to make the multiple calls like so:
for (NSDictionary* appDictionary in selectedApps) {
[self postToTwitterUsingTWRequest:appDictionary];
}
Sometimes it allows me to send one giving me the 200 statusCode. But when sending multiple, I get 403 and 200, or just 403.
How can I fix this?
You should read the following links before proceeding, the thing you are trying to do is called spamming..
https://dev.twitter.com/docs/error-codes-responses
https://support.twitter.com/articles/15364-about-twitter-limits-update-api-dm-and-following
TRY THIS
AT .H
#import <Twitter/Twitter.h>
#import <Accounts/Accounts.h>
- (void)sendTweet
{
Class tweeterClass = NSClassFromString(#"TWTweetComposeViewController");
if(tweeterClass != nil) { // check for Twitter integration
if ([TWTweetComposeViewController canSendTweet])
{
// Create account store, followed by a twitter account identifier
// At this point, twitter is the only account type available
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
// Request access from the user to access their Twitter account
[account requestAccessToAccountsWithType:accountType withCompletionHandler:^(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)
{
// Keep it simple, use the first account available
ACAccount *acct = [arrayOfAccounts objectAtIndex:0];
// Build a twitter request
TWRequest *postRequest = [[TWRequest alloc] initWithURL:
[NSURL URLWithString:#"http://api.twitter.com/1/statuses/update.json"]
parameters:[NSDictionary dictionaryWithObject:str_tweet
forKey:#"status"] requestMethod:TWRequestMethodPOST];
// Post the request
[postRequest setAccount:acct];
// Block handler to manage the response
[postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error)
{
// NSString *response = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
// NSLog(#"Twitter response: %#, HTTP response: %#", response, [urlResponse statusCode]);
}];
}
}
}];
}
else
{
NSLog(#"Unable to tweet!");
}
}
}
Related
I have a GIF image and want to share it in twitter but unfortunately it's not working.
When i posted the image using the twitter api on the dev.twitter.com site it works fine and animates.
However i want to post the image using the Twitter IOS App/API. Does anybody know how to do this?
Thanks in advance.
- (void)postImage:(UIImage *)image withStatus:(NSString *)status url:(NSURL*)urlData {
// UIImage *img = [UIImage animatedImageNamed:#"test.gif" duration:3.0];
NSURL *url = [NSURL URLWithString:#"https://api.twitter.com/1.1/statuses/update_with_media.json"];
NSMutableDictionary *paramater = [[NSMutableDictionary alloc] init];
//set the parameter here. to see others acceptable parameters find it at twitter API here : http://bit.ly/Occe6R
[paramater setObject:status forKey:#"status"];
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error) {
if (granted == YES) {
NSArray *accountsArray = [accountStore accountsWithAccountType:accountType];
if ([accountsArray count] > 0) {
ACAccount *twitterAccount = [accountsArray lastObject];
SLRequest *postRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:url parameters:paramater];
NSData *imageData = [NSData dataWithContentsOfURL:urlData]; // GIF89a file
[postRequest addMultipartData:imageData withName:#"media[]" type:#"image/gif" filename:#"animated.gif"];
[postRequest setAccount:twitterAccount]; // or postRequest.account = twitterAccount;
[postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSString *output = [NSString stringWithFormat:#"HTTP response status: %i", [urlResponse statusCode]];
NSLog(#"output = %#",output);
dispatch_async(dispatch_get_main_queue(), ^{
});
}];
}
}
}];
}
Just call above method like this
[self postImage:nil withStatus:#"Your Text" url:assetURL]
Actually update_with_media is deprecated.
From now you need to use upload.json + update.json only. It is a 2-tier process.
I wrote a tutorial on how to do this with complete codes. See here:
http://xcodenoobies.blogspot.my/2016/01/how-to-using-slrequest-to-upload-image.html
I would like to get user profile information using SLRequest in twitter?
Currently I am coding like
NSURL *url = [NSURL URLWithString:#"https://api.twitter.com/1.1/users/show.json"];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:#"ali",#"screen_name",nil];
account = [[ACAccountStore alloc] init];
ACAccountType *twitterAccountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
NSArray *twitterAccounts = [account accountsWithAccountType:twitterAccountType];
// Runing on iOS 6
if ([LoginViewController isTwitterAvailable])
{
NSLog(#"In the IFF...... ");
[account requestAccessToAccountsWithType:twitterAccountType options:NULL completion:^(BOOL granted, NSError *error)
{
NSLog(#"in body ");
if (granted)
{
NSLog(#"in granted ..");
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:url parameters:params];
[request setAccount:[twitterAccounts lastObject]];
dispatch_async(dispatch_get_main_queue(), ^
{
[NSURLConnection sendAsynchronousRequest:request.preparedURLRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response1, NSData *data, NSError *error)
{
dispatch_async(dispatch_get_main_queue(), ^
{
if (data)
{
//NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] ;
//NSLog(#"data:%#",string);
NSError* error;
NSDictionary* dicUser = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions
error:&error];
It returns the whole of the info, not profile info,
How can I get profile info of user who is getting sign in ?
Thanks
Try folowing code giving from one of the live project, you can modify as per your existing structure. Let me know in case of any problem.
_accountStore = [[ACAccountStore alloc] init]; //Declare accountStore as property and initialize
ACAccountType *accountType = [_accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[_accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error){
if (granted){
NSArray *accounts = [_accountStore accountsWithAccountType:accountType];
if (accounts.count > 0){
ACAccount *twitterAccount = [accounts lastObject];
NSDictionary *dict1 = [twitterAccount dictionaryWithValuesForKeys:[NSArray arrayWithObject:#"properties"]];
NSDictionary *properties = dict1[#"properties"];
NSDictionary *returnDict = #{#"TwitterID":properties[#"user_id"],#"UserName":twitterAccount.username};
NSLog(#"Profile details->%#",properties);
}else{
NSMutableDictionary* details = [NSMutableDictionary dictionary];
[details setValue:kTwitterErrorMsg forKey:NSLocalizedDescriptionKey];
error = [NSError errorWithDomain:#"Domain" code:error.code userInfo:details];
NSLog(#"Error occured->%#",error.localizedDescription);
}
} else {
NSMutableDictionary* details = [NSMutableDictionary dictionary];
if(error.code == ACErrorAccountNotFound){
[details setValue:kTwitterErrorMsg forKey:NSLocalizedDescriptionKey];
}else if(error.code == ACErrorPermissionDenied || error.code == ACErrorAccessDeniedByProtectionPolicy) {
[details setValue:kTwitterAccessDeniedMsg forKey:NSLocalizedDescriptionKey];
}else {
[details setValue:kTwitterErrorMsg forKey:NSLocalizedDescriptionKey];
}
error = [NSError errorWithDomain:#"Domain" code:error.code userInfo:details];
NSLog(#"Error occured->%#",error.localizedDescription);
}
}];
Few macros
#define kTwitterErrorMsg #"Please set your Twitter account in Settings."
#define kTwitterAccessDeniedMsg #"Twitter Access denied."
I'm trying to get the user's Twitter timeline using the Twitter API in iOS SDK and got an error saying:
code = 92; message = "SSL is required";
I googled the error and I found this page on the Twitter API website, but I have no idea how to use it in iOS.
Here's my code:
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[account requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error)
{
if (granted == YES){
NSArray *arrayOfAccounts = [account accountsWithAccountType:accountType];
if ([arrayOfAccounts count] > 0) {
ACAccount *twitterAccount = [arrayOfAccounts lastObject];
NSURL *requestAPI = [NSURL URLWithString:#"http://api.twitter.com/1.1/statuses/user_timeline.json"];
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
[parameters setObject:#"100" forKey:#"count"];
[parameters setObject:#"1" forKey:#"include_entities"];
SLRequest *posts = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:requestAPI parameters:parameters];
posts.account = twitterAccount;
[posts performRequestWithHandler:
^(NSData *response, NSHTTPURLResponse
*urlResponse, NSError *error)
{
// The NSJSONSerialization class is then used to parse the data returned and assign it to our array.
array = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableLeaves error:&error];
if (array.count != 0) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"%#",array);
});
}
}];
}
} else {
// Handle failure to get account access
NSLog(#"%#", [error localizedDescription]);
}
}];
Is there a way to solve this problem?
Use "https" in your URL:
https://api.twitter.com/1.1/statuses/user_timeline.json
Docs: https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline
Is there a way to get user data (first name, last name, and email) from Twitter using the iOS social/accounts frameworks? I'm able to do it with Facebook, but every SLRequest I make to Twitter returns an empty array.
Here's the code I've got right now. I've tried several URLS with varying parameters, but I haven't had any luck.
- (void)populateTwitterAccount {
NSURL *twitterURL = [NSURL URLWithString:#"https://api.twitbridge.com/1.1/users/show.json"];
SLRequest *twitterRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:twitterURL parameters:nil];
[twitterRequest setAccount:self.twitterAccount];
[twitterRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
NSString *accountDataString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"%#", accountDataString);
}];
}
yes we can.
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
NSString *message = _textView.text;
//hear before posting u can allow user to select the account
NSArray *arrayOfAccons = [account accountsWithAccountType:accountType];
for(ACAccount *acc in arrayOfAccons)
{
NSLog(#"%#",acc.username);
NSDictionary *properties = [acc dictionaryWithValuesForKeys:[NSArray arrayWithObject:#"properties"]];
NSDictionary *details = [properties objectForKey:#"properties"];
NSLog(#"user name = %#",[details objectForKey:#"fullName"]);//full name
NSLog(#"user_id = %#",[details objectForKey:#"user_id"]);//user id
}
for email id,
we can also able to get user email id see the updated answer hear
Yes, you can get user information using ACAccountStore,
You have to retain ACAccountStore:
.h
#property (nonatomic, strong) ACAccountStore *account;
.m
NSUrl *url = [NSURL URLWithString:#"https://api.twitter.com/1.1/users/show.json"];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:twittername,#"screen_name",nil];
account = [[ACAccountStore alloc] init];
ACAccountType *twitterAccountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
NSArray *twitterAccounts = [account accountsWithAccountType:twitterAccountType];
// Runing on iOS 6
if (NSClassFromString(#"SLComposeViewController") && [SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter])
{
[account requestAccessToAccountsWithType:twitterAccountType options:NULL completion:^(BOOL granted, NSError *error)
{
if (granted)
{
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:url parameters:params];
[request setAccount:[twitterAccounts lastObject]];
dispatch_async(dispatch_get_main_queue(), ^
{
[NSURLConnection sendAsynchronousRequest:request.preparedURLRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response1, NSData *data, NSError *error)
{
dispatch_async(dispatch_get_main_queue(), ^
{
if (data)
{
// [self loadData:data];
NSString* newStr = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] ;
NSLog(#"data:%#",newStr);
}
});
}];
});
}
}];
}
else if (NSClassFromString(#"TWTweetComposeViewController") && [TWTweetComposeViewController canSendTweet]) // Runing on iOS 5
{
[account requestAccessToAccountsWithType:twitterAccountType withCompletionHandler:^(BOOL granted, NSError *error)
{
if (granted)
{
TWRequest *request = [[TWRequest alloc] initWithURL:url parameters:params requestMethod:TWRequestMethodGET];
[request setAccount:[twitterAccounts lastObject]];
dispatch_async(dispatch_get_main_queue(), ^
{
[NSURLConnection sendAsynchronousRequest:request.signedURLRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response1, NSData *data, NSError *error)
{
dispatch_async(dispatch_get_main_queue(), ^
{
if (data)
{
NSString* newStr = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSLog(#"data:%#",newStr); }
});
}];
});
}
}];
}
}
I am using the following code to post to Twitter using SLRequest and ACAccounts in iOS 6. The issue is that when there is more than one account, I have no control over which one gets access granted. Suggestions for letting the user pick the account they want to post from?
-(void)twitteraccess {
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account accountTypeWithAccountTypeIdentifier:
ACAccountTypeIdentifierTwitter];
[account requestAccessToAccountsWithType:accountType options:nil
completion:^(BOOL granted, NSError *error)
{
if (granted == YES)
{
NSArray *arrayOfAccounts = [account
accountsWithAccountType:accountType];
if ([arrayOfAccounts count] > 0)
{
ACAccount *twitterAccount = [arrayOfAccounts lastObject];
NSDictionary *message = #{#"status": #"Message"};
NSURL *requestURL = [NSURL
URLWithString:#"http://api.twitter.com/1/statuses/update.json"];
SLRequest *postRequest = [SLRequest
requestForServiceType:SLServiceTypeTwitter
requestMethod:SLRequestMethodPOST
URL:requestURL parameters:message];
postRequest.account = twitterAccount;
[postRequest performRequestWithHandler:^(NSData *responseData,
NSHTTPURLResponse *urlResponse, NSError *error)
{
NSLog(#"Twitter HTTP response: %i", [urlResponse
statusCode]);
}];
}
}
else {
if(error.code == 6){
[self performSelectorOnMainThread:#selector(alertmessagetwitter)
withObject:nil
waitUntilDone:YES]; }
}
}];
}