-1

I use URLForResource to find on-demand resources after downloading them and it currently works correctly.

Due to some issues with Apple not being able to download the ODR during their review, I now have to temporarily embed my On-Demand Resources AssetPacks in the App Bundle changing in XCode "Embed Asset Packs In Product Bundle" from false to true.

The problem is that after doing that when I use the same URLForResource method it now returns null.

NSURL *myDirectoryURL = [[NSBundle mainBundle] URLForResource:targetFolder withExtension:@""];

Since they become part of the product bundle am I not supposed to be able to find them in that way?


UPDATE: Some (ugly) working code from a non-iOS dev working on a Cordova plugin.. :)

    NSLog(@"[odr] calling nsbrr conditionallyBeginAccessingResourcesWithCompletionHandler..");
    @try
    {
      [odrRequest conditionallyBeginAccessingResourcesWithCompletionHandler:^(BOOL resourcesAvailable) {
        if (resourcesAvailable) {
          NSLog(@"[odr] already available (in-bundle) / downloaded.");
          @try
          {
            NSURL *myDirectoryURL = [[NSBundle mainBundle] URLForResource:targetFolder withExtension:@""];
            NSLog(@"[odr] Target directory URL: '%@'", myDirectoryURL);
            NSString *res = myDirectoryURL.absoluteString;
            pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:res];
            NSLog(@"[odr] path found, returning it in callback: '%@'", res);
            [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
          }
          @catch(id anException) {
            NSString *errMsg = @"Error in path detection or calling callback (in already-downl-odr handler): ";
            errMsg = [errMsg stringByAppendingString:anException];
            NSLog(@"[odr] Exception: '%@'", errMsg);
            pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:errMsg];
            [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
          }
        } else {
          NSLog(@"[odr] Starting to load (in-bundle) / download..");
          @try
          {
            [odrRequest beginAccessingResourcesWithCompletionHandler:^(NSError * _Nullable error) {
              if (error == nil) {
                NSLog(@"[odr] File load / download success.");
                @try
                {
                  NSURL *myDirectoryURL = [[NSBundle mainBundle] URLForResource:targetFolder withExtension:@""];
                  NSLog(@"[odr] Target directory URL: '%@'", myDirectoryURL);
                  NSString *res = myDirectoryURL.absoluteString;
                  pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:res];
                  NSLog(@"[odr] path found, returning it in callback: '%@'", res);
                  [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
                }
                @catch(id anException) {
                // ...

Gabe
  • 5,997
  • 5
  • 46
  • 92
  • Unclear what the question is. On-demand resources are not stored in your app bundle (your app bundle is immutable), and it is unclear what "temporarily embed my OnDemandResources AssetPacks in the App Bundle" means. – matt Oct 05 '20 at 17:24
  • @matt edited, should be more clear now. Thanks – Gabe Oct 05 '20 at 17:32
  • What's the `targetFolder`? Why would embedding the asset packs cause there to be a folder that wasn't there before? – matt Oct 05 '20 at 17:38
  • Also, if this is an app review issue "Due to some issues with Apple not being able to download the ODR during their review", I would worry about what the issues are rather than trying to circumvent them temporarily during testing (like Volkswagen). – matt Oct 05 '20 at 17:40
  • Plus, what's your plan for when you unembed the asset packs? You're just going to have to thru review again. – matt Oct 05 '20 at 17:48
  • @matt `targetFolder` is a folder containing assets that will be on the file system only after the ODR download. If I embed the ODR it should be there straight away without a download from Apple server, correct? The issue with Apple is just that they are not able to download the ODR. It works fine in the Testflight build we submit them and in the live app so it's an issue on their side (read this too in another Apple thread). We just need them to see the ODR assets for the approval, then in the next version we can go back to downloading them as we do in the live app. Thx – Gabe Oct 05 '20 at 18:32
  • So the ODR asset is a folder? And you are doing the bundle request dance as usual? And then using `URLForResource` in the completion handler? – matt Oct 05 '20 at 20:34
  • It would really help if you would show some real code and not just a single line out of context. Accessing on-demand resource is an elaborate business, we need to see how you're doing it. You still have to "download" the resources even though they are already there, in order to access them. They don't magically stop being on-demand just because you included them in the bundle. – matt Oct 05 '20 at 21:05
  • @matt understood, this helped: "You still have to "download" the resources even though they are already there, in order to access them". I was trying to find them before calling `conditionallyBeginAccessingResourcesWithCompletionHandler` / `beginAccessingResourcesWithCompletionHandler`. Solved calling the latter before looking for the odr. – Gabe Oct 05 '20 at 22:10
  • I'll give it as an answer. – matt Oct 05 '20 at 22:20

1 Answers1

0

The fact that you are sidestepping the use of the server as a source of the ODR download by embedding the on-demand resources changes nothing about how you access them. You still have to have an NSBundleResourceRequest and call beginAccessingResourcesWithCompletionHandler: and access the resources in the completion handler, exactly as you would do if you hadn't turned on Embed Asset Packs In Product Bundle.

So your code should be unchanged, without regard to the value of Embed Asset Packs In Product Bundle. If the same code works when Embed Asset Packs In Product Bundle is NO but not when it is YES, your code was wrong to start with.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • How I solved was: 1. removed the URL of where the non-prod ODR were served from (ie. "Asset Pack Manifest URL Prefix"), 2. the resources tagged in my local build were just placeholders (before switching to in-bundle DOR I needed those to create the tags and download the ODR from my static server for non-prod apps). Thx – Gabe Oct 06 '20 at 07:26