Very first question here...
I'm desperately trying to upload a photo to Facebook from my Mac OS App (cocoa), using an HTTP POST request.
Using the "https://graph.facebook.com/me/photos?access_token=....." followed by "source=MyURLOnline.jpg", it works great, but I need to upload the DATA, not a link of an image already on the Web...
So I'm switching "feed" to "photos", and the URL by the RAW data of my NSImage (and maybe the "source=" to "image=" ?).
But : I set the header of my request to "multipart/form-data, boundary=%AaB03x" and add some "\r\n" and "Content-Type: image/jpeg\r\n\r\n" etc to the body, but the only thing I get is the error "(#324) Requires upload file"...
I have a few years of experience on Cocoa but don't know anything about HTTP request, and especially what is the Graph API expecting, so I've read all Facebook help I found, would have loved to find an example as I'm sure I make several mistakes, but I'm wondering if it is just possible at all.
ANY help appreciated !
UPDATE:
Thank you very much Anvesh.
If you know that I should POST a JSON then I spent my day trying to figure out how to do that, but no success yet.
Here is my code, if I POST a "source=URLOnline.jpg" to the "feed" (and remove the HTTPHeader and the Body), my image shows on my wall. With my image data to the "photos", the only hint I receive is the #324 error...
Wondering where I can find out what I should exactly write in the HTTPBody.
// Convert NSImage to data
NSImage * MyIm = [[NSImage alloc] initWithContentsOfURL:[MyLogoPath URL]];
NSData *imageData = [MyIm TIFFRepresentation];
NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageData];
imageData = [imageRep representationUsingType:NSPNGFileType properties:nil];
// HTTP Request with access token
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init] ;
NSString * MyStr = [#"https://graph.facebook.com/me/photos?access_token=" stringByAppendingString:FacebookToken]; // feed?access_token
[request setURL:[NSURL URLWithString:MyStr]];
[request setHTTPMethod:#"POST"];
const char *bytes = [[NSString stringWithFormat:#"&image="] UTF8String];
// const char *bytes = [[NSString stringWithFormat:#"&source=http://www.google.ca/intl/en_ALL/images/logos/images_logo_lg.gif"] UTF8String];
NSMutableData * MyData = [NSMutableData dataWithBytes:bytes length:strlen(bytes)];
// HTTP Header
NSString * boundary = [NSString stringWithFormat:#"AaB03x"];
NSString * contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#", boundary];
[request addValue:contentType forHTTPHeaderField:#"Content-Type"];
// HTTP Body
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Disposition: attachment; name=\"image\"; filename=\".jpg\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imageData]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[MyData appendData:body];
[request setHTTPBody:MyData];
[[FacebookView mainFrame] loadRequest:request];
// NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:MyURLRequest delegate:self];
// [connection start];
// [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// }];
Thank you Anvesh, with your help and a Cocoa post about HTTP POST, I finally managed to create my NSURLRequest to upload my NSImage to Facebook.
I hope it will save a lot of trouble to people connecting their Mac App to Facebook, as there is no SDK.
// Convert the NSImage to NSData
NSData *imageData = [MyIm TIFFRepresentation];
NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageData];
imageData = [imageRep representationUsingType:NSPNGFileType properties:nil];
// Create the URL request with the access token
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init] ;
NSString * MyStr = [#"https://graph.facebook.com/me/photos?access_token=" stringByAppendingString:FacebookToken];
[request setURL:[NSURL URLWithString:MyStr]];
[request setHTTPMethod:#"POST"];
// Create the header and body of the request with all those settings
NSMutableData *body = [NSMutableData data];
NSString * boundary = [NSString stringWithFormat:#"Random_Boundary_Chars"];
NSString *contentType2 = [NSString stringWithFormat:#"multipart/form-data; boundary=%#", boundary];
[request addValue:contentType2 forHTTPHeaderField:#"Content-Type"];
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Disposition: attachment; name=\"image\"; filename=\".tiff\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imageData]];
[body appendData:[#"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"--%#--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
// [[FacebookView mainFrame] loadRequest:request];
// Send the request, not showing in the webview
NSData * returnData = [ NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil ];
NSString * returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(#"Returned Json: %#", returnString);
//NSImage is now on Facebook's wall and we got the ID returned.
Related
I currently upload images in the background to a server like this (the names get changed at the server to something better).
buildURL = [buildURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSData *imageData = UIImageJPEGRepresentation(imageToUpload, 1.0); //change Image to NSData
if (imageData != nil)
{
NSString *filenames = [NSString stringWithFormat:#"imagename"]; //set name here
NSLog(#"%#", filenames);
NSString *urlString = buildURL;
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
NSString *boundary = #"---------------------------14737809831466499882746641449";
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"filenames\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[filenames dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Disposition: form-data; name=\"userfile\"; filename=\".jpg\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imageData]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// setting the body of the post to the reqeust
[request setHTTPBody:body];
// now lets make the connection to the web
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
{
NSString *returnString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Returned From Image Upload : %#",returnString);
}];
}
This works fine, I can see the images finish in the background no problem. The thing is I want to change this to use NSURLSession and the delegate didSendBodyData so that I can monitor the upload.
I have found a load of information about the download but none really about upload. I have tried to do this with the request BUT the completion block NEVER happens.. I have also tried using uploadTaskWithStreamedRequest but I can not get the delegate to happen...
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil];
NSURLSessionDataTask *uploadTask = [session uploadTaskWithRequest:request fromData:imageData completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
NSLog(#"Image Uploaded ------------");
}];
[uploadTask resume];
I also found this StackOverflow 19985353 which seems to highlight some problems but I could really do with some example code. The image is picked from imagePicker if that helps.
I also tried both the answers here StackOverflow 19099448 but neither of them worked, again the block never executed. Is there something fundamental I am doing wrong with NSURLSession, a framework maybe! I also note I have no idea about the HTTP body which I have tried to play with but no luck.
Okay I did not realise that Session only works in iOS7 and above. To this end I have done a test and if iOS6 then I use NSURLConnection. The problem is I cannot get progress status from this (with the session I have an upload bar).
If anyone has any ideas about an upload progress bar using NSURLConnection then I would love to hear about it.
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:_urlToUpload];// create request
[request setHTTPMethod:#"POST"];// request type
[request setTimeoutInterval:60];
[request setValue:#"application/octet-stream" forHTTPHeaderField: #"Content-Type"];// content type
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];// configuration
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil];// session
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromFile:file completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { }
Use the delegates
#pragma mark -
#pragma mark Session Upload Delegate Methods
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend {
float status = (double)totalBytesSent / (double)totalBytesExpectedToSend;
[[MTFileStreamer sharedFileStreamer] setCurrentStatus:status];
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
NSLog(#"%s", __PRETTY_FUNCTION__);
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response
newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest *))completionHandler {
NSLog(#"%s", __PRETTY_FUNCTION__);
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
NSLog(#"%s", __PRETTY_FUNCTION__);
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task needNewBodyStream:(void (^)(NSInputStream *bodyStream))completionHandler {
NSLog(#"%s", __PRETTY_FUNCTION__);
}
I am making an application which has the option to choose multiple photos, those photos are then saved in an array, as I can do to send that photo array to the server...
I tried but I'm not able to get.. I hope you can help me with this..
This is my code:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
NSString *mediaType=info[UIImagePickerControllerMediaType];
NSData*dataImage=UIImageJPEGRepresentation([infoobjectForKey:#"UIImagePickerControllerOriginalImage"];
UIImage *image = [[UIImage alloc] initWithData:dataImage];
[arrayImagenes addObject:dataImage];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)ActualizarReporte:(id)sender {
NSString *urlString = #"http://appsiste.com/test/uploadimage.php";
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
NSString *boundary = #"---------------------------14737809831466499882746641449";
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
NSMutableData *body = [NSMutableData data];
for (int i=0; i<[arrayImagenes count]; i++)
{
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"userfile\"; filename=\".jpg\"\r\n"]] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:[arrayImagenes objectAtIndex:i]]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
}
[request setHTTPBody:body];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString=[[NSString alloc]initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(#"%#",returnString);
}
no se si estare bien lo que estoy haciendo..alguna idea por favor de como lo pueda hacer..me esta dando muchos dolores de cabeza..esto es lo que me muestra cuando ejecuto :
<html>
<head><title>413 Request Entity Too Large</title></head>
<body bgcolor="white">
<center><h1>413 Request Entity Too Large</h1></center>
<hr><center>nginx/1.1.19</center>
</body>
</html>
Thanks...
I’ve been trying to follow some examples for uploading data to a website. I want to save the message as a .txt file. Any ideas what to do here?
- (IBAction)sendSerializedGreeting:(id)sender;
{
NSString *message;
message =#"Here we go for a test message.";
// Show a loading indicator
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSString *greetingURL = [NSString stringWithFormat:#"http://www.site.com/upload.php"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:greetingURL]
cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
NSDictionary *headerFieldsDict = [NSDictionary dictionaryWithObjectsAndKeys:#"text/xml; charset=utf-8", #"Content-Type", nil];
[theRequest setHTTPBody:[message dataUsingEncoding:NSUTF8StringEncoding]];
[theRequest setAllHTTPHeaderFields:headerFieldsDict];
[theRequest setHTTPMethod:#"POST"];
// create the connection with the request and start loading the data
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection == nil)
{
NSLog(#"Failed to create the connection");
}
}
Here is the upload.php file. I’m assuming the issue is with this but not sure. I don’t know where the filename gets set in the example above. This code was used from somewhere else.
<?php
$uploaddir = './'; //Uploading to same directory as PHP file
$file = basename($_FILES['userfile']['name']);
$uploadFile = $file;
$randomNumber = rand(0, 99999);
$newName = $uploadDir . $randomNumber . $uploadFile;
if (is_uploaded_file($_FILES['userfile']['tmp_name'])) {
echo "Temp file uploaded.";
} else {
echo "Temp file not uploaded.";
}
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $newName)) {
}
?>
I am sending a image to server through this code .... use for your text file or any type of multiform data
NSString *strUrl=#"http://www.site.com/upload.php";
NSLog(#"%#",strUrl);
NSURL *url=[NSURL URLWithString:strUrl];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:130.0];
// file name of user picture
// I am sending a image to server
NSString *fileName=[[eMailTxtField.text stringByReplacingOccurrencesOfString:#"#" withString:#"-"] stringByAppendingString:#".jpg"];
//image data
UIImage *userImage=imgUser.image;
NSData *imageData =UIImageJPEGRepresentation(userImage, 90);
NSMutableData *myRequestData = [[NSMutableData alloc] init];
[myRequestData appendData:[NSData dataWithBytes:[postData UTF8String] length:[postData length]]];
NSString *boundary = [NSString stringWithString:#"--"];
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
[myRequestData appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[myRequestData appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"uploadfile\"; filename=\"%#\"\r\n", fileName] dataUsingEncoding:NSUTF8StringEncoding]];
[myRequestData appendData:[[NSString stringWithString:#"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[myRequestData appendData:[NSData dataWithData:imageData]];
[myRequestData appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[ request setHTTPMethod: #"POST" ];
[ request setHTTPBody: myRequestData ];
NSURLResponse *response;
NSError *error;
NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse:&response error:&error];
if (!error && returnData) {
NSString *content = [NSString stringWithUTF8String:[returnData bytes]];
[self registerWithJsonString:content];
}
else{
[self showServerNotFoundError];
}
I have the following code which uploads an image to a web site.
[request setURL:nsurl];
[request setHTTPMethod:#"POST"];
NSString *boundary = [NSString stringWithString:#"---------------------------14737809831466499882746641449"];
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
/*
now lets create the body of the post
*/
NSMutableData *body = [NSMutableData data];
//parameter1
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"guid\"\r\n\r\n%#", [Settings sharedInstance].uploadID] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
//Image
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"filMyFile\"; filename=\"%#\"\r\n", fileName] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Type: image/png\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:dataObj]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// setting the body of the post to the reqeust
[request setHTTPBody:body];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
All is well when running over HTTP, but when I switch to HTTPS it fails with
Error: Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo=0x1c7f70 {NSErrorFailingURLStringKey=https:.......
The server it is communicating with is MS Server 2008 R2.
Any ideas would be appreciated.
Neil.
Refer Using NSURLConnection for https connection
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html
This code snippet isn't working, I'm getting an "Authentication Failed." response from the server. Any ideas?
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
initWithURL:
[NSURL URLWithString:#"http://www.tumblr.com/api/write"]];
[request setHTTPMethod:#"POST"];
[request addValue:_tumblrLogin forHTTPHeaderField:#"email"];
[request addValue:_tumblrPassword forHTTPHeaderField:#"password"];
[request addValue:#"regular" forHTTPHeaderField:#"type"];
[request addValue:#"theTitle" forHTTPHeaderField:#"title"];
[request addValue:#"theBody" forHTTPHeaderField:#"body"];
NSLog(#"Tumblr Login:%#\nTumblr Password:%#", _tumblrLogin, _tumblrPassword);
[NSURLConnection connectionWithRequest:request delegate:self];
[request release];
Both _tumblrLogin and _tumblrPassword are run through stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding elsewhere in my code. My login email is of the form "address+test#test.com". It works just fine for logging in directly to tumblr, but I'm wondering if the "+" character is causing problems with the encoding? It's not being escaped. Should it be?
Thanks to Martin's suggestion, I'm now using CFURLCreateStringByAddingPercentEscapes to escape my login and password. I'm still having the same issue, though, my Authentication is failing.
The problem is that you are not creating a proper HTTP POST request. A POST request requires a properly formatted multipart MIME-encoded body containing all the parameters you want to send to the server. You are trying to set the parameters as HTTP headers which won't work at all.
This code will do what you want, note especially the NSString categories that create a valid Multipart MIME string:
#interface NSString (MIMEAdditions)
+ (NSString*)MIMEBoundary;
+ (NSString*)multipartMIMEStringWithDictionary:(NSDictionary*)dict;
#end
#implementation NSString (MIMEAdditions)
//this returns a unique boundary which is used in constructing the multipart MIME body of the POST request
+ (NSString*)MIMEBoundary
{
static NSString* MIMEBoundary = nil;
if(!MIMEBoundary)
MIMEBoundary = [[NSString alloc] initWithFormat:#"----_=_YourAppNameNoSpaces_%#_=_----",[[NSProcessInfo processInfo] globallyUniqueString]];
return MIMEBoundary;
}
//this create a correctly structured multipart MIME body for the POST request from a dictionary
+ (NSString*)multipartMIMEStringWithDictionary:(NSDictionary*)dict
{
NSMutableString* result = [NSMutableString string];
for (NSString* key in dict)
{
[result appendFormat:#"--%#\r\nContent-Disposition: form-data; name=\"%#\"\r\n\r\n%#\r\n",[NSString MIMEBoundary],key,[dict objectForKey:key]];
}
[result appendFormat:#"\r\n--%#--\r\n",[NSString MIMEBoundary]];
return result;
}
#end
#implementation YourObject
- (void)postToTumblr
{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
initWithURL:
[NSURL URLWithString:#"http://www.tumblr.com/api/write"]];
[request setHTTPMethod:#"POST"];
//tell the server to expect 8-bit encoded content as we're sending UTF-8 data,
//and UTF-8 is an 8-bit encoding
[request addValue:#"8bit" forHTTPHeaderField:#"Content-Transfer-Encoding"];
//set the content-type header to multipart MIME
[request addValue: [NSString stringWithFormat:#"multipart/form-data; boundary=%#",[NSString MIMEBoundary]] forHTTPHeaderField: #"Content-Type"];
//create a dictionary for all the fields you want to send in the POST request
NSDictionary* postData = [NSDictionary dictionaryWithObjectsAndKeys:
_tumblrLogin, #"email",
_tumblrPassword, #"password",
#"regular", #"type",
#"theTitle", #"title",
#"theBody", #"body",
nil];
//set the body of the POST request to the multipart MIME encoded dictionary
[request setHTTPBody: [[NSString multipartMIMEStringWithDictionary: postData] dataUsingEncoding: NSUTF8StringEncoding]];
NSLog(#"Tumblr Login:%#\nTumblr Password:%#", _tumblrLogin, _tumblrPassword);
[NSURLConnection connectionWithRequest:request delegate:self];
[request release];
}
#end
As per the answers to this question, stringByAddingPercentEscapesUsingEncoding: doesn't perform a full escape encoding. For whatever reason, the CoreFoundation version of this method does, however:
[(NSString *) CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)[[self mutableCopy] autorelease], NULL,
CFSTR("=,!$&'()*+;#?\n\"<>#\t :/"), kCFStringEncodingUTF8) autorelease];
You can also use NSMutableString's replaceOccurencesOfString:withString:options: method to do the replacement manually, but that method is more repetitive and verbose. (See here.)