How to upload multiple images without using ASIHTTPRequest - objective-c

I want to upload two images to the server with following code can any one please help me, here is my code for post data
- (void)uploadPath:(NSString*)path withOptions:(NSDictionary*)options withImageData1:(NSData*)data1 ofImageName1:(NSString *)imageName1 andImageData2:(NSData*)data2 ofImageName2:(NSString *)imageName2 {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSURL *url = [NSURL URLWithString:path relativeToURL:[NSURL URLWithString:baseURLString]];
NSMutableURLRequest *mutableRequest = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:90.0];
NSString *boundary = #"-------1234567";
[mutableRequest setValue:[NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary] forHTTPHeaderField:#"Content-Type"];
[mutableRequest setHTTPMethod:#"POST"];
NSMutableData *postbody = [NSMutableData data];
for(NSString *key in options)
{
NSString *value = [options objectForKey:key];
[postbody appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"%#\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[value dataUsingEncoding:NSUTF8StringEncoding]];
}
[postbody appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
//******************* Append 1st Image ************************/
if ([imageName1 isEqualToString:#"picture1.jpg"]) {
[postbody appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"picture1\"; filename=\"%#\"\r\n",imageName1] dataUsingEncoding:NSUTF8StringEncoding]];
}
[postbody appendData:[[NSString stringWithString:#"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[NSData dataWithData:data1]];
[postbody appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
//******************* Append 1st Image ************************/
//******************* Append 2nd Image ************************/
if ([imageName2 isEqualToString:#"picture2.jpg"]) {
[postbody appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"picture2\"; filename=\"%#\"\r\n",imageName2] dataUsingEncoding:NSUTF8StringEncoding]];
}
[postbody appendData:[[NSString stringWithString:#"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[NSData dataWithData:data2]];
//******************* Append 2nd Image ************************/
[mutableRequest setHTTPBody:postbody];
urlConnection = [[NSURLConnection alloc] initWithRequest:mutableRequest delegate:self];
if (self.urlConnection) {
self.dataXml = [NSMutableData data];
}
self.urlConnection = nil;
[mutableRequest release];
[pool release];
}

One solution to see what is wrong:
make a new project, using ASIHttpRequest
Get a web debugging proxy like Charles
Turn on Charles (or whatever), do a multi-file upload that succeeds.
Record data from HTTP traffic to server.
Now run your own code. Record that traffic. What is different from
your traffic to the working traffic? Makes yours IDENTICAL in all
respects, and how can it not work?
You can also replace step (1) with a curl command line that uploads multiple files to a server and record that traffic, but I'm not versed enough in curl to say off the top of my head what that command would look like.

- (NSString*) nameValString: (NSDictionary*) dict {//example CHLOVA_FORM_BOUNDARY is #"aaa"
NSArray* keys = [dict allKeys];
NSString* result = [NSString string];
int i;
for (i = 0; i < [keys count]; i++) {
result = [result stringByAppendingString:
[#"--" stringByAppendingString:
[CHLOVA_FORM_BOUNDARY stringByAppendingString:
[#"\r\nContent-Disposition: form-data; name=\"" stringByAppendingString:
[[keys objectAtIndex: i] stringByAppendingString:
[#"\"\r\n\r\n" stringByAppendingString:
[[dict valueForKey: [keys objectAtIndex: i]] stringByAppendingString: #"\r\n"]]]]]]];
}
return result;
}
- (void)sendPhoto{
NSString *param = [self nameValString:dic];//dic is post info like {lat=36;lng=120;}
NSString *footer = [NSString stringWithFormat:#"\r\n--%#--\r\n", CHLOVA_FORM_BOUNDARY];
param = [param stringByAppendingString:[NSString stringWithFormat:#"--%#\r\n", CHLOVA_FORM_BOUNDARY]];
param = [param stringByAppendingString:#"Content-Disposition: form-data; name=\"pic\";filename=\"image.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n"];
NSData *jpeg = UIImageJPEGRepresentation([UIImage imageWithContentsOfFile:_path], 0.55);
//NSLog(#"jpeg size: %d", [jpeg length]);
NSMutableData *data = [NSMutableData data];
//img one
[data appendData:[param dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:jpeg];
[data appendData:[footer dataUsingEncoding:NSUTF8StringEncoding]];
//img two
[data appendData:[param2 dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:jpeg2];
[data appendData:[footer2 dataUsingEncoding:NSUTF8StringEncoding]];
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#", CHLOVA_FORM_BOUNDARY];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPShouldHandleCookies:NO];
[request setHTTPMethod:#"POST"];
[request setValue:contentType forHTTPHeaderField:#"Content-Type"];
[request setValue:[NSString stringWithFormat:#"%d", [data length]] forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:data];
//then do sending
}

Related

Objective c uploading multiple files to server

In my app i need to upload a audio file and xml file to server. I successfully post audio file. But i don’t know how to send two files in parallel. Anyone please help me.
NSString *soundFilePath = [[self GetDocumentDirectory]
stringByAppendingPathComponent:audioDet.audioName];
NSMutableData *file1Data = [[NSMutableData alloc] initWithContentsOfFile:soundFilePath];
//uploads/
NSString *urlString = #"http://192.168.1.99/projects/fileUpload/upload.php";
NSString *filename = audioDet.audioName;
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"];
[request setValue:#"Crystal" forHTTPHeaderField:#"ClientApp"];
[request setValue:#"1.0" forHTTPHeaderField:#"ClientVersion"];
[request setValue:#"617272656E64616C65445652" forHTTPHeaderField:#"ClientCredential"];
[request setValue:audioDet.audioName forHTTPHeaderField:#"Target-file-name"];
[request setValue:[NSString stringWithFormat:#"%#",audioDet.audioFileSize] forHTTPHeaderField:#"Target-file-length"];
NSMutableData *postbody = [NSMutableData data];
[postbody appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// NSString * value1 = [NSString stringWithFormat:#"Content-Disposition: form-data; name=\"userfile\"; name=\"%#\"\r\n", filename];
[postbody appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"userfile\"; filename=\"%#\"\r\n", filename ] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[#"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[NSData dataWithData:file1Data]];
[postbody appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:postbody];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
Thanks,
AKS
Store the multiple files in an array and iterate the same using for loop to send multiple files in the server.

Xcode Upload File (Image) to FTP site

i want to upload a file, an image, to a website. I have read the SimpleFTPSample from Apple. It´s work with the TestPhotos but it´s too complicated. Can someone post a simple Code, where i can put my URL in it? I have used BlackRaccoon and ASIHTTPRequest but it doesn´t work.
Thanks
What worked easiest for me was to write a small php script and upload the file to that. The php isn't that sophisticated but it works
be sure to replace the urls with your site name
upload.php
<?php
$uploaddir = 'Images/';
$file = basename($_FILES['userfile']['name']);
$uploadfile = $uploaddir . $file;
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
echo "transfer successful at: http://YOURWEBSITE.COM/{$uploaddir}/{$file}";
}
?>
obj-c
NSString *imageString = [NSString stringWithFormat:#"Content-Disposition: form-data; name=\"userfile\"; filename=\"%#\"\r\n", YOURIMAGE];
NSData *imageData = UIImageJPEGRepresentation(newimageGlobal, 0.4);
NSString *urlString = #"http://YOURWEBSITE.COM/upload.php";
NSLog(#"upload url%#", urlString);
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
NSString *boundary = [NSString stringWithString:#"-------------------------- -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 stringWithString:imageString ] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithString:#"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];

Objective C post variables as well as files

I am attempting to write a method/function in objective c to post data to an online php script. All is going well, Its successfully uploads as many files as I provide it with but I cannot figure out to send variables along with these files. I've spent hours now looking through this site and I am unable to find an example that posts files as well as variables.
NSURL * postURL = [NSURL URLWithString:serverURL];
NSString * contentBoundary = #"-14737809831466499882746641449";
NSString * contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#", contentBoundary];
// Build Request
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:postURL];
[urlRequest setHTTPMethod:#"POST"];
[urlRequest addValue:contentType forHTTPHeaderField: #"Content-Type"];
NSMutableData * postBody = [NSMutableData data];
NSMutableString * postString = [NSMutableString stringWithFormat:#""];
for(NSString * key in dataArray) [postString appendString:[NSString stringWithFormat:#"%#=%#&", key, [dataArray objectForKey:key]]];
[postString deleteCharactersInRange:NSMakeRange([postString length] -1, 1)]; // Trim trailing ampersand from string
NSData * postData = [postString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:NO];
[postBody appendData:[NSData dataWithData:postData]];
if(attachments != nil){
for(NSString * filePath in attachments){
NSString * fileName = [filePath lastPathComponent];
NSData * attachedFile = [NSData dataWithContentsOfFile:filePath];
[postBody appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n", contentBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat:#"Content-Disposition:form-data;name=\"userfile[]\"; filename=\"%#\"\r\n", fileName] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[[NSString stringWithFormat:#"Content-Type:application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[postBody appendData:[NSData dataWithData:attachedFile]];
[postBody appendData:[[NSString stringWithFormat:#"\r\n--%#--\r\n", contentBoundary] dataUsingEncoding:NSUTF8StringEncoding]];
}
}
NSString * postLength = [NSString stringWithFormat:#"%d", [postBody length]];
[urlRequest setValue:postLength forHTTPHeaderField:#"Content-Length"];
[urlRequest setHTTPBody:postBody];
Any help would be appreciated.
You can try appending the variable's values to the posted data in the following manner :
// text parameter
[postbody appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"applicationId\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
NSString *parameterValue1=[dict objectForKey:#"applicationId"];
[postbody appendData:[parameterValue1 dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[#"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
Hope that works for you. Above code is just an example of the parameter sent with the file upload.

Printing to Google Cloud Print using iOS

I have been trying to print a PDF file to Google cloud print using the following code. Instead of actually printing the document, it is only printing a string that shows the location of the file as well as the file name. I would like to have it print the actual document.
We can assume that the data being passed into this method is valid as it seems to be finding the correct printer from calls to cloud prints /search
Update: The code is updated from its original format to include some multi-part form data
NSString *currentPDFFileName = [[NSBundle mainBundle] pathForResource:#"TestPDF" ofType:#"pdf"];
NSData *pdfData = [NSData dataWithContentsOfFile:currentPDFFileName];
NSData *validPDF = [[NSString stringWithString:#"%PDF"] dataUsingEncoding: NSASCIIStringEncoding];
if (!(pdfData && [[pdfData subdataWithRange:NSMakeRange(0, 4)] isEqualToData:validPDF]))
{
NSLog (#"Not valid");
}
NSLog (#"%#", currentPDFFileName);
NSLog (#"%#", [currentPDFFileName lastPathComponent]);
//create the body
NSMutableData *body = [NSMutableData data];
//create the POST vars
NSString *thePrinter = [NSString stringWithFormat:#"Content-Disposition: form-data; name=\"printerid\"\r\n\r\n%#", printerID];
NSString *pdf = [NSString stringWithFormat:#"Content-Disposition: form-data; name=\"content\"; filename=\"%#\"\r\n", [currentPDFFileName lastPathComponent]];
NSString *theContent = [NSString stringWithFormat:#"Content-Disposition: form-data; name=\"contentType\"\r\n\r\n%#", contentType];
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", #"----foo"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[thePrinter dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n", #"----foo"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[pdf dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n", #"----foo"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[theContent dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n", #"----foo"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Type: application/pdf\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:pdfData];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n", #"----foo"] dataUsingEncoding:NSUTF8StringEncoding]];
NSMutableURLRequest *pdfRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"https://www.google.com/cloudprint/submit"]];
[pdfRequest setValue:#"multipart/form-data; boundary=----foo" forHTTPHeaderField:#"Content-type"];
[pdfRequest setHTTPMethod:#"POST"];
[pdfRequest setHTTPBody:body];
[self.authenticate authorizeRequest:pdfRequest completionHandler:^(NSError *error) {
NSString *output = nil;
if(error) {
output = [error description];
} else {
NSURLResponse *response = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:pdfRequest
returningResponse:&response
error:&error];
if(data) {
output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
} else {
output = [error description];
}
}
NSLog(#"%#", output);
}];

UIIMagePickerController & NSURLConnection

UIImagePickerController freezes while I think the Image is being compressed or being sent by NSURLConnection although I'm not convinced it's the later.
What I want is, all this to be done in the background. Instead when I pick a photo from the library, the Screen freezes for what feels like forever. This isn't optimal, obviously. What approach should I take here?
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo
{
int i = 0;
NSString *uniquePath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/selectedImage.png"];
while ([[NSFileManager defaultManager] fileExistsAtPath:uniquePath])
{
uniquePath = [NSString stringWithFormat:#"%#/%#-%d.%#", [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"], #"selectedImage", ++i, #"png"];
}
NSLog(#"Writing selected Image to Documents Folder, %#", uniquePath);
dataForPNGFile = UIImagePNGRepresentation(img);
if (!dataForPNGFile) return NO;
[UIImagePNGRepresentation(img) writeToFile:uniquePath atomically:YES];
UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil);
[[self parentViewController] dismissModalViewControllerAnimated:YES];
[picker release];
NSString *urlString = #"http://localhost:3000/photos";
NSURL *url = [NSURL URLWithString:urlString];
NSString *boundary = #"----1010101010";
NSString *contentType = [NSString stringWithFormat:#"multipart/form-data; boundary=%#",boundary];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
NSString *photoPath = [[NSBundle mainBundle] pathForResource:#" my-photo " ofType:#"jpg"];
NSData *photoData = [NSData dataWithContentsOfFile:photoPath];
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:#"--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Disposition: form-data; name=\"photo-description\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"testing 123" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// [body appendData:[[NSString stringWithFormat:#"Content-Disposition: form-data; name=\"photo-file\"; filename=\"%#\"\r\n", " my-photo.jpg"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:photoData];
[body appendData:[[NSString stringWithFormat:#"\r\n--%#\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"Content-Disposition: form-data; name=\"tags\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[#"random,test,example" 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 alloc] initWithRequest:request delegate:self];
}
You should use:
detachNewThreadSelector:toTarget:withObject:
Detaches a new thread and uses the specified selector as the thread entry point.
+ (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument
Documentation here: NSThread
This will create a new thread for the operation that is eating up the cpu, so your UI isn't affected remember to create a NSAutoreleasePool for the new thread, as only the main thread gets a NSAutoreleasePool pool by default.
So at the beginning of your selector do:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//and at the end:
[pool drain]: