iosnsurlsessionnsurlsessionuploadtask

IOS NSURLSession Background Uploading how to upload Large Files in Background?


I want to Upload the Large Files (Videos) of 2-3 GB to Server in background with the following requirements

First Method

  1. Uploading should resume if the internet Connection lost and reconnected

  2. Uploading should continue even application is in background

  3. Uploading should resume if user kills the application and comes back

for the Above features what I have implemented

  1. User select the File

  2. Split the File into Chunks Of 1MB and save all the Chunks on the Disk as File

  3. Create the Upload Task Against Each Chunk File and add the File in Background Session

Above Method works but fails in Some Case

  1. If the File Is Larger than 1GB Creating Chunks and Writing Chunks on Disk throw Memory Exception

  2. If I want to Upload the File of 1GB I need extra 1 GB Space to Create Chunks

Second Method

Upload the Original File without creating chunks, in this case, I am not able to resume uploading if network connectivity lost or User Kill the application

My question is What is the best way to upload the Large files in Background Keeping all these points in Mind

I know there are some questions of this type already asked but none of them answer my question

I have spent lot of time Implementing this but can not implement it successfully please help me or give some suggestion what is the best way to complete the above points

Update

I am Using the Following Code to Create Chunks Code is in Xamarin.IOS but i am Ok if some one Provide explantion in Objective C or Swift

public static void SplitFileInChunks( UploadFileInfo UploadFile )
{
        int i = -1;

        long chunkSize = UploadHelper.chunkSize;
        nuint dataLength = (System.nuint)chunkSize; 

        //var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
        string directoryPath = UploadHelper.UploadsDirectory;

        int chunkCount = 0;
        NSFileHandle fileHandleRead = NSFileHandle.OpenRead(UploadFile.FilePath);

        fileHandleRead.ReadInBackground();
        //fileHandleRead.WaitForDataInBackground();

        if (fileHandleRead == null)
            return;

        do
        {
            i++;
            ulong index = (ulong)(i * chunkSize);

            var filePath = Path.Combine(directoryPath, UploadFile.ContentGuide + "" + i.ToString());
            //fileHandleRead.SeekToFileOffset(index);

            NSData data = fileHandleRead.ReadDataOfLength(dataLength );
            Console.WriteLine(UploadFile.FileStatus);

            if (data.Length <= 0)
                continue;

            NSFileManager.DefaultManager.CreateFile(filePath, data, attr: null);


            NSError error;
            //data.Save(filePath, true, out error);

            chunkCount++;

            Console.WriteLine("Data Lenght" + data.Length);
            data.Dispose();
            Console.WriteLine("Chunk " + i);
        }

        while ( i * chunkSize <= UploadFile.Size && UploadFile.FileStatus != UploadFileStatus.Aborted );

        fileHandleRead.CloseFile();
        fileHandleRead.Dispose();

        Console.WriteLine("All Files Written sucessuflly");
        UploadFile.TotalChunksCount = chunkCount;

    }

Solution

  • That will certainly work, but if you're in control over the software on the other end, you can do better:

    This architecture also makes it possible to show a status bar fairly easily.