I'm trying to upload a file to a server (from a custom mac os application) using ASIFormDataRequest. In my cocoa/obj-c code, I have:
- (IBAction)uploadFile:(id)sender
{
[networkQueue reset];
[networkQueue setShowAccurateProgress:YES];
[networkQueue setUploadProgressDelegate:progressIndicator];
[networkQueue setRequestDidFailSelector:@selector(postFailed:)];
[networkQueue setRequestDidFinishSelector:@selector(postFinished:)];
[networkQueue setDelegate:self];
ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:@"http://domain.com/to/upload.php"]] autorelease];
[request setFile:@"/path/to/file.jpg" forKey:@"file"];
[networkQueue addOperation:request];
[networkQueue go];
}
- (void)postFinished:(ASIHTTPRequest *)request
{
NSLog(@"Post Success");
}
- (void)postFailed:(ASIHTTPRequest *)request
{
NSLog(@"Post Failed");
}
The PHP code on the server looks like this:
$target_path = "files/";
$target_path = $target_path . basename( $_FILES['uploadedfile']['name']);
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
echo "The file ". basename( $_FILES['uploadedfile']['name']).
" has been uploaded";
} else{
echo "There was an error uploading the file, please try again!";
}
When I try to upload a file using this code, I get a "Post Success" response on the client end, but the file never shows up on my server. I have CHMODed the files folder to 777 just in case, but it still didn't seem to work. Does anyone have a suggestion, or see an error in the way I'm approaching this?
Thanks!
Update for future readers. The fundamental problem here was that you must create ASIFormDataRequest items exactly like this:
NSURL *url = [NSURL URLWithString:@"https://www.you.com/cgi-bin/you.cgi?stuff"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
Do not add in more release, retain, autorelease, self., etc etc! That's all it is.
Hmm. I'm not entirely sure the autorelease there is correct. You have to be careful about not losing resuest pointers in ASIHttpRequest.
Setting that aside, would it be worth trying it first as a simple (non-queued, asynchronous) request, using exactly this pattern which has been tested billions of times:
-(void) sendSomethingAnything
{
NSURL *url = [NSURL URLWithString:@"https://www.you.com/cgi-bin/you.cgi?stuff"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:@"fakeIDstring" forKey:@"id"];
[request setPostValue:@"anotherCalue" forKey:@"username"];
// your file here ..
[request setDelegate:self];
[request setDidFinishSelector:@selector(postFinished:)];
[request setDidFailSelector:@selector(postFailed:)];
[request startAsynchronous];
}
Just paste in your URL and you can try that immediately. That will eliminate a lot of problems and get us closer to the problem. In the done routine, get and show the result like this...
NSData *newStringData = [request responseData];
NSString *x = [[[NSString alloc] initWithData:newStringData
encoding:NSUTF8StringEncoding] autorelease];
NSLog(@"result text from server is %@", x);
Finally in your PHP. I find it useful to add a line of code that EMAILS ME from the php stating what the heck is going on. Alternately, use a "wall" command, and just have a shell open on your server as you work with the client. It's the only way to see what the heck is going on as you work.
(In fact I use old-fashioned perl rather than futuristic php, so I can't offer any code on that end! :) )
I did this and it works.Make sure to do this -> #import "ASIFormDataRequest.h"
NSURL *url = [NSURL
URLWithString:@"XXXXXX"];
ASIFormDataRequest *request = [ASIFormDataRequest
requestWithURL:url];
[request setPostValue:@"fakeIDstring" forKey:@"id"];
[request setPostValue:@"anotherCalue" forKey:@"username"];
// your file here ..
[request setFile:@"path/filename.png" forKey:@"uploadedfile"];
[request setDelegate:self];
[request setDidFinishSelector:@selector(requestDone:)];
[request setDidFailSelector:@selector(requestWentWrong:)];
[request startAsynchronous];
then in php code
$target_path = "files/";
$target_path = $target_path .
basename(
$_FILES['uploadedfile']['name']);
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'],
$target_path)) { echo "The file ".
basename(
$_FILES['uploadedfile']['name']).
" has been uploaded"; } else{ echo "There was an error uploading the
file, please try again!"; }
Note that you should have "files" folder beside you php file that handles this uploaded file.