How to send 100 MB videos over URLSession

This function will send small videos only. How do I change this to send 100 MB videos? The server limits are set to 200 MB. When uploading the video I send the file path for the video to a SQL Db and the video with a unique id to the file manager. If the video is less then 5MB it returns the massage added successfully and if the video is over 5MB there's no video in the file manager. I have tried to get this but I can't work it out.

From what I understand Swift/NSURLSession will not load large amounts into memory.

Can someone show my how to convert this to work.


   func uploadVideo2 (){


        //Bool to control Post Activity Indicator.isHidden
        DispatchQueue.main.async(execute: {
        self.videoOnOff = "on"
        self.postActivityIndicatorIsHidden()
        })
    
        //Here we get the card's UUID to be used with the param
        let unquieID  =  theDictionary.value(forKey: "unquieID") as! String
    
        // param to be sent in body. This will be used in the $_request variable in the DBVideo.php
        let param = ["videoUnquieID" : unquieID] //This is the card's UUID
    
        // url path to php file
        let url = URL(string: "http://***.xxxxxxxxx.com/***/DBVideo.php")!
    
        // Adding the url to the request variable
        var request = URLRequest(url: url)
    
        // Declare POST method
        request.httpMethod = "POST"
    
        // Assign video to videoData variable
        let videoData = theDictionary.value(forKey: "theVideo") as! Data
    
        // Creat a UUID for the boundary as a string
        let boundary = "Boundary-\(UUID().uuidString)"
    
        //Set the request value to multipart/form-data     the boundary is the UUID string
        request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
    

        request.httpBody = createBodyWithParamsVideo(param, //This is the card's UUID
                                                     filePathKey: "file", //The path to the variable $_FILES in the DBVideo.php
                                                     imageDataKey: videoData as Data, //The video's data from the card
                                                     boundary: boundary) // A unquie ID setup just for the baundary
    
        // launch session
       URLSession.shared.dataTask(with: request) { data, response, error in
        
            if response != nil {
            }
        
            // get main queue to communicate back to user
            DispatchQueue.main.async(execute: {
                if error == nil {
                    do {
                        // json containes $returnArray from php  //converting resonse to NSDictionary
                        let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary
                    
                        DispatchQueue.main.async(execute: {
                        self.videoOnOff = "off" //Controls for the Activity indicator
                        self.postActivityIndicatorIsHidden() //Activity indicator
                        })

                    
                        // declare new parseJSON to store json
                        guard let parseJSON = json else {
                            print("Error while parsing")
                        
                            DispatchQueue.main.async(execute: {
                            self.contactImageOnOff = "off" //Controls for the Activity indicator
                            self.postActivityIndicatorIsHidden() //Activity indicator
                            })
                            return
                        }
                    
                        var msg : String!
                    
                        //getting the json response
                        msg = parseJSON["message"] as! String?
                    
                        //printing the response
                        print(msg)

                    
                        // error while jsoning
                    } catch {
                         let message = error
                        print(message)
                     }
                
                    // error with php
                } else {
                    //no nothing
                }
            })
            }.resume()
    }


Here is the PHP


<?php





//STEP 1. Check to see if data was passed to this php file
if (empty($_REQUEST['videoUnquieID'])) {
    $returnArray["massage"] = "Missing required information";
    return;
}


// Pass POST via htmlencryot and assign to $id
$id = htmlentities($_REQUEST['videoUnquieID']);


//STEP 2. Createing the $folder variable to hold the path where the video will be placed
$folder = "VBCVideo/";


//STEP 3. Move uploaded file
$folder = $folder . basename($_FILES["file"]["name"]);

if (move_uploaded_file($_FILES["file"]["tmp_name"], $folder)) {
    $returnArray["status"]="200";
    $returnArray["message"]="The Video file has been uploaded";
} else {
    $returnArray["status"]="300";
    $returnArray["message"]="Error while uploading the Video";
}



//STEP 4. Build connection
//Constructor to create connection
    function __construct()
    {
        require_once dirname(__FILE__) . '/Config.php';
        require_once dirname(__FILE__) . '/DbConnect.php';
        // opening db connection
        $db = new DbConnect();
        $this->connect = $db->connect();
    }



// STEP 5. Feedback array to app user
echo json_encode($returnArray);

?>


The php.ini

max_execution_time = 500000;
upload_max filesize = 200000M;
post_max_size = 400000M;
memory_limit = 200000m;

Replies

There’s three issues here:

  • Uploading large resources — 100 MB is too big to hold in memory. You’ll need to upload from a file. You can do that using a

    URLSessionUploadTask
    , creating it with
    uploadTask(with:fromFile:)
    .
  • Background session — Ultimately you’ll want to move this to a background session, so that the upload can continue if the user moves your app to the background. I recommend that you skip that for the moment because background sessions introduce their own complexities and you should focus on getting the upload to just work.

    Note You can find a bunch of background session hints in the pinned posts on the right of the Core OS > Networking topic page.

  • PHP - Your PHP code requires that the upload comes in via a

    multipart/form-data
    body. This is fine for small uploads but is a pain for large ones because you need to add a prefix and suffix to the file data, and file system APIs don’t let you insert data at the front of the file. You should restructure your PHP code to accept the upload as the request body (passing ancillary information, if any, via custom headers). I don’t know PHP enough to advise you on how to do that.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"