Reputation: 234
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
Reputation: 349
Are you using conditionalyBeginAccessingResources
method before beginAccessingResources
?
Check this nice ODR ios tutorial from Ray, and this book from Vandad (it contains a section for propper ODR fetching).
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)
})
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?
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