edit:
I need to upload a file asynchronously from an iPhone to a Python server-side process. I'd like to do the request asynchronously so that I can display a busy animation while it's working.
The request needs to include the username, password and file as 'multipart/form-data'.
I can get it working synchronously using NSURLConnection with the code looking like this::
-(void) uploadDatabase{
Database *databasePath = [[Database alloc] init];
NSString *targetPath = [databasePath getPathToDatabaseInDirectory];
NSData *dbData = [NSData dataWithContentsOfFile:targetPath];
NSString *url = #"http://mydomain.com/api/upload/";
//NSString *username = [[NSUserDefaults standardUserDefaults] stringForKey:USERNAME];
NSString *username = #"user";
NSString *password = #"pass";
NSMutableURLRequest *request = [self createRequestForUrl:url withUsername:username andPassword:password andData:dbData];
NSURLResponse *response;
NSError *error;
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *stringResult = [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
NSLog(#"**server info %#", stringResult);}
// Request construction
-(NSMutableURLRequest*) createRequestForUrl: (NSString*)urlString withUsername:(NSString*)username andPassword:(NSString*)password andData:(NSData*)dbData
{NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60.0];
[request setHTTPMethod:#"POST"];
NSString *boundary = #"BOUNDARY_STRING";
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#", boundary];
[request addValue:contentType forHTTPHeaderField:#"Content-Type"];
NSMutableData *body = [NSMutableData data];
if(dbData != NULL)
{
//only send these methods when transferring data as well as username and password
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"file\"; filename=\"dbfile\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:dbData]];
}
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"username\"\r\n\r\n%#", username] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"password\"\r\n\r\n%#", password] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
return request;}
However, when I try to do this asynchronously using NSURLSession it doesn't seem to work properly. The code with NSURLSession looks like this:
-(void)uploadDatabase{
Database *databasePath = [[Database alloc] init];
NSString *targetPath = [databasePath getPathToDatabaseInDirectory];
NSURL *phonedbURL = [NSURL URLWithString:targetPath];
NSString *url = #"http://mydomain.com/api/upload/";
NSString *username = #"user";
NSString *password = #"pass";
NSMutableURLRequest *request = [self createRequestForUrl:url withUsername:username andPassword:password andData:NULL];
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
self.uploadSession = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue:Nil];
NSLog(#"the url = %#",url);
NSURLSessionUploadTask *uploadTask = [self.uploadSession uploadTaskWithRequest:request fromFile:phonedbURL];
[uploadTask resume];}
I'm struggling to see what I'm doing differently though as it seems this should work.
Is using NSURLSession the right way to do asynchronous requests? and I'm new to NSURLSession so do I have to change my NSURLMutableRequest for NSURLSession requests rather than NSURLConnection?
Thanks in advance for any help!
You are correct, that if you just want to make your request asynchronous, you should retire sendSynchronousRequest. While we once would have recommended sendAsynchronousRequest, effective iOS 9, NSURLConnection is formally deprecated and one should favor NSURLSession.
Once you start using NSURLSession, you might find yourself drawn to it. For example, one can use a [NSURLSessionConfiguration backgroundSessionConfiguration:], then have uploads progress even after the app has gone into background. (You have to write a few delegate methods, so for simplicity's sake, I've stayed with a simple foreground upload below.) It's just a question of your business requirements, offsetting the new NSURLSession features versus the iOS 7+ limitation it entails.
By the way, any conversation about network requests in iOS/MacOS is probably incomplete without a reference to AFNetworking. It greatly simplifies creation of these multipart requests and definitely merits investigation. They have NSURLSession support, too (but I haven't used their session wrappers, so can't speak to it). But AFNetworking is undoubtedly worthy of your consideration. You can enjoy some of the richness of the delegate-base API (e.g. progress updates, cancelable requests, dependencies between operations, etc.), offering far greater control that available with convenience methods (like sendSynchronousRequest), but without dragging you through the weeds of the delegate methods themselves.
Regardless, if you're really interested in how to do uploads with NSURLSession, see below.
If you want to upload via NSURLSession, it is a slight shift in thinking, namely, separating the configuration of the request (and its headers) in the NSMutableURLRequest from the creation of the the body of the request (which you now specify during the instantiation of the NSURLSessionUploadTask). The body of the request that you now specify as part of the upload task can be either a NSData, a file, or a stream (I use a NSData below, because we're building a multipart request):
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
NSString *boundary = [self boundaryString];
[request addValue:[NSString stringWithFormat:#"multipart/form-data; boundary=%#", boundary] forHTTPHeaderField:#"Content-Type"];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
NSData *fileData = [NSData dataWithContentsOfFile:path];
NSData *data = [self createBodyWithBoundary:boundary username:#"rob" password:#"password" data:fileData filename:[path lastPathComponent]];
NSURLSessionUploadTask *task = [session uploadTaskWithRequest:request fromData:data completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSAssert(!error, #"%s: uploadTaskWithRequest error: %#", __FUNCTION__, error);
// parse and interpret the response `NSData` however is appropriate for your app
}];
[task resume];
And the creation of the NSData being sent is much like your existing code:
- (NSData *) createBodyWithBoundary:(NSString *)boundary username:(NSString*)username password:(NSString*)password data:(NSData*)data filename:(NSString *)filename
{
NSMutableData *body = [NSMutableData data];
if (data) {
//only send these methods when transferring data as well as username and password
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"file\"; filename=\"%#\"\r\n", filename] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Type: %#\r\n\r\n", [self mimeTypeForPath:filename]] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:data];
[body appendData:[#"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
}
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"username\"\r\n\r\n%#\r\n", username] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"password\"\r\n\r\n%#\r\n", password] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"--%#--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
return body;
}
You hardcoded the boundary and the mime type, which is fine, but the above happens to use the following methods:
- (NSString *)boundaryString
{
NSString *uuidStr = [[NSUUID UUID] UUIDString];
// If you need to support iOS versions prior to 6, you can use
// Core Foundation UUID functions to generate boundary string
//
// adapted from http://developer.apple.com/library/ios/#samplecode/SimpleURLConnections
//
// NSString *uuidStr;
//
// CFUUIDRef uuid = CFUUIDCreate(NULL);
// assert(uuid != NULL);
//
// NSString *uuidStr = CFBridgingRelease(CFUUIDCreateString(NULL, uuid));
// assert(uuidStr != NULL);
//
// CFRelease(uuid);
return [NSString stringWithFormat:#"Boundary-%#", uuidStr];
}
- (NSString *)mimeTypeForPath:(NSString *)path
{
// get a mime type for an extension using MobileCoreServices.framework
CFStringRef extension = (__bridge CFStringRef)[path pathExtension];
CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, extension, NULL);
assert(UTI != NULL);
NSString *mimetype = CFBridgingRelease(UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType));
assert(mimetype != NULL);
CFRelease(UTI);
return mimetype;
}
Related
Hi i am trying to upload an image through multipart to server in objective c using NSURLSession. But i am getting few errors like
org.apache.commons.fileupload.FileUploadException: Header section has more than 10240 bytes (maybe it is not properly terminated)
Below is my objective c code:
{
NSString *boundaryConstant = #"----------V2ymHFg03ehbqgZCaKO6jy";
NSString *fileParamConstant = #"photo";
NSMutableURLRequest *req = [[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:url]];
[req setHTTPMethod:#"POST"];
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data;boundary=%#",boundaryConstant];
[req setValue:contentType forHTTPHeaderField:#"Content-Type"];
NSMutableData *body = [NSMutableData data];
if (imageData) {
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"%#\"; filename=\"%#\"\r\n", fileParamConstant, fileName] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:imageData];
[body appendData:[[NSString stringWithFormat:#"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"--%#--\r\n", boundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]];
NSString *bodyLength = [NSString stringWithFormat:#"%zu",[body length]];
[req setValue:bodyLength forHTTPHeaderField:#"Content-Length"];
[req setHTTPBody:body];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:nil delegateQueue:nil];
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:req fromData:body completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(#"STRING %#", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}];
[uploadTask resume];
}
}
Any help would be greatly appreciated.
Thanks
I'm working on uploading an image to a server from last two days as there are tons of questions about uploading an image through AFNetworking and NSURLSession and other methods of uploading all I'm asking is I didn't found a single answer explaining the whole concept about how the things work and what is going on under the hood I searched youtube also all the stuff are available in Swift and trust me no Explanation at all and from my result I found this answer is something that looks familiar to me
//Init the NSURLSession with a configuration
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil delegateQueue: [NSOperationQueue mainQueue]];
//Create an URLRequest
NSURL *url = [NSURL URLWithString:#"yourURL"];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
//Create POST Params and add it to HTTPBody
NSString *params = #"api_key=APIKEY&email=example#example.com&password=password";
[urlRequest setHTTPMethod:#"POST"];
[urlRequest setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
//Create task
NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
//Handle your response here
}];
[dataTask resume];
and also the most popular answer about this topic is by User XJones is:-
Here's code from my app to post an image to our web server:
// Dictionary that holds post parameters. You can set your post parameters that your server accepts or programmed to accept.
NSMutableDictionary* _params = [[NSMutableDictionary alloc] init];
[_params setObject:[NSString stringWithString:#"1.0"] forKey:[NSString stringWithString:#"ver"]];
[_params setObject:[NSString stringWithString:#"en"] forKey:[NSString stringWithString:#"lan"]];
[_params setObject:[NSString stringWithFormat:#"%d", userId] forKey:[NSString stringWithString:#"userId"]];
[_params setObject:[NSString stringWithFormat:#"%#",title] forKey:[NSString stringWithString:#"title"]];
// the boundary string : a random string, that will not repeat in post data, to separate post data fields.
NSString *BoundaryConstant = [NSString stringWithString:#"----------V2ymHFg03ehbqgZCaKO6jy"];
// string constant for the post parameter 'file'. My server uses this name: `file`. Your's may differ
NSString* FileParamConstant = [NSString stringWithString:#"file"];
// the server url to which the image (or the media) is uploaded. Use your server url here
NSURL* requestURL = [NSURL URLWithString:#""];
// create request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:30];
[request setHTTPMethod:#"POST"];
// set Content-Type in HTTP header
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#", BoundaryConstant];
[request setValue:contentType forHTTPHeaderField: #"Content-Type"];
// post body
NSMutableData *body = [NSMutableData data];
// add params (all params are strings)
for (NSString *param in _params) {
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", BoundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"%#\"\r\n\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"%#\r\n", [_params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
}
// add image data
NSData *imageData = UIImageJPEGRepresentation(imageToPost, 1.0);
if (imageData) {
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", BoundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"%#\"; filename=\"image.jpg\"\r\n", FileParamConstant] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"Content-Type: image/jpeg\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:imageData];
[body appendData:[[NSString stringWithFormat:#"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
}
[body appendData:[[NSString stringWithFormat:#"--%#--\r\n", BoundaryConstant] dataUsingEncoding:NSUTF8StringEncoding]];
// setting the body of the post to the reqeust
[request setHTTPBody:body];
// set the content-length
NSString *postLength = [NSString stringWithFormat:#"%d", [body length]];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
// set URL
[request setURL:requestURL];
But my point is I'm learning on my own and it is very difficult to understand for the beginner without explanation so All I'm asking is an explanation, an Detail explanation about the whole process if someone have a hard time to spend on this question because believe it or not I found this the hardest topic till now because the main reason is there are no tutorials about the whole process and also no explanation at all for beginners if someone can a step now and explain the concept it'll be easier to the students who will learn tomorrow. So anybody who can explain this in detail and how the uploading process works and some steps for the reference will be greatly appreciated.
Note : Consider I Have an API and a Key "image" .
here we gonna look at image uploading along with some **parameters because most of time we upload image along with some parameters such as userId.
Before going deep into our topic let me provide the code for doing the stuff source,All the details we gonna see below are from some other stack overflow threads and some from other sites,i'll provide all the links for your reference.
-(void)callApiWithParameters:(NSDictionary *)inputParameter images:(NSArray *)image imageParamters:(NSArray *)FileParamConstant{
//1
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:30];
[request setHTTPMethod:#"POST"];
//2
NSString *boundary = #"------CLABoundaryGOKUL";
//3
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#", boundary];
[request setValue:contentType forHTTPHeaderField: #"Content-Type"];
//4
NSMutableData *body = [NSMutableData data];
for (NSString *key in inputParameter) {
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"%#\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"%#\r\n", [inputParameter objectForKey:key]] dataUsingEncoding:NSUTF8StringEncoding]];
}
for (int i = 0; i < image.count; i++) {
NSData *imageDatasss = UIImagePNGRepresentation(image[i]);
if (imageDatasss)
{
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"%#\"; filename=\"image.jpg\"\r\n", FileParamConstant[i]] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Type:image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:imageDatasss];
[body appendData:[[NSString stringWithFormat:#"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
}
}
[body appendData:[[NSString stringWithFormat:#"--%#--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
//5
[request setHTTPBody:body];
//6
[request setURL:[NSURL URLWithString:#"http://changeThisWithYourbaseURL?"]];//Eg:#"http://dev1.com/PTA_dev/webservice/webservice.php?"
//7
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
//8
if ([httpResponse statusCode] == 200) {
NSDictionary * APIResult =[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
NSLog(#"Response of %#: %#",[inputParameter valueForKey:#"service"],APIResult);
}else{
//9
NSLog(#"%#",error.localizedDescription);
}
}];
}
NOTE: Since it is a broad topic i have provided documentation link for detail info.
We are using ** NSMutableURLRequest** instead of ** NSURLRequest** because we gonna append some data to it.if you need some deep clarification about mutable url request go through this documentation.
setHTTPShouldHandleCookies here we have to decide whether we are going to use cookies or not.To know more about visit
setTimeoutInterval this helps to set a time limit to url request.Add time interval in seconds after the given time,request will be terminated.
setHTTPMethod there are many methods.But we use GET and POST methods in many cases.Difference between POST and GET is here and here
Boundary helps in separating the parameters from each other,so that the server can identify them.The boundary may be anything as your wish feel free to edit it.
Here we use multipart/form-data; boundary= as content type.To know why we are going to this content type look into this thread.
NSMutableData * body we gonna append all the parameters and values to this data and later setHTTPBody to the UrlRequest.
If this is how we call the 'callApiWithParameters' method
- (IBAction)Done:(id)sender{
NSDictionary * inputParameters = [NSDictionary dictionaryWithObjectsAndKeys:
#"1",#"user_id" ,
"XXX",#"name" ,
nil];
NSArray * image = [NSArray arrayWithObjects:[UIImage imageNamed:#"Test"],[UIImage imageNamed:#"Test1"],nil];
NSArray * imageParameters = [NSArray arrayWithObjects:#"img_one",#"img_two",nil];
[self callApiWithParameters:inputParameters images:image imageParamters:imageParameters];
}
then the data (i.e body) will look like this
Content-Type=multipart/form-data; boundary=------CLABoundaryGOKUL
--------CLABoundaryGOKUL
Content-Disposition: form-data; name=user_id
1
--------CLABoundaryGOKUL
Content-Disposition: form-data; name=name
XXX
--------CLABoundaryGOKUL
Content-Disposition: form-data; name=img_one; filename=image.jpg
Content-Type:image/jpeg
//First image data appended here
--------CLABoundaryGOKUL
Content-Disposition: form-data; name=img_two; filename=image.jpg
Content-Type:image/jpeg
//Second image data appended here.
The above give data will clearly explain what going on,all the parameters and keys have been append in the data Here you can find more details about sending multipart/form.
Now simply add the above data to request by [request setHTTPBody:body];
setURL in this method add your base url of your app.
Now all we need to do is make a connection to the server and send the request.Here we use NSURLConnection to send request.Description about NSURLConnection Loads the data for a URL request and executes a handler block on an operation queue when the request completes or fails.
statusCode which helps to find out whether we got successful response from server. If 200 means OK, 500 means Internal Server Error, etc.. more details here .
Handle the error in else case.
FYI I have explained what i can,refer the links for better understanding.
EDIT:
Just change the name in imageParamater array,To satisfy your requirement changed img_one & img_two with image.
- (IBAction)Done:(id)sender{
//Change input parameters as per your requirement.
NSDictionary * inputParameters = [NSDictionary dictionaryWithObjectsAndKeys:
#"1",#"user_id" ,
"XXX",#"name" ,
nil];
NSArray * image = [NSArray arrayWithObjects:[UIImage imageNamed:#"Test"],nil]; //Change Test with your image name
NSArray * imageParameters = [NSArray arrayWithObjects:#"image",nil];//Added image as a key.
[self callApiWithParameters:inputParameters images:image imageParamters:imageParameters];
}
and Change Point 6 with your example base URL,
//6
[request setURL:[NSURL URLWithString:#"http://google.com/files/upload.php?"]];
I think it's Helpful for you...
- (void)sendImageToServer
{
UIImage *yourImage= [UIImage imageNamed:#"image.png"];
NSData *imageData = UIImagePNGRepresentation(yourImage);
NSString *base64 = [imageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
NSString *strImage = [NSString stringWithFormat:#"data:image/png;base64,%#",base64];
NSMutableDictionary *dic = [[NSMutableDictionary alloc] initWithObjectsAndKeys:strImage,#"image", nil];
NSError * err;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:0 error:&err];
NSString *UserProfileInRequest = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSData *data=[UserProfileInRequest dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *len = [NSString stringWithFormat:#"%ld", (unsigned long)[data length]];
// Init the URLRequest
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] init];
[req setURL:[NSURL URLWithString:#"http://YOUR_URL"]];
[req setHTTPMethod:#"POST"];
[req setValue:len forHTTPHeaderField:#"Content-Type"];
[req setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[req setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[req setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[req setHTTPBody:data];
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithRequest:req completionHandler:^(NSData *dt, NSURLResponse *response, NSError *err){
//Response Data
NSMutableDictionary *dic = [NSJSONSerialization JSONObjectWithData:dt options:kNilOptions error:&err];
NSLog(#"%#", [dic description]);
}]resume];
}
Use AFNetworking For this task which will give very easy and reliable solution.
I am trying to upload a photo onto a server on my iOS App using multipart method. However, I can't seem to get it to work. I am getting the error:
At least one of the pre-conditions you specified did not hold. Bucket POST must be of the enclosure-type multipart. I've looked this error and can't seem to figure out how I can solve this problem on my end. The Android version of the app works so the API should not be the problem?
Here is my code:
//photo file
NSData *data = [[NSFileManager defaultManager] contentsAtPath:filePath];
NSMutableDictionary* _params = [[NSMutableDictionary alloc] init];
[_params setObject:uploadInfo.key forKey:#"key"];
[_params setObject:uploadInfo.aaki forKey:#"AWSAccessKeyId"];
[_params setObject:uploadInfo.acl forKey:#"acl"];
[_params setObject:uploadInfo.policy forKey:#"policy"];
[_params setObject:uploadInfo.signature forKey:#"signature"];
[_params setObject:uploadInfo.success_action_status forKey:#"success_action_status"];
[_params setObject:#"image/jpeg" forKey:#"Content-Type"];
NSURL* requestURL = [NSURL URLWithString:uploadInfo.path];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:30];
[request setHTTPMethod:#"POST"];
NSMutableData *body = [NSMutableData data];
for (NSString *param in _params) {
[body appendData:[[NSString stringWithFormat:#"%#", [_params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
}
if (data) {
[body appendData:data];
}
[request setHTTPBody:body];
[request setURL:requestURL];
NSURLResponse * response = nil;
NSError * error = nil;
NSData * data1 = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *responseString = [[NSString alloc] initWithData:data1 encoding:NSUTF8StringEncoding];
NSLog(#"%#",responseString);
Try as below.
//photo file
NSData *data = [[NSFileManager defaultManager] contentsAtPath:filePath];
NSMutableDictionary* _params = [[NSMutableDictionary alloc] init];
[_params setObject:uploadInfo.key forKey:#"key"];
[_params setObject:uploadInfo.aaki forKey:#"AWSAccessKeyId"];
[_params setObject:uploadInfo.acl forKey:#"acl"];
[_params setObject:uploadInfo.policy forKey:#"policy"];
[_params setObject:uploadInfo.signature forKey:#"signature"];
[_params setObject:uploadInfo.success_action_status forKey:#"success_action_status"];
NSURL* requestURL = [NSURL URLWithString:uploadInfo.path];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:30];
[request setHTTPMethod:#"POST"];
//Create boundary, it can be anything
NSString *boundary = #"------VohpleBoundary4QuqLuM1cE5lMwCy";
// set Content-Type in HTTP header
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#", boundary];
[request setValue:contentType forHTTPHeaderField: #"Content-Type"];
NSMutableData *body = [NSMutableData data];
for (NSString *param in _params) {
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"%#\"\r\n\r\n", param] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"%#\r\n", [_params objectForKey:param]] dataUsingEncoding:NSUTF8StringEncoding]];
}
NSString *FileParamConstant = #"image"; // Key of webservice in which you need to send image
// add image data
if (data) {
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"%#\"; filename=\"image.jpg\"\r\n", FileParamConstant] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:data];
[body appendData:[[NSString stringWithFormat:#"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
}
//Close off the request with the boundary
[body appendData:[[NSString stringWithFormat:#"--%#--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
// set the content-length
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[body length]];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setURL:requestURL];
NSURLResponse * response = nil;
NSError * error = nil;
NSData * data1 = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
Try with another simple code.
NSDictionary *aParams =#{}; //your param dictionary here
UIImage *aImage = [UIImage imageNamed:#"your image here"]; //set yout image here
NSString *aStrParamName = #"image parameter name here";// set parameter name of image here
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"uploadInfo.path"]];// url here
[request setHTTPMethod:#"POST"];
[request setTimeoutInterval:30];
NSString *uuidStr = [[NSUUID UUID] UUIDString];
[request addValue:[NSString stringWithFormat:#"multipart/form-data; boundary=%#", uuidStr] forHTTPHeaderField:#"Content-Type"];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
NSData *imagedata = UIImageJPEGRepresentation(aImage, (CGFloat)0.6);
NSData *fileData = UIImagePNGRepresentation([UIImage imageWithData:imagedata]);
NSData *data = [self createBodyWithBoundary:uuidStr withDictData:aParams data:fileData filename:aStrParamName];
NSURLSessionUploadTask *task = [session uploadTaskWithRequest:request fromData:data completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSAssert(!error, #"%s: uploadTaskWithRequest error: %#", __FUNCTION__, error);
// parse and interpret the response `NSData` however is appropriate for your app
NSString *aStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"ResponseString:%#",aStr);
NSMutableDictionary *aMutDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"responce:%#",aMutDict);
});
}];
[task resume];
also add below method
- (NSData *)createBodyWithBoundary:(NSString *)boundary withDictData:(NSDictionary *)aDict data:(NSData*)data filename:(NSString *)paramName
{
NSMutableData *body = [NSMutableData data];
if (data) {
//only send these methods when transferring data as well as username and password
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"%#\"; filename=\"%#\"\r\n", paramName,#"image.png"] dataUsingEncoding:NSUTF8StringEncoding]];
#warning if you have to chane name of image then change. if there is any error then chane other wise go as it is..
[body appendData:[[NSString stringWithFormat:#"Content-Type: %#\r\n\r\n", #"image/png"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:data];
[body appendData:[#"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
}
for (NSString *aKey in aDict.allKeys) {
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"%#\"\r\n\r\n%#\r\n", aKey,aDict[aKey]] dataUsingEncoding:NSUTF8StringEncoding]];
}
[body appendData:[[NSString stringWithFormat:#"--%#--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
return body;
}
I am trying upload an image along with some form fields. I am able to upload image to server using the following link as a reference.
File Upload to HTTP server in iphone programming
But if i try to send some form fields along with the image i am error response. Here is the code i am using
-(void)saveData{
NSString *urlString = #"Sample url";
NSString *filename = #"filename";
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 *postbody = [NSMutableData data];
[postbody appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[self generateDataFromText:FORM DATA IN JSON fieldName:#"add_product"]];
[postbody appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"files\"; filename=\"%#.jpg\"\r\n", filename] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[#"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[NSData dataWithData:fileData]];
[postbody appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:postbody];
[request setValue:APIKEY forHTTPHeaderField:#"X-API-KEY"];
NSURLResponse *urlResp;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResp error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSHTTPURLResponse *resp = (NSHTTPURLResponse *) urlResp;
NSLog(#"status code: %ld, response string: %#",(long)[resp statusCode],returnString);
}
-(NSMutableData *)generateDataFromText:(NSString *)dataText fieldName:(NSString *)fieldName
{
NSString *post = [NSString stringWithFormat:#"--AaB03x\r\nContent-Disposition: form-data; name=\"%#\"\r\n\r\n", fieldName];
// Get the post header int ASCII format:
NSData *postHeaderData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
// Generate the mutable data variable:
NSMutableData *postData = [[NSMutableData alloc] initWithLength:[postHeaderData length]];
[postData setData:postHeaderData];
NSData *uploadData = [dataText dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
// Add the text:
[postData appendData: uploadData];
// Add the closing boundry:
[postData appendData: [#"\r\n" dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]];
// Return the post data:
return postData;
}
So some one please help me to send form data along with am image to PHP server using POST method. Thanks in advance.
Every Field should be in its own boundary #"\r\n--%#\r\n". So make the following changes to make the code work.
Remove the line:
[postbody appendData:[self generateDataFromText:FORM DATA IN JSON fieldName:#"add_product"]];
And after the line
[postbody appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
put the following code:
[postbody appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; add_product=\"%#\"\r\n\r\n",key] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[[self generateDataFromText:FORM DATA IN JSON] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[[NSString stringWithString:#"\r\n--%#\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
for every field, you need to add these 4 lines.
You should think to use AFNetworking instead. Its easy to work.
Getting it to work with AFNetworking is very easy. Add AFNetworking into your project through Cocoapods, here are the instructions:
https://github.com/AFNetworking/AFNetworking
Once AFNetworking is setup, use the following code:
NSString *apiName = URL;
UIImage *yourImage;
NSData *imgData = UIImageJPEGRepresentation(yourImage,1.0);
imgData = [imgData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];];
NSData *otherFields = [self generateDataFromText:FORM DATA IN JSON];
NSDictionary * params = [[NSDictionary alloc] initWithObjectsAndKeys:imgData, #"imgFieldName",otherFields,#"add_product",nil];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:apiName parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
//posted successfully
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//failed
}];
This is very simple Post method with image encoded in Base64. You can add as many fields into params dictionary as needed.
I want to send my image with parameter (username, password..etc) ?? following is my code:
-(void) senRequestForPostAnswerWithImage:(NSString *)imageName andAnswer:(NSString *)answer andQuestionID:(NSString *)questionID
{
NSUserDefaults *loginData = [NSUserDefaults standardUserDefaults];
NSString *username = [loginData objectForKey:#"username"] ;
NSString *password = [loginData objectForKey:#"password"];
NSString *postString = [NSString stringWithFormat:#"&username=%#&password=%#&image=%#&answer=%#&question_id=%#", username, password, imageName, answer, questionID];
NSString *urlString = #"http://myAPIName/MethodName";
NSURL *myURL = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSMutableURLRequest *detailRequestToServer =[NSMutableURLRequest requestWithURL:myURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0];
[detailRequestToServer setHTTPMethod:#"POST"];
[detailRequestToServer setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
const char *utfString = [postString UTF8String];
NSString *utfStringLenString = [NSString stringWithFormat:#"%zu", strlen(utfString)];
[detailRequestToServer setHTTPBody:[NSData dataWithBytes: utfString length:strlen(utfString)]];
[detailRequestToServer setValue:utfStringLenString forHTTPHeaderField:#"Content-Length"];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:detailRequestToServer delegate:self];
if (theConnection)
{
self.responseData = [[NSMutableData alloc] init];
[GeneralClass startHUDWithLabel:#"Loading…"];
}
else
NSLog(#"Connection Failed!");
}
I know there are many question on this site but I don't know where and what I need to change in my existing code ??
So, please suggest me what I need to change in my existing code for add functionality of send image ??
NOTE: without image this above code is working well for me.
My suggestion would be to use AFNetworking. It will simplify the process for your considerably and save you a lot of time. It is widely used framework by developers.
https://github.com/AFNetworking/AFNetworking
You can easily send image with parameters using just few lines (POST-multipart request):
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = #{#"foo": #"bar"};
NSURL *filePath = [NSURL fileURLWithPath:#"file://path/to/image.png"];
[manager POST:#"http://example.com/resources.json" parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileURL:filePath name:#"image" error:nil];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Success: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
As far as I know, you can't directly send it as UIImage. You need to convert it to NSData, which the gets decoded on the server side.
Another alternative, is to upload the image somewhere, which can be accessed via a URL. (But this is usually done on the server side and the URL is given back as response).
There's a post here about converting UIImage to NSData.
using this you can pass parameters as well as with image data.
NSString *urlString = [NSString stringWithFormat:#"http://myAPIName/MethodName/test.php&username=%#&password=%#&image=%#&answer=%#&question_id=%#", username, password, imageName, answer, questionID];
NSLog(#"MyURL: %#",urlString);
urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
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]];
NSString *str=[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"SourceImage\"; filename=\"Image_%#\"\r\n",[imagePath lastPathComponent]];
[body appendData:[[NSString stringWithString:str] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithContentsOfFile:imagePath]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
If you want to send parameter with image by post method then use following code. Its working very well for me..
I tried to change my code as per your requirement, follow it.
You need to create NSMutableDictionary and add your parameter on it and also append this dictionary to NSMutableData as JSON formate. (You need to add NSMutableData Library to your project)
-(void) senRequestForPostAnswerWithImage:(NSString *)imageName andAnswer:(NSString *)answer andQuestionID:(NSString *)questionID
{
NSUserDefaults *loginData = [NSUserDefaults standardUserDefaults];
NSString *username = [loginData objectForKey:#"username"] ;
NSString *password = [loginData objectForKey:#"password"];
// create NSMutableDictionary for store parameter
NSMutableDictionary *dicOfData = [[NSMutableDictionary alloc] init];
[dicOfData setObject:username forKey:#"username"];
[dicOfData setObject:password forKey:#"password"];
[dicOfData setObject:imageName forKey:#"imageName"];
[dicOfData setObject:answer forKey:#"answer"];
[dicOfData setObject:questionID forKey:#"questionID"];
NSString *url = #"http://myAPIName/MethodName";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0];
[request setHTTPMethod:#"POST"];
/// create NSMutableData to store data of dictionary
NSMutableData *body = [NSMutableData data];
NSString *boundary = #"--iOS Boundary Line--";
[request addValue:[NSString stringWithFormat:#"multipart/form-data; boundary=%#", boundary] forHTTPHeaderField: #"Content-Type"];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *imgPath = [documentsDir stringByAppendingPathComponent:imageName];
if([imageName length] > 0)
{
if([[NSFileManager defaultManager] fileExistsAtPath:imgPath])
{
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"photo\"; filename=\"%#\"\r\n", imageName] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithContentsOfFile:imgPath]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
}
}
[body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"requestData\"\r\n\r\n%#", [dicOfData JSONRepresentation] ] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
[request addValue:[NSString stringWithFormat:#"%d", [body length]] forHTTPHeaderField:#"Content-Length"];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (theConnection)
{
self.responseData = [[NSMutableData alloc] init];
}
else
NSLog(#"Connection Failed!");
}
At your server (PHP) side.. you get image (object and name if you added) with other parameter in dictionary formate.
Refer this code - It works perfect for me -
NSString *userID = mainDelegate.loginUserPin;
UIImage *imag = self.addImage;
NSString *urlString = mainDelegate.I2K2_Webservice_Url;
NSData *imageData = UIImageJPEGRepresentation(imag, 90);
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
[request setTimeoutInterval:6*60000];
NSString *boundary = #"*****";
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]];
//Title
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Disposition: form-data; name=\"title\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"%#~%#",userID,txtName.text] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
//Description
[body appendData:[#"Content-Disposition: form-data; name=\"description\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
NSString *imgNameString = [NSString stringWithFormat:#"Content-Disposition: form-data; name=\"uploadedfile\"; filename=\"%#~%#\"\r\n",userID,txtName.text];
NSLog(#"imgNameString : %#",imgNameString);
[body appendData:[[NSString stringWithString:imgNameString] 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]];
[request setHTTPBody:body];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(#"%#",returnString);
You cant send UIImage by specifying it's name to web server. You should include it in the HTTP body as NSData .I used ASIHTTPRequest, it was simple and perfect. Use ASIHTTPRequest. A sample code is given below
NSData *imgData = UIImageJPEGRepresentation(IMAGE_HERE, 0.9);
formReq = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:urlString]];
formReq.delegate = self;
[formReq setPostValue:VALUE1 forKey:KEY1];
[formReq setPostValue:VALUE2 forKey:KEY2];
if (imgData) {
[formReq setData:imgData withFileName:#"SAMPLE.jpg" andContentType:#"image/jpeg" forKey:IMAGE_KEY];
}
[formReq startSynchronous];