I am trying to integrate "tumblr" into my application.I am able to get the access token successfully. But, when I try to post, I am getting the following error
{"meta":{"status":401,"msg":"Not Authorized"},"response":[]}
I am using the OAuthConsumer
client for iOS, which I have pulled if from MGTwitterEngine
.
This is what I have tried.
#import "ViewController.h"
#define consumer_key @"u9iZvT8KIlrTtUrh3vUeXXXXXXXXXXXXXAfgpThGyom8Y6MKKCnU"
#define consumer_secret @"xfA10mQKmALlpsnrFXXXXXXXXXXXXXXXXXXXXXXXXXX"
#define request_token_url @"http://www.tumblr.com/oauth/request_token"
#define access_token_url @"http://www.tumblr.com/oauth/access_token"
#define authorize_url @"http://www.tumblr.com/oauth/authorize?oauth_token=%@"
#define base_url @"http://api.tumblr.com/v2/user/XXXXXXXXXXXXX.tumblr.com/info"
#define user_info @"http://api.tumblr.com/v2/user/info"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (IBAction)postIt:(id)sender
{
NSURL *postURL = [NSURL URLWithString:@"http://api.tumblr.com/v2/blog/xxxxxxxx.tumblr.com/post"];
OAMutableURLRequest *oRequest = [[OAMutableURLRequest alloc] initWithURL:postURL
consumer:self.consumer
token:self.accessToken
realm:nil
signatureProvider:nil];
[oRequest setHTTPMethod:@"POST"];
[oRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
OARequestParameter *statusParam = [[OARequestParameter alloc] initWithName:@"body"
value:@"Sample Body"];
OARequestParameter *statusParam2 = [[OARequestParameter alloc] initWithName:@"type"
value:@"text"];
NSArray *params = [NSArray arrayWithObjects:statusParam,statusParam2, nil];
[oRequest setParameters:params];
OAAsynchronousDataFetcher *fetcher = [OAAsynchronousDataFetcher asynchronousFetcherWithRequest:oRequest
delegate:self
didFinishSelector:@selector(sendStatusTicket:didFinishWithData:)
didFailSelector:@selector(sendStatusTicket:didFailWithError:)];
NSLog(@"URL = %@",[oRequest.URL absoluteString]);
[fetcher start];
}
- (void)didReceiveAccessToken:(OAServiceTicket *)ticker data:(NSData *)responseData
{
}
- (void)webView:(UIWebView*)webView didFailLoadWithError:(NSError*)error {
// ERROR!
}
- (void)sendStatusTicket:(OAServiceTicket *)ticker didFinishWithData:(NSData *)responseData
{
if (ticker.didSucceed) {
NSLog(@"Success");
}
NSString *responseBody = [[NSString alloc] initWithData:responseData
encoding:NSUTF8StringEncoding];
NSLog(@"Description = %@",responseBody);
}
- (void)sendStatusTicket:(OAServiceTicket *)ticker didFailWithError:(NSError *)error
{
NSLog(@"Error = %@",[error localizedDescription]);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (IBAction)login:(id)sender
{
self.consumer = [[OAConsumer alloc] initWithKey:consumer_key secret:consumer_secret];
NSURL *url = [NSURL URLWithString:request_token_url];
OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:url
consumer:self.consumer
token:nil // we don't have a Token yet
realm:nil // our service provider doesn't specify a realm
signatureProvider:nil]; // use the default method, HMAC-SHA1
[request setHTTPMethod:@"POST"];
OADataFetcher *fetcher = [[OADataFetcher alloc] init];
[fetcher fetchDataWithRequest:request
delegate:self
didFinishSelector:@selector(requestTokenTicket:didFinishWithData:)
didFailSelector:@selector(requestTokenTicket:didFailWithError:)];
}
- (void)requestTokenTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data {
if (ticket.didSucceed)
{
NSString *responseBody = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
self.accessToken= [[OAToken alloc] initWithHTTPResponseBody:responseBody];
NSURL *author_url = [NSURL URLWithString:[ NSString stringWithFormat:authorize_url,self.accessToken.key]];
OAMutableURLRequest *oaR = [[OAMutableURLRequest alloc] initWithURL:author_url consumer:nil token:nil realm:nil signatureProvider:nil];
UIWebView *webView =[[UIWebView alloc] initWithFrame:[UIScreen mainScreen].bounds];
[[[UIApplication sharedApplication] keyWindow] addSubview:webView];
webView.delegate=self;
[webView loadRequest:oaR];
}
}
// This is to get oAuth_verifier from the url
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
NSString *url = [[request URL] absoluteString];
NSString *keyOne = @"oauth_token";
NSString *keyTwo = @"oauth_verifier";
NSRange r1 =[url rangeOfString:keyOne];
NSRange r2 =[url rangeOfString:keyTwo];
if (r1.location!=NSNotFound && r2.location!=NSNotFound) {
// Extract oauth_verifier from URL query
NSString* verifier = nil;
NSArray* urlParams = [[[request URL] query] componentsSeparatedByString:@"&"];
for (NSString* param in urlParams) {
NSArray* keyValue = [param componentsSeparatedByString:@"="];
NSString* key = [keyValue objectAtIndex:0];
if ([key isEqualToString:@"oauth_verifier"]) {
verifier = [keyValue objectAtIndex:1];
break;
}
}
if (verifier) {
NSURL* accessTokenUrl = [NSURL URLWithString:@"http://www.tumblr.com/oauth/access_token"];
OAMutableURLRequest* accessTokenRequest =[[OAMutableURLRequest alloc] initWithURL:accessTokenUrl
consumer:self.consumer
token:self.accessToken
realm:nil
signatureProvider:nil];
OARequestParameter* verifierParam =[[OARequestParameter alloc] initWithName:@"oauth_verifier" value:verifier];
[accessTokenRequest setHTTPMethod:@"POST"];
[accessTokenRequest setParameters:[NSArray arrayWithObjects:verifierParam,nil]];
OADataFetcher* dataFetcher = [[OADataFetcher alloc] init];
[dataFetcher fetchDataWithRequest:accessTokenRequest
delegate:self
didFinishSelector:@selector(requestTokenTicketForAuthorization:didFinishWithData:)
didFailSelector:@selector(requestTokenTicket:didFailWithError:)];
} else {
// ERROR!
}
[webView removeFromSuperview];
return NO;
}
return YES;
}
- (void)requestTokenTicketForAuthorization:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data
{
if (ticket.didSucceed)
{
NSString *responseBody = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
self.accessToken = [self.accessToken initWithHTTPResponseBody:responseBody];
accessText=self.accessToken.key;
accessSecret=self.accessToken.secret;
}
else
{
NSString *responseBody = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSLog(@"Response = %@",responseBody);
}
}
- (void)requestTokenTicket:(OAServiceTicket *)ticket didFailWithError:(NSError *)error
{
NSLog(@"Error = %@",[error localizedDescription]);
}
@end
Whats the mistake I am making here? Why I am getting that error? Did I follow the steps properly?
Please XXX out your consumer_key and consumer_secret to avoid unwanted use of them. Code wise there are a few things you might want to look for here.
Are you able to use an oauth 'GET' request such as "http://api.tumblr.com/v2/user/info"? If you can receive a successful 'GET' request then your access token is valid and you can look at how you're sending your post parameters.
Make sure you are passing in your parameters as HTTP Body as well as signature parameters. Correct parameter ordering is likely provided by the library.
NSString *postbody = @"body=myBodyText&type=text";
[oRequest setHTTPBody:[postbody dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:TRUE]];