Uploading file using NSURLSessionUploadTask to server

Discussion in 'iOS Programming' started by blueeye, Sep 30, 2014.

  1. blueeye macrumors member

    blueeye

    Joined:
    Oct 27, 2007
    #1
    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?
     
  2. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
  3. blueeye thread starter macrumors member

    blueeye

    Joined:
    Oct 27, 2007
    #3
    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).
     
  4. mjohnson1212 macrumors member

    Joined:
    Nov 15, 2007
    #4
    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.
     
  5. ernestc, Feb 1, 2015
    Last edited: Feb 1, 2015

    ernestc macrumors newbie

    Joined:
    Apr 16, 2006
    Location:
    Wellington, New Zealand
    #5
    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
    	}
    ?>
     
  6. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #6
    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.
     

Share This Page