I'm using the OAuthConsumer in my iOS application which makes use of the Tumblr API. Making API-Calls in general works fine. However, I struggle to upload any media. When all the parameters of my requests are ints or strings, I add them just like that:
[request setParameters:[NSArray arrayWithObjects:
[OARequestParameter requestParameterWithName:@"x_auth_username" value:username],
[OARequestParameter requestParameterWithName:@"x_auth_password" value:password],
nil]];
That obviously won't work for e.g. images.
I figured out that I probably will have to send this data as multipart/form-data
instead of application/x-www-form-urlencoded
and therefore, it won't have any effect on the oAuth signature. However, as far as I can tell, the OAuthConsumer only supports x-www-form-urlencoded
(with the relevant code lying in the NSMutableURLRequest+Parameters.m
). However, I'm not sure whether this is correct and, if so, I don't really know how to modify the Consumer
correctly. Any help would be appreciated!
Ok, I figured it out my self. There are several parts to this and since I saw other people having similar questions, I'll go into full length:
First of all, I was using an outdated version of OAuthConsumer. Instead of using the version that is linked on Google Code, you should use the more recent version from github since it includes the means to send a multipart form with more than strings in it.
Now, if I'm not completely wrong, what you should theoretically do now is the following:
//Setup the request...
[request setParameters:params];
[request attachFileWithName:@"data" filename:@"photo.jpg" contentType:@"image/jpeg" data:dataProp.data];
//Setup the fetcher and send the request...
This will generate an oAuth signature which includes only the oauth_...
-variables, putting all your other variables into the multipart form. This is how it should be and according to the documentation, you should be fine. Unfortunately, you aren't, tumblr will return a 401 error, resulting most likely from an invalid signature.
Here is what you really have to do:
//Setup the request...
[request setParameters:params];
[request prepare]; //Whaaaat?
[request attachFileWithName:@"data" filename:@"photo.jpg" contentType:@"image/jpeg" data:dataProp.data];
//Setup the fetcher, make sure "prepare" isn't called again, send the request...
This will work... Again, I'm pretty sure that this is not how oAuth is supposed to handle this but at least it works.