Uploading file using NSURLSessionUploadTask to server

blueeye

macrumors member
Original poster
Oct 27, 2007
80
0
I have a video upload system in an iOS app using NSURLSessionUploadTask. The video file is saved to an NSURL so I am using the following code in my upload method:
Code:
request.HTTPMethod = @"POST";
[request addValue:@"file" forHTTPHeaderField:@"fileName"];

// Create upload task
NSURLSessionUploadTask *task = [session uploadTaskWithRequest:request fromFile:filePath completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    if(!error) {
        // handle success
    } else {
        // handle error
    }
}];

// Run the task
[task resume];
I have a PHP server (using Laravel) running under nginx to handle this upload. I have tested it with Postman, and it accepts uploads fine (expecting a file under the name "file").

When I run the above objc code, the server tells me that no file has been uploaded (the $_FILES array is empty).

I have tried with and without setting the "fileName" header, and I've tried setting "Content-Type" to "multipart/form-data" but none of these works.

How can I get NSURLSessionUploadTask to properly upload these files (from an NSURL) to the server?
 

blueeye

macrumors member
Original poster
Oct 27, 2007
80
0
It's not so much that there is an explicit error thrown, but that when my code checks for the presence of an uploaded file (by examining the $_FILES array in PHP), the server doesn't see that a file has been uploaded.

As mentioned, this has been tested with Postman (REST client) and file upload works perfectly well in normal circumstances, it's just that when performed by NSURLSessionUploadTask, the server doesn't recognise that a file has been uploaded (thus I imagine it's a problem on the iOS side).
 

mjohnson1212

macrumors member
Nov 15, 2007
92
11
I ran into this a while ago and php doesn't like way NSURLSession does the upload. I believe it was because it's multi-part even though your only sending one file.

I used Fiddler to sniff what was going on between the upload that worked and the NSURLSession upload that didn't.

I believe I ended up using an NSURLConnection via AFNetworking at the time for the upload which worked.
 

ernestc

macrumors newbie
Apr 16, 2006
26
0
Wellington, New Zealand
Old thread, but I stumbled across this when I was searching for answers.

Anyway, I used Charles proxy to determine that the upload task sends the file in the request body (by itself).

So, in PHP, get the body of the request, do some sanity / security checks and save it to file.

Code:
<?php
	// File Path to save file
	$file = 'uploads/recording.m4v';
	
	// Get the Request body
	$request_body = @file_get_contents('php://input');
	
	// Get some information on the file
	$file_info = new finfo(FILEINFO_MIME);
	
	// Extract the mime type
	$mime_type = $file_info->buffer($request_body);

	// Logic to deal with the type returned
	switch($mime_type) 
	{
    		case "video/mp4; charset=binary":
        	
        		// Write the request body to file
			file_put_contents($file, $request_body);
			
			break;
			
		default:
			// Handle wrong file type here
	}
?>
 
Last edited:

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
I think that NSURLSessionUploadTask doesn't create multipart posts. It just submits the data that your code provides to it. If you want a multipart post you have to generate the data in your own code, or use AFNetworking like everyone else.

I don't know about the php side but probably it knows how to decode the multipart post.