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"
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
When i try to get https://api.twitter.com/1.1/statuses/retweets/21947795900469248.json with my authorized credentials (oauth), i'm getting:
{
"errors": [
{
"message": "Your credentials do not allow access to this resource",
"code": 220
}
]
}
error: Any other twit id's not working. Is there a problem with this endpoint? Because i was getting true response until yesterday. Something changed?
I experienced same issue with getting error code 220. Fix in my case was to prompt user to enter it's Twitter password again.
Check sample code below:
SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter
requestMethod:SLRequestMethodPOST
URL:[NSURL URLWithString:#"https://api.twitter.com/1.1/statuses/update.json"]
parameters:#{#"status": tweetString}];
[request setAccount:account];
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if ([responseData isKindOfClass:[NSData class]]) {
NSError *jsonError = nil;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&jsonError];
if (json) {
NSArray *errors = json[#"errors"];
if (errors.count) {
NSUInteger errorCode = [json[#"errors"][0][#"code"] integerValue];
if (errorCode == 220) {
ACAccountStore *accountStore = [[ACAccountStore alloc] init];
[accountStore renewCredentialsForAccount:account completion:^(ACAccountCredentialRenewResult renewResult, NSError *error2) {
NSLog(#"Renew result: %ld, error: %#", (long)renewResult, error2);
if (renewResult == ACAccountCredentialRenewResultRenewed) {
[self __makeTweetWithAccounts:#[account] rating:rating review:review];
}
}];
}
}
}
}
NSLog(#"Twitter response data: %#", [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]);
}];
Was getting the same error when I noticed I was using GET instead of POST. Changed it and it worked.
Set app permissions to Read, write, and direct messages
...and Regenerate Access Token and Token Secret.
It worked for me
I had similar problem with SLRequest class on iOS SDK7.1. Now to get retweets, or post retweet, i started to use deprecated class TWRequest. Just #import resource and use this method:
- (void)retweetMessageV2HavingId:(NSString*)messageId {
NSString *retweetString = [NSString stringWithFormat:#"https://api.twitter.com/1.1/statuses/retweet/%#.json", messageId];
NSURL *retweetURL = [NSURL URLWithString:retweetString];
TWRequest *request = [[TWRequest alloc] initWithURL:retweetURL parameters:nil requestMethod:TWRequestMethodPOST];
request.account = self.account;
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if (responseData)
{
NSError *parseError = nil;
id json = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil];
if (!json)
{
NSLog(#"Parse Error: %#", parseError);
}
else
{
NSLog(#"%#", json);
}
}
else
{
NSLog(#"Request Error: %#", [error localizedDescription]);
}
}]; }
I have generated access-tokens going to 'Keys and Access Tokens' tab in my current app page. Then, i have set 'Access Token' and 'Access Token Secret' for the access tokens for 'auth' obj that has permisson for the app to access in source code.
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);
}
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.
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);
}