Sumeet Bajaj
Sumeet Bajaj

Reputation: 234

Is archive files allowed on On-Demand Resource?

We have .zip file in app, tagged as on demand resource. On downloading it we get success in NSBundleResourceRequest completion handler, but unable to find path of downloaded file(.zip). It works fine for png and jpg file but fails for .zip files. Also .zip file download works fine in our testing devices and fails only on App Reviewer devices.

Any alternative for .zip in iOS will work on ODR?

Upvotes: 4

Views: 731

Answers (1)

Nikola Markovic
Nikola Markovic

Reputation: 349

Are you using conditionalyBeginAccessingResources method before beginAccessingResources ?

Resources:

Check this nice ODR ios tutorial from Ray, and this book from Vandad (it contains a section for propper ODR fetching).

From the Ray's tutorial:

class ODRManager {

  // MARK: - Properties
  static let shared = ODRManager()
  var currentRequest: NSBundleResourceRequest?

  // MARK: - Methods
  func requestFileWith(tag: String,
                        onSuccess: @escaping () -> Void,
                        onFailure: @escaping (NSError) -> Void) {

    currentRequest = NSBundleResourceRequest(tags: [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()
    }
  }
}
In use:
  ODRManager.shared.requestFileWith(tag: "<#Your tag#>", onSuccess: {
    // load it through Bundle
  }, onFailure: { (error) in
    let controller = UIAlertController(title: "Error", message: "There was a problem.", preferredStyle: .alert)

    switch error.code {
    case NSBundleOnDemandResourceOutOfSpaceError:
      controller.message = "You don't have enough space available to download this resource."
    case NSBundleOnDemandResourceExceededMaximumSizeError:
      controller.message = "The bundle resource was too big."
    case NSBundleOnDemandResourceInvalidTagError:
      controller.message = "The requested tag does not exist."
    default:
      controller.message = error.description
    }

    controller.addAction(UIAlertAction(title: "Dismiss", style: .default, handler: nil))
    guard let rootViewController = self.view?.window?.rootViewController else { return }

    rootViewController.present(controller, animated: true)
  })

From the book:

let tag = "<#tagString#>"
var currentResourcePack: NSBundleResourceRequest? = NSBundleResourceRequest(tags: [tag])
guard let req = currentResourcePack else { return }

req.conditionallyBeginAccessingResources { available in
  if available {
    self.displayImagesForResourceTag(tag)
  } else {
    // this usualy means that the resources are not downloaded so you need to download them first
    req.beginAccessingResources { error in
      guard error == nil else {
        <#/* TODO: you can handle the error here*/#>
        return
      }
      self.displayImagesForResourceTag(tag) 
    }
  }
}

func displayImagesForResourceTag(_ tag: String) {
  OperationQueue.main.addOperation {
    for n in 0..<self.imageViews.count {
      self.imageViews[n].image = UIImage(named: tag + "-\(n+1)")
    }
  }
}

So, maybe you can dig out the source of zip there?

Alternative way

Another solution is to download the zip, extract it and start using resources from the extract sandbox destination folder by using the FileManager, and use Bundle only when ODR are not or can't be downloaded.

GL

Upvotes: 1

Related Questions