Posting a blog post with JSON API on Objective-C

746 views
Skip to first unread message

Sean Choe

unread,
Oct 18, 2011, 5:58:31 AM10/18/11
to typepad-d...@googlegroups.com
Hi!

I'm developing an iPhone app using OAuthConsumer framework for the OAuth authentication.

I succeeded to fetch data from TypePad blog but was not able to post anything to my blog.

I used blogs/<BLOG_ID>/post-assets.json URL, http method "POST". but I'm keep getting error message saying,

ewPostTicket Failed : Error Domain=NSURLErrorDomain Code=-1012 "The operation couldn’t be completed. (NSURLErrorDomain error -1012.)" UserInfo=0x6d853b0 {NSErrorFailingURLKey=https://api.typepad.com/blogs/6a014e8be467db970d014e8be467e4970d/post-assets.json, NSErrorFailingURLStringKey=https://api.typepad.com/blogs/6a014e8be467db970d014e8be467e4970d/post-assets.json, NSUnderlyingError=0x6d87030 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1012.)"}


Do anyone knows how to post with JSON in objective-c?

Thank you!

- Sean

Sean Choe

unread,
Oct 27, 2011, 3:01:44 AM10/27/11
to typepad-d...@googlegroups.com, ml...@saymedia.com
Thank you for your reply Michael!

I'm still struggling with it. :(

This is the code I used. I don't know how you're familiar with Objective-C code, but I'll put it here anyway.
 
- (id)newPost:(Blog*)blog withPost:(Post*)post{
    [super newPost:blog withPost:post];
    
    OAConsumer *consumer = [[OAConsumer alloc] initWithKey:consumerKey secret:consumerSecret];
    
    NSURL *url = [NSURL URLWithString:@"https://api.typepad.com/blogs/6a014e8be467db970d014e8be467e4970d/post-assets.json"]];
    OAToken *loadedToken = [[OAToken alloc] initWithKey:blog.username secret:[blog getPassword]];
    
    OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:url consumer:consumer token:loadedToken realm:realm signatureProvider:nil];
    NSString *postString = @"title=ok&content=ok";
    NSData *requestData = [postString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
    NSString *postLength = [NSString stringWithFormat:@"%d", [requestData length]];
    
    [request setHTTPMethod:@"POST"];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPBody:requestData];
    
    OADataFetcher *fetcher = [[OADataFetcher alloc] init];
    [fetcher fetchDataWithRequest:request delegate:self didFinishSelector:@selector(newPostTicket:didFinishWithData:) didFailSelector:@selector(newPostTicket:didFailWithError:)];
    
    [request release];
    [loadedToken release];
    [consumer release];
    [fetcher release];
    
    return nil;
}

I just put in "title" and "content". is there some thing I need to add?

I'm using OAuthConsumer framework and it works fine on fetching blog posts but not posting. So I don't know why it returns authentication error.

Thanks again for helping me!

- Sean

Michael wrote --------------------------
I was just speaking with Martin Atkins in the TypePad Platform team
and he had the following feedback...
Some googling for the error you received found this:
http://iphonesdkbasics.blogspot.com/2010/07/nsurlerrordomain-error-1012.html
This page explains that the error is raised when the server returns a
401 Unauthorized response; TypePad will do this in the following
situations:
 * The request didn't have an Authorization header at all.
 * The request had an Authorization header that is for the wrong
authentication method. (We expect OAuth, but client libraries often
default to trying Basic authentication.)
 * The request has a OAuth Authorization header but the signature
provided isn't what we expected.
Since you are using an oAuth client, it's assumed there's a problem
with your (or its) implementation that's causing it to end up
malformed somehow.
We could speculate a little more about what it might be with a sample
of the part of the code that is failing but we can't do much to solve
it if it's an Obj-C thing or something to do with the library. Do you
have something you can share?
Best,
Michael 

Martin Atkins

unread,
Oct 27, 2011, 5:12:59 PM10/27/11
to typepad-d...@googlegroups.com

Hi Sean,

I'm an engineer on the TypePad API. I don't really know Objective C but
if I'm understanding your code correctly then it looks like you're
sending the POST body in urlencoded format, but the API actually expects
JSON.

So here's the first thing I'd try changing:

NSString*postString = @"{\"title\":\"ok\",\"content\"=\"ok\"}";

and then,
[request
setValue:@"application/json"forHTTPHeaderField:@"Content-Type"];

I also can't see anywhere that you add the OAuth authorization header,
but perhaps your OAuthConsumer library is taking care of that for you;
you'll need to make sure it's present in the request or you'll get a 401
Unauthorized response.

I'm sorry that my lack of experience with Objective C leaves me
resorting to guesswork, but hopefully we can get to the bottom of
this... if you still see the error after the changes I described above,
it might be useful if you can find a way to extract the body of the
error response the API is returning, since the message returned there
will allow me to distiguish between a few different error conditions
that all manifest in a 401 Unauthorized status code.

On 10/26/2011 08:01 PM, Sean Choe wrote:
> Thank you for your reply Michael!
>
> I'm still struggling with it. :(
>
> This is the code I used. I don't know how you're familiar with
> Objective-C code, but I'll put it here anyway.
>
> - (id)newPost:(Blog*)blog withPost:(Post*)post{
> [super newPost:blog withPost:post];
>
> OAConsumer*consumer = [[OAConsumeralloc]

> initWithKey:consumerKeysecret:consumerSecret];


>
> NSURL *url = [NSURL
> URLWithString:@"https://api.typepad.com/blogs/6a014e8be467db970d014e8be467e4970d/post-assets.json"]];
> OAToken *loadedToken = [[OAToken alloc] initWithKey:blog.username
> secret:[blog getPassword]];
>
> OAMutableURLRequest *request = [[OAMutableURLRequest alloc]
> initWithURL:url consumer:consumer token:loadedToken realm:realm
> signatureProvider:nil];
> NSString*postString = @"title=ok&content=ok";
> NSData*requestData = [postString

> dataUsingEncoding:NSASCIIStringEncodingallowLossyConversion:YES];


> NSString *postLength = [NSString stringWithFormat:@"%d",
> [requestData length]];
>
> [request setHTTPMethod:@"POST"];
> [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
> [request setValue:@"application/json"forHTTPHeaderField:@"Accept"];
> [request
> setValue:@"application/x-www-form-urlencoded"forHTTPHeaderField:@"Content-Type"];
> [request setHTTPBody:requestData];
>

> OADataFetcher*fetcher = [[OADataFetcheralloc] init];

> --
> You received this message because you are subscribed to the TypePad
> Developers Network.
> To post to this group, send email to typepad-d...@googlegroups.com
> To unsubscribe from this group, send email to
> typepad-dev-net...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/typepad-dev-network?hl=en

Reply all
Reply to author
Forward
0 new messages