Hello,
I am encountering the following error when uploading a build to App Store Connect:
ITMS-90555: Thinned app size is too large – Your on-demand resources in the universal variant are 30 GB, which exceeds the maximum allowable size. After app thinning, the total size of your on-demand resource asset packs in any variant must be less than 30 GB.
Our application includes a large amount of font resources delivered via ODR.
Before making structural changes, I need clarification because the documentation does not fully explain how ODR size calculations work per variant.
Environment
Xcode: (latest stable)
Distribution method: App Store submission
ODR total size before thinning: approximately (28 GB)
Build processing fails immediately with the ITMS-90555 error
Questions
How exactly does App Thinning compute the size of ODR asset packs per variant?
Is ODR size evaluated:
Per device-specific variant,
Or is the “universal variant” treated as an additional variant that must independently stay under 30GB?
The documentation mentions a 30GB limit per variant, but the universal variant error message is ambiguous.
If device-specific variants are below 30GB but only the “universal variant” exceeds it, is the build still rejected?
In our case:
iPhone-only variants appear to be below the limit,
But the universal variant exceeds 30GB due to aggregated resources.
Is this expected behavior?
Best practices for managing very large ODR sets (e.g., fonts)
Fonts are small individually, but thousands of them produce very large ODR groups.
Is there recommended guidance from Apple for:
Structuring ODR bundles to avoid the universal variant exceeding the limit
Segmenting ODR by device class / feature sets
Any alternative packaging strategies
Are there tools or logs that reveal how App Store Connect decides variant groupings and ODR size?
At the moment, the failure only shows the ITMS-90555 error without further detail.
Case-ID for DTS reference
DTS advised submitting this question here.
Case-ID: 17273913
Any clarification from Apple engineers or community members who have navigated ODR size limits would be greatly appreciated.
Thank you very much!
On demand resources
RSS for tagOn-demand resources are app contents that are hosted on the App Store and are separate from the related app bundle that you download.
Posts under On demand resources tag
7 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I read on this documentation :
https://developer.apple.com/help/app-store-connect/reference/app-uploads/on-demand-resources-size-limits
that On Demand Resources a legacy technology.
Does this mean ODR will be deprecated?
If so, when will it officially take effect?
Our application is planning to use it, so we need more information to support our decision.
After uploading the build to Test Flight, we are successfully able to download the ODR tags. Submitting that same build for an App Review, they are having issues. After further investigation, they are not able to resolve the hostname when trying to download the tag. This failure on the app is causing our app to be rejected.
It would be great to get some guidance on how best to resolve this situation for the App Review team.
Thanks!
I am integrating On Demand Resources into my Unity game. The resources install without any problems if the internet connection is stable: all resources are installed. While testing various scenarios without an internet connection, I encountered the following problem: if I turn off the internet during installation, I don't get any error messages, but if I turn the internet back on, the download no longer continues (and I still don't get an error). If I reopen the application with a stable internet connection, the download will always be at 0%. Please tell me what I am doing wrong.
#import "Foundation/Foundation.h"
#if ENABLE_IOS_ON_DEMAND_RESOURCES
#import "Foundation/NSBundle.h"
#endif
#include <string.h>
struct CustomOnDemandResourcesRequestData;
typedef void (*CustomOnDemandResourcesRequestCompleteHandler)(struct CustomOnDemandResourcesRequestData* handler, const char* error);
#if ENABLE_IOS_ON_DEMAND_RESOURCES
struct CustomOnDemandResourcesRequestData
{
NSBundleResourceRequest* request;
};
extern "C" CustomOnDemandResourcesRequestData* CustomOnDemandResourcesCreateRequest(const char* const* tags, int tagCount, CustomOnDemandResourcesRequestCompleteHandler handler)
{
NSMutableArray* tagArray = [NSMutableArray array];
for (int i = 0; i < tagCount; i++) {
const char* tag = tags[i];
if (tag != NULL) {
[tagArray addObject:[NSString stringWithUTF8String:tag]];
}
}
NSSet* tagSet = [NSSet setWithArray:tagArray];
CustomOnDemandResourcesRequestData* data = new CustomOnDemandResourcesRequestData();
data->request = [[NSBundleResourceRequest alloc] initWithTags:tagSet];
[data->request beginAccessingResourcesWithCompletionHandler:^(NSError* error) {
dispatch_async(dispatch_get_main_queue(), ^{
const char* errorMessage = error ? [[error localizedDescription] UTF8String] : NULL;
handler(data, errorMessage);
});
}];
return data;
}
extern "C" void CustomOnDemandResourcesRelease(CustomOnDemandResourcesRequestData* data)
{
[data->request endAccessingResources];
delete data;
}
extern "C" float CustomOnDemandResourcesGetProgress(CustomOnDemandResourcesRequestData* data)
{
return data->request.progress.fractionCompleted;
}
extern "C" float CustomOnDemandResourcesGetLoadingPriority(CustomOnDemandResourcesRequestData* data)
{
float priority = (float)data->request.loadingPriority;
return priority;
}
extern "C" void CustomOnDemandResourcesSetLoadingPriority(CustomOnDemandResourcesRequestData* data, float priority)
{
if (priority < 0.0f)
priority = 0.0f;
if (priority > 1.0f)
data->request.loadingPriority = NSBundleResourceRequestLoadingPriorityUrgent;
else
data->request.loadingPriority = (double)priority;
}
extern "C" const char* CustomOnDemandResourcesGetResourcePath(CustomOnDemandResourcesRequestData * data, const char* resource)
{
NSString* resourceStr = [NSString stringWithUTF8String: resource];
NSString* path = [[data->request bundle] pathForResource: resourceStr ofType: nil];
if (path == nil) {
return NULL; // или другое значение по умолчанию
}
const char* result = strdup([path UTF8String]); // копируем строку
return result; // в C# нужно будет освободить память
}
extern "C" void CustomOnDemandResourcesFreeString(const char* str) {
free((void*)str);
}
#else // ENABLE_IOS_ON_DEMAND_RESOURCES
struct CustomOnDemandResourcesRequestData
{
};
extern "C" CustomOnDemandResourcesRequestData* CustomOnDemandResourcesCreateRequest(const char* const* tags, int tagCount, CustomOnDemandResourcesRequestCompleteHandler handler)
{
CustomOnDemandResourcesRequestData* data = new CustomOnDemandResourcesRequestData();
if (handler)
handler(handlerData, NULL);
return data;
}
extern "C" void CustomOnDemandResourcesRelease(CustomOnDemandResourcesRequestData* data)
{
delete data;
}
extern "C" float CustomOnDemandResourcesGetProgress(CustomOnDemandResourcesRequestData* data)
{
return 0.0f;
}
extern "C" float CustomOnDemandResourcesGetLoadingPriority(CustomOnDemandResourcesRequestData* data)
{
return 0.0f;
}
extern "C" void CustomOnDemandResourcesSetLoadingPriority(CustomOnDemandResourcesRequestData* data, float priority)
{
}
extern "C" const char* CustomOnDemandResourcesGetResourcePath(CustomOnDemandResourcesRequestData * data, const char* resource)
{
return NULL;
}
extern "C" void CustomOnDemandResourcesFreeString(const char* str) {
}
#endif // ENABLE_IOS_ON_DEMAND_RESOURCES
I am working on an iOS app and I want to achieve on demand module download inside the app when the user clicks on the module icon which he wants to use.
The idea is that we have a super app consisting of multiple modules say four independent apps/features and I want to separate each one so that when the user selects a specific app/feature, it’s downloaded on demand and then opened directly within the same super app resulting in a lower app size initially
I want to upload all the code of all modules to app store connect but when the user downloads the app, then only one module's code should be available to the user, the rest of the module's code should be downloaded when the user wants to use that module. I know apple restricts downloading new code but in my case I want to upload all the code to app store for review but just give option to the user to get rest of the code when needed. Any guidance, architectural advice, or example implementations would be highly appreciated.
Topic:
Developer Tools & Services
SubTopic:
General
Tags:
App Clips
iOS
App Store Connect
On demand resources
I'm a newbie to on-demand resources and I feel like I'm missing something very obvious. I've successfully tagged and set up ODR in my Xcode project, but now I want to upload the assets to my own server so I can retrieve them from within the app, and I can't figure out how to export the files I need.
I'm following the ODR Guide and I'm stuck at Step #4, after I've selected my archive in the Archives window it says to "Click the Export button", but this is what I see:
As shown in the screenshot, there is no export button visible. I have tried different approaches, including distributing to appstore connect, and doing a local development release. The best I've been able to do is find a .assetpack folder inside the archive package through the finder, but uploading that, or the asset.car inside it, just gives me a "cannot parse response" error from the ODR loading code. I've verified I uploaded those to the correct URL.
Can anyone walk me through how to save out the file(s) I need, in a form I can just upload to my server?
Thanks,
Pete
I started using on-demand resources for some data assets. After that, the Swift Asset Symbol Extension feature began to fail in the Xcode editor. Even though the app builds and runs fine, the Xcode editor shows errors, indicating that there is no extension variable for my color and image assets.
I submitted feedback and updated it after each new Xcode release. However, I have not received any responses, and the problem persists.
The Xcode versions I tested: 15.3, 15.4, 16.1, 16.2, 16.3
Steps to reproduce this error:
Create a new app project (SwiftUI, Swift).
Create a new color asset named "myBackground."
In ContentView, add a background modifier to a view: .background(Color.myBackground). Auto-completion will work, and there are no issues.
Create a new data asset named "myData."
Add the "On Demand Resource" tag to "myData" with the tag "some_tag."
Create a new color asset named "myOtherBackground" and make its color different from "myBackground."
In ContentView, try to replace the background with Color.myOtherBackground. It will not be listed in auto-completion and will show the error "Type 'Color' has no member 'myOtherBackground.'"
However, it will still compile and show "myOtherBackground" in the preview, simulator, or on the device.
You will start to see the failed "Project Build Preparation" report in the Reports Navigator in Xcode.
According to the report, the "GenerateAssetSymbols" command fails.
Error message:
GenerateAssetSymbols /Users/***/Projects/***/***/Assets.xcassets (in target '***' from project '***')
cd /Users/***/Projects/***
/Applications/Xcode_15.3.app/Contents/Developer/usr/bin/actool --output-format human-readable-text --notices --warnings --export-dependency-info /Users/***/Library/Developer/Xcode/DerivedData/***-***/Index.noindex/Build/Intermediates.noindex/***.build/Debug-iphonesimulator/***.build/assetcatalog_dependencies --output-partial-info-plist /Users/***/Library/Developer/Xcode/DerivedData/***-***/Index.noindex/Build/Intermediates.noindex/***.build/Debug-iphonesimulator/***.build/assetcatalog_generated_info.plist --app-icon AppIcon --accent-color tint --compress-pngs --enable-on-demand-resources YES --development-region en --target-device iphone --minimum-deployment-target 15.0 --platform iphonesimulator --asset-pack-output-specifications /Users/***/Library/Developer/Xcode/DerivedData/***-***/Index.noindex/Build/Intermediates.noindex/***.build/Debug-iphonesimulator/***.build/AssetPackOutputSpecifications.plist --compile /Users/***/Library/Developer/Xcode/DerivedData/***-***/Index.noindex/Build/Products/Debug-iphonesimulator/workoutai.app /Users/***/Projects/***/***/Assets.xcassets --bundle-identifier *** --generate-swift-asset-symbols /Users/***/Library/Developer/Xcode/DerivedData/***-***/Index.noindex/Build/Intermediates.noindex/***.build/Debug-iphonesimulator/***.build/DerivedSources/GeneratedAssetSymbols.swift --generate-objc-asset-symbols /Users/***/Library/Developer/Xcode/DerivedData/***-***/Index.noindex/Build/Intermediates.noindex/***.build/Debug-iphonesimulator/***.build/DerivedSources/GeneratedAssetSymbols.h --generate-asset-symbol-index /Users/***/Library/Developer/Xcode/DerivedData/***-***/Index.noindex/Build/Intermediates.noindex/***.build/Debug-iphonesimulator/***.build/DerivedSources/GeneratedAssetSymbols-Index.plist
/* com.apple.actool.errors */
: error: Could not create a NSArray from '/Users/***/Library/Developer/Xcode/DerivedData/***-***/Index.noindex/Build/Intermediates.noindex/***.build/Debug-iphonesimulator/***.build/AssetPackOutputSpecifications.plist'.
: error: Not enough arguments provided; where is the input document to operate on?
Command GenerateAssetSymbols failed with a nonzero exit code