PDA

View Full Version : Sending pictures with NSURLRequest




Kozmicstu
Feb 4, 2008, 10:58 AM
Hi

I'm trying to send a multipart/form-data 'POST' request using NSURLRequest, including several keys, but also an image. I'm not particularly knowledgeable on HTTP request (and pretty new to Cocoa, to be honest...)

If you want to know what it's for, right now I'm trying to work against the Tumblr API (http://tumblr.com/api) to post a photo to a Tumblelog from a Cocoa app. I've managed to make text posts from the app, but I can't work out how to do a photo post.

I've been looking on forums and there's a couple of people with really long-winded solutions but I haven't managed to get any of them working. The connection starts and then a message comes back saying 'posts cannot be empty', suggesting that the authentication is fine, but it's not receiving the data part of the message

Anyway, I'd be grateful for any help, if anyone knows how to make this happen :)

Stu



kainjow
Feb 4, 2008, 11:49 AM
There are two pages on CocoaDev about this. Might be of some help. HTTPFileUpload (http://www.cocoadev.com/index.pl?HTTPFileUpload) and POSTMethodANDNSURLRequest (http://www.cocoadev.com/index.pl?POSTMethodANDNSURLRequest).

If that doesn't help it would be useful to post some code.

Kozmicstu
Feb 5, 2008, 05:28 PM
Thanks very much for that. I had found one of them before and tried it, but I gave it another go and got it working perfectly. I think I might have been leaving keys out somewhere along the way or something...

Anyway, here's the (probably messy) code I used in the end, for posterity's sake (or for anyone else who wants to do this...)

- (BOOL)sendPhotoToTumblr:(NSString *)photo withCaption:(NSString *)caption;
{
//get image data from file
NSData *imageData = [NSData dataWithContentsOfFile:photo];
//stop on error
if (!imageData) return NO;

//Create dictionary of post arguments
NSArray *keys = [[NSArray alloc] initWithObjects:@"email",@"password",@"type",@"caption",nil];
NSArray *objects = [[NSArray alloc] initWithObjects:
[NSString stringWithFormat:@"%@",CFPreferencesCopyAppValue(CFSTR("TumblrEmail"), kCFPreferencesCurrentApplication)],
[NSString stringWithFormat:@"%@",CFPreferencesCopyAppValue(CFSTR("TumblrPassword"), kCFPreferencesCurrentApplication)],
@"photo", caption, nil];
NSDictionary *keysDict = [[NSDictionary alloc] initWithObjects:objects forKeys:keys];

//create tumblr photo post
NSURLRequest *tumblrPost = [self createTumblrRequest:keysDict withData:imageData];

//send request, return YES if successful
tumblrConnection = [[NSURLConnection alloc] initWithRequest:tumblrPost delegate:self];
if (!tumblrConnection) {
NSLog(@"Failed to submit request");
return NO;
} else {
NSLog(@"Request submitted");
receivedData = [[NSMutableData data] retain];
return YES;
}
}


-(NSURLRequest *)createTumblrRequest:(NSDictionary *)postKeys withData:(NSData *)data
{
//create the URL POST Request to tumblr
NSURL *tumblrURL = [NSURL URLWithString:@"http://www.tumblr.com/api/write"];
NSMutableURLRequest *tumblrPost = [NSMutableURLRequest requestWithURL:tumblrURL];
[tumblrPost setHTTPMethod:@"POST"];

//Add the header info
NSString *stringBoundary = [NSString stringWithString:@"0xKhTmLbOuNdArY"];
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",stringBoundary];
[tumblrPost addValue:contentType forHTTPHeaderField: @"Content-Type"];

//create the body
NSMutableData *postBody = [NSMutableData data];
[postBody appendData:[[NSString stringWithFormat:@"--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];

//add key values from the NSDictionary object
NSEnumerator *keys = [postKeys keyEnumerator];
int i;
for (i = 0; i < [postKeys count]; i++) {
NSString *tempKey = [keys nextObject];
[postBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",tempKey] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat:@"%@",[postKeys objectForKey:tempKey]] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
}

//add data field and file data
[postBody appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"data\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[NSData dataWithData:data]];
[postBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",stringBoundary] dataUsingEncoding:NSUTF8StringEncoding]];

//add the body to the post
[tumblrPost setHTTPBody:postBody];

return tumblrPost;
}

kainjow
Feb 5, 2008, 06:56 PM
Make sure you release or autorelease your keys, objects, and keysDict variables. You're leaking memory if you don't (unless you have GC on).

narendar
Jul 21, 2009, 07:00 AM
hi , im also sending images using NSMutableURLRequest with post method to my remote web page which is in ASP VB.net.

I have seen one tutroial which can upload a image from iphone to remote web(php page)

http://iphone.zcentric.com/2008/08/29/post-a-uiimage-to-the-web/#comment-8145

I am not getting how can I retrieve the image in my VB.net page??

Can any one suggest how can I do that ??

Thanks & Regards,
Narendar

lukeirvin
Sep 1, 2011, 11:42 AM
This post has helped me out a ton!

The one thing I can't figure out is how to make a module appear for users to enter their email / pass to log into tumblr to share the image.

any tips on this?