5

I am currently trying to implement Apple's API for On Demand Resource Management for AWS Cloudfront because Apple's ODR is somehow too unreliable.

I noticed that when I tag images inside of Assets.scnassets/ with an ODR resource tag, I can access that image using

UIImage(name: resourceName)

once it has been downloaded by a NSBundleRequest object. Because I can access the downloaded resource as a UIImage, I know that the resource is located in the app's main bundle but I thought this was impossible because Bundles were read-only. How did apple do this? The most important aspect is being able to create UIImages using this incredibly simple interface.

4

2 回答 2

3

I know that the resource is located in the app's main bundle but I thought this was impossible because Bundles were read-only. How did apple do this?

It’s an illusion. ODR files are downloaded to a directory outside the app bundle, and calls like UIImage init(named:) are swizzled to look in that directory.

于 2019-11-18T23:48:30.673 回答
1

Not sure how it is done technically, but I am pretty certain that attributing ODR to a particular bundle (typically main) is done on purpose, so you can rely on it.

I am using RxOnDemandResources library to fetch hundreds of MP3 from dozens of tags, and it is done on a per bundle basis -

Bundle
    .main
    .rx
    .demandResources(withTags: tags) // tags: Set<String>
    .subscribeOn(Scheduler.concurrentUser) // declare your scheduler first
    .observeOn(Scheduler.concurrentMain) // declare your scheduler first
    .subscribe { event in
        switch event {
        case .next(let progress):
            self.showProgress(progress: Float(progress.fractionCompleted)) // declare your handler first
        case .error(let error):
            break // handle appropriately
        case .completed:
            if let url = Bundle.main.url(forResource: file, withExtension: "") {
                os_log("url: %@", log: Log.odr, type: .info, "\(url)")
                // TODO use your resource
            }
        }
    }
    .disposed(by: self.disposeBag)

Back to your question: yes you can access ODR resources via specific bundle as usual but with all preconditions (checking availability, fetching if needed) - i.e. not always.

于 2018-10-17T15:16:22.437 回答