We’re trying to configure an iOS game for app Slicing using Addressables, but we’re encountering an issue loading the bundles. We’ve found a workaround, but it’s cumbersome, and I’m wondering if there’s a better way to set things up.
The issue that we’re having is that when an asset bundle is requested the “res://” URL is interpreted as a remote http request which fails since the URL is intended to reference an iOS Asset Catalog. We need the “res://” URL to be resolved against the asset catalog, not using an NSURLSession.
While our use case has to do with Slicing, our investigation indicates that a similar issue would happen with ODR.
Our Setup
We’re using Addressables V 1.19.18 (but can also reproduce this with V 1.19.15) and Unity 2021.2.8f1. I have an Addressables profile that sets LocalBuildPath to a location in our Asset database, and LocalLoadPath = “res://”. This prevents the normal installation of the AssetBundles into the Data folder of our Xcode project (which is what we want). Our groups were originally configured to use AssetBundleProvider (the default) but our workaround has required us to change that.
To create an Asset Catalog I assign a callback to UnityEditor.iOS.BuildPipeline.collectResources that generates Resource instances for all of the bundles saved in the previous step.
The Issue
All of the above works, but when we run the project we get a lot of NSURLRequest errors and none of the bundles are able to load. Digging into this a bit we discovered that ResourceManagerConfig.ShouldPathUseWebRequest() returns true for “res://” requests because they contain “://”. If AssetBundleProvider is expected to work with Asset Catalogs, then ShouldPathUseWebRequest() should check to see if the platform is iOS, and if it is return false for requests that start with “res://”.
Workaround
Our workaround is a bit more complicated, since ResourceManagerConfig.ShouldPathUseWebRequest() is static and difficult to patch. We implemented our own ResourceProvider that is essentially just a copy of AssetBundleProvider, with the following check in GetLoadInfo():
if (path.StartsWith("res://"))
loadType = LoadType.Local;
This works, and the bundles load properly, but it’s a hack and requires a lot of duplicate code. For deployment we’re considering cloning the Addressables package and just fixing ResourceManagerConfig. But if we could avoid all of this using an existing ResourceProvider or a different configuration it would be cleaner.