OAuthConsumer and Twitpic - iphone

I'm trying to post images to TwitPic using OAuthConsumer. I keep receiving a 401 "Could not authenticate you (header rejected by twitter)." error.
I am also making use of the Twitter+OAuth library to handle the login and posting regular tweets, and then saving the token and token secret for using with TwitPic.
This is the code I am using the construct the request:
NSURL *twitpicUrl = [NSURL URLWithString:#"http://api.twitpic.com/2/upload.json"];
NSString* realm = #"http://api.twitter.com/";
OAToken* oaToken = [[OAToken alloc] initWithKey:savedToken secret:savedTokenSecret];
OAConsumer* oaConsumer = [[OAConsumer alloc] initWithKey:kOAuthConsumerKey secret:kOAuthConsumerSecret];
OAMutableURLRequest *request = [[[OAMutableURLRequest alloc] initWithURL:twitpicUrl consumer:oaConsumer
token:oaToken realm:realm signatureProvider:nil] autorelease];
[request prepare];
[request setHTTPMethod:#"POST"];
[request setValue:#"https://api.twitter.com/1/account/verify_credentials.json" forHTTPHeaderField:#"X-Auth-Service-Provider"];
NSString* authorizeHeader = [request valueForHTTPHeaderField:#"Authorization"];
[request setValue:authorizeHeader forHTTPHeaderField:#"X-Verify-Credentials-Authorization"];
And if I print out my headers, this is what I get (excluding the unused Authorization header):
"X-Auth-Service-Provider" = "https://api.twitter.com/1/account/verify_credentials.json";
"X-Verify-Credentials-Authorization" = "OAuth realm=\"http%3A%2F%2Fapi.twitter.com%2F\", oauth_consumer_key=\"JOvwW7mtZUjRXZRInkQI7w\", oauth_token=\"293217559-pD0HL0oE6TZSkU35mPnc7kia325oPDgMfQMTVArK\", oauth_signature_method=\"HMAC-SHA1\", oauth_signature=\"ctmCK35JFwx8qs8lQj0AYB6sUr4%3D\", oauth_timestamp=\"1304580843\", oauth_nonce=\"7EBE3EB0-641A-40EA-A57C-8D071B5E647F\", oauth_version=\"1.0\"";
The error I receive is:
Error: The operation couldn’t be completed. (NSURLErrorDomain error -1012.)
{"errors":[{"code":401,"message":"Could not authenticate you (header rejected by twitter)."}]}
I have excluded some detail here, specifically appending the post data, mainly because I don't think it's relevant to the error. If you think otherwise let me know and I'll update the question.
Can anyone help?
Update: Here is the code that I am now using successfully
In header:
#define kVerifyCredentialsUrl #"https://api.twitter.com/1/account/verify_credentials.json"
#define kTwitPicUrl #"http://api.twitpic.com/2/upload.json"
Implementation:
//prepare the verify credentials header
NSURL* serviceUrl = [NSURL URLWithString:kVerifyCredentialsUrl];
NSString* realm = #"http://api.twitter.com/";
OAToken* token = [[OAToken alloc] initWithKey:tokenKey secret:tokenSecret];
OAConsumer* consumer = [[OAConsumer alloc] initWithKey:kOAuthConsumerKey secret:kOAuthConsumerSecret];
OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:serviceUrl consumer:consumer token:token realm:realm signatureProvider:nil];
[request setHTTPMethod:#"GET"];
[request prepare];
NSDictionary* headerDictionary = [request allHTTPHeaderFields];
NSString* oAuthHeader = [NSString stringWithString:[headerDictionary valueForKey:#"Authorization"]];
[request release];
request = nil;
//prepare the full request
serviceUrl = [NSURL URLWithString:kTwitPicUrl];
request = [[OAMutableURLRequest alloc] initWithURL:serviceUrl consumer:consumer token:token realm:realm signatureProvider:nil];
[request setHTTPMethod:#"POST"];
[request setValue:kVerifyCredentialsUrl forHTTPHeaderField:#"X-Auth-Service-Provider"];
[request setValue:oAuthHeader forHTTPHeaderField:#"X-Verify-Credentials-Authorization"];
//add the content and start the request
UIImage* imageToUpload = [UIImage imageNamed:#"test.png"];
NSData *data = UIImagePNGRepresentation(imageToUpload);
ASIFormDataRequest *asiRequest = [[[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:kTwitPicUrl]] autorelease];
[asiRequest addRequestHeader:#"X-Auth-Service-Provider" value:kVerifyCredentialsUrl];
[asiRequest addRequestHeader:#"X-Verify-Credentials-Authorization" value:oAuthHeader];
[asiRequest setPostValue:#"Message here" forKey:#"message"];
[asiRequest setPostValue:kTwitPicAPIKey forKey:#"key"];
[asiRequest setData:data forKey:#"media"];
[asiRequest setDidFinishSelector:#selector(requestDone:)];
[asiRequest setDidFailSelector:#selector(requestWentWrong:)];
[asiRequest setDelegate:self];
[asiRequest startAsynchronous];

Try this :
NSURL *serviceURL = [NSURL URLWithString:#"https://api.twitter.com/1/account/verify_credentials.json"];
OAMutableURLRequest *oRequest = [[OAMutableURLRequest alloc] initWithURL:serviceURL
consumer:consumer_
token:accessToken_
realm:#"http://api.twitter.com/"
signatureProvider:nil];
[oRequest setHTTPMethod:#"GET"];
[oRequest prepare];
NSDictionary * headerDict = [oRequest allHTTPHeaderFields];
NSString * oauthHeader = [NSString stringWithString:[headerDict valueForKey:#"Authorization"]];
[oRequest release];
// Prepare the POST request
oRequest = nil;
serviceURL = nil;
serviceURL = [NSURL URLWithString:#"http://api.twitpic.com/2/upload.json"];
oRequest = [[OAMutableURLRequest alloc] initWithURL:serviceURL
consumer:consumer_
token:accessToken_
realm:#"http://api.twitter.com/"
signatureProvider:nil];
[oRequest setHTTPMethod:#"POST"];
[oRequest setValue:#"https://api.twitter.com/1/account/verify_credentials.json" forHTTPHeaderField:#"X-Auth-Service-Provider"];
[oRequest setValue:oauthHeader forHTTPHeaderField:#"X-Verify-Credentials-Authorization"];
You should also make this change in OAMutableURLRequest.m at the end of the method - (void)prepare:
NSString *oauthHeader = [NSString stringWithFormat:#"OAuth realm=\"%#\", oauth_consumer_key=\"%#\", %#oauth_signature_method=\"%#\", oauth_signature=\"%#\", oauth_timestamp=\"%#\", oauth_nonce=\"%#\", oauth_version=\"1.0\"%#",
[realm URLEncodedString],
[consumer.key URLEncodedString],
oauthToken,
[[signatureProvider name] URLEncodedString],
[signature URLEncodedString],
timestamp,
nonce,
extraParameters];
if(![self valueForHTTPHeaderField:#"X-Verify-Credentials-Authorization"])
[self setValue:oauthHeader forHTTPHeaderField:#"Authorization"];

It may also be a problem with twitter right now.
My code using OAMutableURLRequest like yours, has been working fine for ages, and today I keep getting the 401 error code. Searching twitter you will find more people having this problem recently.
This is what you can read now in the api status page:
We are currently experiencing elevated
error rates. There may be intermittent
issues loading twitter.com and Twitter
clients. We are aware of the problem
and taking action. Thanks for your
patience!
Twitter API Status

Related

How to post an image to a LinkedIn account using Objective-C code on iOS?

I am able to post the comment to LinkedIn but not able to post the image. This is the code for posting the comment:
NSURL *url = [NSURL URLWithString:#"http://api.linkedin.com/v1/people/~/shares"];
OAMutableURLRequest *request =
[[OAMutableURLRequest alloc] initWithURL:url
consumer:self.consumer
token:self.accessToken
callback:nil
signatureProvider:nil];
NSString *postedStr = self.textView.text;
NSDictionary *update = [[NSDictionary alloc] initWithObjectsAndKeys:
[[NSDictionary alloc]
initWithObjectsAndKeys:
#"anyone",#"code",nil], #"visibility",
postedStr, #"comment", nil];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSString *updateString = [update JSONString];
[request setHTTPBodyWithString:updateString];
[request setHTTPMethod:#"POST"];
OADataFetcher *fetcher = [[OADataFetcher alloc] init];
[fetcher fetchDataWithRequest:request
delegate:self
didFinishSelector:#selector(postUpdateApiCallResult:didFinish:)
didFailSelector:#selector(postUpdateApiCallResult:didFail:)];
// [self.view addSubview:linkedinView];
[request release];
Any suggestion really appreciated!
try this bellow code may be its help you:-
-(void)postUpdateHERE
{
NSURL *url = [NSURL URLWithString:#"http://api.linkedin.com/v1/people/~/shares"];
OAMutableURLRequest *request =
[[OAMutableURLRequest alloc] initWithURL:url
consumer:[self getConsumer]
token:self.accesstoken
callback:nil
signatureProvider:nil];
NSDictionary *update = [[NSDictionary alloc] initWithObjectsAndKeys:
[[NSDictionary alloc]
initWithObjectsAndKeys:
#"anyone",#"code",nil], #"visibility",
#"comment goes here", #"comment",
[[NSDictionary alloc]
initWithObjectsAndKeys:
#"description goes here",#"description",
#"www.google.com",#"submittedUrl",
#"title goes here",#"title",
#"http://economy.blog.ocregister.com/files/2009/01/linkedin-logo.jpg",#"submittedImageUrl",nil],#"content",
nil];
[request setValue:#"json" forHTTPHeaderField:#"x-li-format"];
[request setValue:#"application/xml" forHTTPHeaderField:#"Content-Type"];
NSString *updateString = [update JSONString];
[request setHTTPBodyWithString:updateString];
[request setHTTPMethod:#"POST"];
OADataFetcher *fetcher = [[OADataFetcher alloc] init];
[fetcher fetchDataWithRequest:request
delegate:self
didFinishSelector:#selector(postUpdateApiCallResult:didFinish:)
didFailSelector:#selector(postUpdateApiCallResult:didFail:)];
}
i found this from bellow stackover flow answer:-
Can't share using OAuth Starter Kit for LinkedIn
EDIT:-
For TamilKing comment reply. you can get image URL of you currunt Location using Google API. First you need to get you currunt Location Image Like:-
NSString *staticMapUrl = [NSString stringWithFormat:#"http://maps.google.com/maps/api/staticmap?markers=color:red|%f,%f&%#&sensor=true",lat, log,#"zoom=12&size=114x116"]; //That above staticMapURl NSlog is :http://maps.google.com/maps/api/staticmap?markers=color:red|1.282130,103.803131&zoom=12&size=114x116&sensor=true
That given you current Location image for example:-
Now you have to convert this above NSString to NSURL like
NSURL *mapUrl = [NSURL URLWithString:[staticMapUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
and use this url that you want to share in to LinkedIn. hope that helps you.
You may need to do more, but for sure you'll need to set the length...
[request setValue:[NSString stringWithFormat:#"%d", updateString.length] forHTTPHeaderField:#"Content-Length"];

Sending JSON Request to server?

I have following JSON for sending request on server
{
"name":"Home",
"latitude":"45.5037078163837",
"longitude":"-122.622699737549",
"radius":"240"
}
and URL of for request is
URL: https://api.geoloqi.com/1/place/create
I am making request like this,
NSString *urlString= #"https://api.geoloqi.com/1/place/create ";
NSURL* url = [[NSURL alloc] initWithString:urlString];
NSString *jsonRequest = #"{\"name\":\"veer\",\"latitude\":\"45.5037078163837\",\"longitude\":\"-122.622699737549\,\"radius\":\"500\ }";
jsonRequest = [self JSONString:jsonRequest];
NSData* requestData = [jsonRequest dataUsingEncoding:NSUTF8StringEncoding];
NSString* requestDataLengthString = [[NSString alloc] initWithFormat:#"%d", [requestData length]];
NSMutableURLRequest* request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:requestData];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:requestDataLengthString forHTTPHeaderField:#"Content-Length"];
[request setTimeoutInterval:30.0];
[url release];
[requestData release];
[requestDataLengthString release];
NSURLConnection *m_URLConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[request release];
What is wrong with this request ?
Your JSON string seems to be missing 2 quotes after the longitude and radius values:
Change
NSString *jsonRequest = #"{\"name\":\"veer\",\"latitude\":\"45.5037078163837\",\"longitude\":\"-122.622699737549\,\"radius\":\"500\ }";
To this
NSString *jsonRequest = #"{\"name\":\"veer\",\"latitude\":\"45.5037078163837\",\"longitude\":\"-122.622699737549\",\"radius\":\"500\" }";
It is not clear from your question what is your issue with that.
Anyway, are you doing also:
[m_URLConnection start];
after creating the connection?
Alternatively, you could create the connection using
[– initWithRequest:delegate:startImmediately:][1]
which allows you to specify that the loading of data shall start immediately.
Also consider using [+sendAsynchronousRequest:queue:completionHandler:][2] as a convenience constructor for your connection.
The Webservice URL you are trying to hit is seem to be using SSL. You may need to put access token in request header in order to get the proper response from web service.
Please see the link for authentication:
https://developers.geoloqi.com/api/authentication

Post image to facebook using graph api

I am using facebook graph api to post image and message to facebook. I have taken help from Raywenderlich tutorial. It was working fine before last two weeks. But now it creating issue for me. I am getting all the facebook profile information.
UIImage *image = [UIImage imageNamed:#"no_image.png"];
data = UIImagePNGRepresentation(image);
NSURL *url = [NSURL URLWithString:#"https://graph.facebook.com/me/photos"];
NSString *message = [couponInfoDictionary objectForKey:#"offerTitle"];
message = [message stringByAppendingString:#"\n"];
NSString *offerSlogan = [couponInfoDictionary objectForKey:#"offerSlogan"];
message = [message stringByAppendingString:[NSString stringWithFormat:#"%#",offerSlogan]];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setData:data forKey:#"file"];
[request setPostValue:message forKey:#"message"];
[request setPostValue:_accessToken forKey:#"access_token"];
[request setDidFinishSelector:#selector(sendToPhotosFinished:)];
[request setDidFailSelector:#selector(requestError:)];
[request setDelegate:self];
[request startAsynchronous];
- (void)sendToPhotosFinished:(ASIHTTPRequest *)request
{
// Use when fetching text data
NSString *responseString = [request responseString];
NSLog(#"response string before photo id %#",responseString);
NSMutableDictionary *responseJSON = [responseString JSONValue];
NSString *photoId = [responseJSON objectForKey:#"id"];
NSLog(#"Photo id is: %#", photoId);
NSString *urlString = [NSString stringWithFormat:#"https://graph.facebook.com/%#?access_token=%#", photoId, [_accessToken stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSLog(#"sendToPhotosFinished = %#",urlString);
NSURL *url = [NSURL URLWithString:urlString];
ASIHTTPRequest *newRequest = [ASIHTTPRequest requestWithURL:url];
[newRequest setDidFinishSelector:#selector(getFacebookPhotoFinished:)];
[newRequest setDelegate:self];
[newRequest startAsynchronous];
}
But when i posting the image, It giving me error
{"error":{"message":"Error validating application.","type":"OAuthException"}}
Photo id is: (null)
sendToPhotosFinished = https://graph.facebook.com/(null)?access_token=ABACesEZBKr3gBALqa4yE2QAnJbNbGvQKa9iCm53GmTwHQYoyaxqAqmdLj0gw9uWCbyhP5sV7N6uZBjaFDpD6v6G1C7GcZCjvcZBPqt7b1ZAxKtDvepN8c&expires_in=4778
Got Facebook Photo: {"error":{"message":"(#803) Some of the aliases you requested do not exist: (null)","type":"OAuthException"}}
I have spent my three days to resolve it. But still not getting any idea..how to solve this?
use this #"117795728310/photos" insted of me/photos
In the third line of your above code ,
Photo id is: (null)
2012-02-16 11:59:11.298 FBFun[2330:207] Got Facebook Photo:
{
"error": {
"message": "(#803) Some of the aliases you requested do not exist: (null)",
"type": "OAuthException",
"code": 803
}
}
I have used following code, and it is working...
NSURL *url = [NSURL URLWithString:#"https://graph.facebook.com/USER_FACEBOOK_PROFILE_ID/photos"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"img1" ofType:#"jpg"];
nsstring *accessToken = #"AAACWZA..............................................Ts28iSOhGoOhe9qAgpZCL7AZDZD";
[request addData:[[NSUserDefaults standardUserDefaults]dataForKey:#"image1"] forKey:#"file"];
[request setPostValue:#"Testing App For iPhone, please don't comment..." forKey:#"message"];
[request setPostValue:accessToken forKey:#"access_token"];
[request setDelegate:self];
[request startAsynchronous];

Oauth Consumer - LinkedIN UPDATE STATUS

I try to develop a app that use OauthConsumer for connection with LinkedIN.
All work fine, I can extract the user data but when I want to update User status I've status error 401 with message [unauthorized].
I've the access token, this is the code:
NSURL *url = [NSURL URLWithString:#"https://api.linkedin.com/v1/people/~/current-status"];
OAMutableURLRequest *request1 = [[OAMutableURLRequest alloc] initWithURL:url
consumer:consumer
token:accToken//
realm:nil //
signatureProvider:nil] ; //
NSLog(#"mytoken%#",[request1 token]);
[request1 setHTTPMethod:#"PUT"];
[request1 setHTTPBodyWithString:#"<?xml version=''1.0'' encoding=''UTF-8'?><current-status>is setting their status using the LinkedIn API.</current-status>"];
OADataFetcher *fetcher = [[OADataFetcher alloc] init];
[fetcher fetchDataWithRequest:request1
delegate:self
didFinishSelector:#selector(status:didFinishWithData:)
didFailSelector:#selector(status:didFailWithError:)];
Any ideas??? Plese help me!!!!!! :(
tnx
OK, the rigth code is the next:
NSURL *url = [NSURL URLWithString:#"http://api.linkedin.com/v1/people/~/shares"];
OAMutableURLRequest *request1 = [[OAMutableURLRequest alloc] initWithURL:url
consumer:consumer
token:accToken
realm:nil
signatureProvider:nil];
NSLog(#"mytoken%#",[request1 token]);
[request1 setHTTPShouldHandleCookies:NO];
[request1 setValue:#"text/xml;charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
[request1 setHTTPMethod:#"POST"];
[request1 prepare];
[request1 setHTTPBody:[NSData dataWithContentsOfFile:[NSString stringWithFormat:#"%#/status.xml", [[ NSBundle mainBundle] resourcePath]]]];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request1 delegate:self];
[connection start];

How to send authenticated requests to Google Reader?

It seems that Google has disabled the old way of sending cookie SID to their Google Data Services, specifically Google Reader.
This way does not work at least for me:
//create request
NSString* content = [NSString stringWithFormat:#"accountType=HOSTED_OR_GOOGLE&Email=%#&Passwd=%#&service=ah&source=myapp", [loginView username].text, [loginView password].text];
NSURL* authUrl = [NSURL URLWithString:#"https://www.google.com/accounts/ClientLogin"];
NSMutableURLRequest* authRequest = [[NSMutableURLRequest alloc] initWithURL:authUrl];
[authRequest setHTTPMethod:#"POST"];
[authRequest setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-type"];
[authRequest setHTTPBody:[content dataUsingEncoding:NSASCIIStringEncoding]];
NSHTTPURLResponse* authResponse;
NSError* authError;
NSData * authData = [NSURLConnection sendSynchronousRequest:authRequest returningResponse:&authResponse error:&authError];
NSString *authResponseBody = [[NSString alloc] initWithData:authData encoding:NSASCIIStringEncoding];
//loop through response body which is key=value pairs, seperated by \n. The code below is not optimal and certainly error prone.
NSArray *lines = [authResponseBody componentsSeparatedByString:#"\n"];
NSMutableDictionary* token = [NSMutableDictionary dictionary];
for (NSString* s in lines) {
NSArray* kvpair = [s componentsSeparatedByString:#"="];
if ([kvpair count]>1)
[token setObject:[kvpair objectAtIndex:1] forKey:[kvpair objectAtIndex:0]];
}
//if google returned an error in the body [google returns Error=Bad Authentication in the body. which is weird, not sure if they use status codes]
if ([token objectForKey:#"Error"]) {
//handle error
};
And the request:
TTURLRequest *request = [TTURLRequest requestWithURL:url delegate:self];
request.cachePolicy = cachePolicy;
request.cacheExpirationAge = TT_CACHE_EXPIRATION_AGE_NEVER;
NSString *cookieHeader = [NSString stringWithFormat:#"Name=SID;SID=%#;Domain=.google.com;Path=/;Expires=160000000000", sid];
[request setValue:cookieHeader forHTTPHeaderField:#"Cookie"];
[request setHttpMethod:#"GET"];
[request setValue:#"myapp" forHTTPHeaderField:#"User-agent"];
Changing to use the GoogleLogin auth=xxx gives me a NSURLErrorDomain 401
TTURLRequest *request = [TTURLRequest requestWithURL:url delegate:self];
request.cachePolicy = cachePolicy;
request.cacheExpirationAge = TT_CACHE_EXPIRATION_AGE_NEVER;
NSString *authorizationHeader = [NSString stringWithFormat:#"GoogleLogin auth=%#", auth];
[request setValue:authorizationHeader forHTTPHeaderField:#"Authorization"];
[request setHttpMethod:#"GET"];
[request setValue:#"myapp" forHTTPHeaderField:#"User-agent"];
The result is always the 401 error code. Could someone show me how to fix in this specific case? Thank you in advance.
Error Domain=NSURLErrorDomain Code=401 "Operation could not be completed. (NSURLErrorDomain error 401.)"
Error description: Operation could not be completed. (NSURLErrorDomain error 401.)
Changing the body of the POST solves the 401 error. Differences are in the service, source & continue.
NSString* content = [NSString stringWithFormat:#"Email=%#&Passwd=%#&service=reader&source=yourapp&continue=http://www.google.com", username, password];