Search code examples
swift4ios11xcode9on-demand-resources

iOS is purging On-Demand resources downloaded mp3, how to prevent this?


iOS will purge assets after being downloaded as soon as it needs to free up some space.

Changing the preservation priorities of the assets will not prevent the system from purging them as stated in the "Setting Preservation Priority" section here.

My relevant code to download the On-demand resources is the following:

func requestResourceWith(tag: [String],
                      onSuccess: @escaping () -> Void,
                      onFailure: @escaping (NSError) -> Void) {
    currentRequest = NSBundleResourceRequest(tags: Set(tag))

    guard let request = currentRequest else { return }

    request.endAccessingResources()

    request.loadingPriority =
    NSBundleResourceRequestLoadingPriorityUrgent

    request.beginAccessingResources { (error: Error?) in
        if let error = error {
            onFailure(error as NSError)
            return
        }
        onSuccess()
    }
}

After downloading the On-Demand resources, they can be accessed from the main bundle.

Is there anyway to make audios persist, and hence prevent the system from purging them?


Solution

  • In response to @RJB comment above, I will answer my question :)

    As soon as the On-demand resources are downloaded, you need to save them in hard disk (The documents directory for example) in order to persist them. Otherwise, iOS will retain the right to purge them as soon as it needs more free space.

    Something like the following:

    request.beginAccessingResources { (error: Error?) in
         if let error = error {
               DispatchQueue.main.async {
                     onFailure(error as NSError)
               }
               return
         }
         // Move ODR downloaded assets to Documents folder for persistence
         DispatchQueue.main.async {
               let path: String! = Bundle.main.path(forResource: "filename", ofType: "mp3")
               let sourceURL = URL(fileURLWithPath: path)
               let destinationURL = // Build a destination url in the Documents directory or any other persistent Directory of your choice
               do {
                  try FileManager.default.copyItem(at: sourceURL, to: destinationURL)
               }catch  {
                  // Handle error accordingly
               }
               onSuccess()
         }
    }