Search Unity

How to use NSURLSession to download and save a file

Discussion in 'iOS and tvOS' started by 265lutab, Aug 15, 2017.

  1. 265lutab

    265lutab

    Joined:
    Sep 15, 2014
    Posts:
    155
    I'm creating an app that needs to download and save a large file (over 600MB). For android I'll be using WebClient.DownloadFileAsync, but I have read that it is recomended to use NSURLSession for iOS. I do want the file to continue downloading in the background if possible, but it isn't required. I also need to be able to read the download progress of the file. Does anyone know how to do this in unity? Thanks.
     
  2. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,735
    With Unity 2017.2 (currently beta) you can use UnityWebRequest with DownloadHandlerFile for that.
    In older versions of Unity you can use WWWConnection.mm file in generated XCode project either as example or you can hack it to do what you want. Note that this file is used as backend for WWW/UnityWebRequest classes and those may also be used by some plugins, Unity services etc., so be careful when modifying it :) If you hack it to use specific code path for certain URL, you could use UnityWebRequest to kick-off the download and you feed the proper data back, you could monitor the progress from UWR too, just don't give it the actual data, fool it to think it's downloading something small at a very low rate just for downloadProgress to report something very close to actual progress.
     
  3. tswalk

    tswalk

    Joined:
    Jul 27, 2013
    Posts:
    1,109
    I use webclient.downloadfileasync on ios and have no issues... when you say 'in the background' do you mean, when the app is swapped to the background to run a different app? reason to ask is that webclient will run on a different thread without a problem and has progress capability.
     
  4. 265lutab

    265lutab

    Joined:
    Sep 15, 2014
    Posts:
    155
    Thanks. Running while the application is paused is mainly important for GearVR since it pauses if you take the headset off. On iOS it doesn't really need to be able to do that. Though might be nice if it could download while the application is in the background and the user is in another app. It's not necessary. I'll use WebClient for now.
     
  5. tswalk

    tswalk

    Joined:
    Jul 27, 2013
    Posts:
    1,109
    Just a word of advice from my experience, make sure to put in something to cancel webclient downloads (or something similar) incase the user decides to suspend your app. I haven't checked to see if the background thread used by webclient gets suspended or not, but I had a case where a user did so for some other apps and the unity app got killed.. corrupting the download.

    Code (CSharp):
    1.        
    2.  
    3. //ONAPPPAUSED
    4.        //where client is the instance of webclient used to begin fileasyncdownload
    5.         void OnApplicationPause(bool pauseStatus)
    6.         {
    7.             if (pauseStatus)
    8.             {
    9.                 client.CancelAsync();
    10.             }
    11.         }
    12.  
    13.  
     
  6. 265lutab

    265lutab

    Joined:
    Sep 15, 2014
    Posts:
    155
    I also want to include a cancel download button for the user if they want to stop it. I'm guessing I would call client.cancelAsync(); for that too. Will doing that remove the partially downloaded file or do I need to delete the file after canceling? I'm currently downloading to the PersistantDataPath.
    Thanks.
     
    Last edited: Aug 17, 2017
  7. 265lutab

    265lutab

    Joined:
    Sep 15, 2014
    Posts:
    155
    Also what is the (bool pauseStatus) for? Is that different than just using:

    Code (CSharp):
    1. void OnApplicationPause(){
    2. client.CancelAsync();
    3. }