Single Size Icons: Solving "Core Data API misuse" and "Command CompileAssetCatalog failed with a nonzero exit code"
* your complications assets have the proper Scale (Individual Scales for Circular and Graphic Extra large, Single Scale for the others)
* all icons are setup to "Single Size", whether it's your main AppIcon or an alternate one
When I first heard about the support for single-size icons at WWDC22, I was thrilled. I had a reasonably good setup to generate the images with Affinity Designer and a Shortcut, but maybe it wasn't worth the trouble.
Starting Size
The first thing I did was to use build an archive and check the size like Antoine van der Lee did, which got me this report (I simplified it). The process is explained by Apple in their Reducing your app’s size guide.
# iPhone 14 Pro
App + On Demand Resources size: 71,8 MB compressed, 82,4 MB uncompressed
App size: 71,8 MB compressed, 82,4 MB uncompressed
On Demand Resources size: Zero KB compressed, Zero KB uncompressed
# Watch Ultra
App + On Demand Resources size: 26,1 MB compressed, 32,2 MB uncompressed
App size: 26,1 MB compressed, 32,2 MB uncompressed
Up until now, I had:
- one AppIcon in the Assets.xcassets of the iOS target, with icons for both iOS and watchOS (can't really remember why…)
- one AppIcon in the Assets.xcassets of the watchOS target
So the first thing I did was to have:
- a single Assets for both iOS and watchOS (add it to the Watch app target): I created a new "Heavy.xcassets" for all assets used for iOS (and soon more…), so that my Assets.xcassets would be limited to assets shared between all apps (I have other catalogs for things shared with apps + extensions). This means I only had the AppIcon in there for now.
- delete the AppIcon from the Assets of the Watch target
I build on the Watch to make sure that the change didn't mess anything up.
I created a new archive and went through the process of exporting the archive for development with app thinning again, to see what changed.
# iPhone 14 Pro
App + On Demand Resources size: 71,8 MB compressed, 82,4 MB uncompressed
App size: 71,8 MB compressed, 82,4 MB uncompressed
On Demand Resources size: Zero KB compressed, Zero KB uncompressed
# Watch Ultra
App + On Demand Resources size: 26,1 MB compressed, 32,2 MB uncompressed
App size: 26,1 MB compressed, 32,2 MB uncompressed
On Demand Resources size: Zero KB compressed, Zero KB uncompressed
All good!
Switching to Single Size
I went ahead and proceed to opt for Single Size
I built my app, and it got ugly:
The error message was not rather confusing: why is Core Data involved in this?
AssetCatalogSimulatorAgent *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Object 0x906e9858c73ac8ba <x-coredata://E0662F14-2CE1-4084-BCF3-D261022348C6/SimpleArtworkRenditionSpec/p82> persistent store is not reachable from this NSManagedObjectContext's coordinator'
*** First throw call stack:
(
0 CoreFoundation 0x00000001807a3b44 __exceptionPreprocess + 172
1 libobjc.A.dylib 0x000000018005c144 objc_exception_throw + 56
2 CoreData 0x00000001858739cc _PFRetainedObjectIDCore + 680
3 CoreData 0x000000018586a1e4 -[NSManagedObjectContext objectWithID:] + 424
4 CoreThemeDefinition 0x000000019d9b5b2c __34-[TDRenditionsDistiller _distill:]_block_invoke + 36
5 CoreData 0x0000000185871720 developerSubmittedBlockToNSManagedObjectContextPerform + 156
6 …
)
2022-11-09 14:00:32.369 AssetCatalogSimulatorAgent[38516:518671] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Object 0x906e9858e65ac95a <x-coredata://E0662F14-2CE1-4084-BCF3-D261022348C6/NamedColorRenditionSpec/p345> persistent store is not reachable from this NSManagedObjectContext's coordinator'
*** First throw call stack:
(…)
2022-11-09 14:00:32.369 AssetCatalogSimulatorAgent[38516:518675] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Object 0x906e9858e5fac8ba <x-coredata://E0662F14-2CE1-4084-BCF3-D261022348C6/SimpleArtworkRenditionSpec/p324> persistent store is not reachable from this NSManagedObjectContext's coordinator'
*** First throw call stack:
(…)
2022-11-09 14:00:32.369 AssetCatalogSimulatorAgent[38516:518672] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Object 0x906e9858c3dac8ba <x-coredata://E0662F14-2CE1-4084-BCF3-D261022348C6/SimpleArtworkRenditionSpec/p117> persistent store is not reachable from this NSManagedObjectContext's coordinator'
*** First throw call stack:
(…)
libc++abi: terminating with uncaught exception of type NSException
/* com.apple.actool.errors */
: error: ERROR: Identical key for two renditions
(E)Key
element: Grouped/Packed Images
part: Artwork Image
value: (null)
identifier: 0
dimension1: 0
state: (null)
scale: 2
idiom: watch
subtype: 0
gamut: sRGB
target: any
sizeClassHorizontal: universal
sizeClassVertical: universal
graphicsFeatureSetClass: GLES2,0
memoryClass: 0
target: any
appearance: (null)
localization: (null)
glyphWeight: (null)
tglypSize: (null)
deployment: any
I got stuck in that place for about a month:
I had more urgent matters to tend to, but with the announcement of a new round of "Ask Apple" I decided to give it another shot and so that I could submit a request.
After a little bit more digging, I found the culprit: Complications Assets.
I switched from "Individual Scales" to "Single Scale", updated one of the icons for the Graphic Extra Large, 38mm, but that was it: the build error disappeared.
I thought I was done and tried to archive the app this time, not just build it: it failed.
For the Graphic Extra Large, I changed the Apple Watch Screen Width to be "Any" instead of Individual Widths. This time I received a new error.
I opened the Assets for my Alternate App Icons and switched them all from "All Sizes" to "Single Size". It worked!
But I received warnings, because not all formats require the same scale 😤. Here's my setup:
- Circular: Individual Scales ⚠️
- Extra Large: Single Scale
- Graphic Bezel: Single Scale
- Graphic Circular: Single Scale
- Graphic Corner: Single Scale
- Graphic Extra Large: Individual Scales ⚠️
- Graphic Large Rectangular: Single Scale
- Modular: Single Scale
- Utilitarian: Single Scale
The (Initial) Result
# iPhone 14 Pro
App + On Demand Resources size: 74,7 MB compressed, 85,3 MB uncompressed
App size: 74,7 MB compressed, 85,3 MB uncompressed
On Demand Resources size: Zero KB compressed, Zero KB uncompressed
# Watch Ultra
App + On Demand Resources size: 26 MB compressed, 32,2 MB uncompressed
App size: 26 MB compressed, 32,2 MB uncompressed
On Demand Resources size: Zero KB compressed, Zero KB uncompressed
74,7 MB compressed with Single Size, vs 71,8MB compressed with All Sizes.
It is rather disappointing as a reward after so much waiting and debugging! But all is not lost. In the process, I discovered that my app could weigh a lot less! But that's for another post ;)
Anyway, I think I'll keep my current setup for the time being. What would you do? 🙃
[Follow-up] The final result!
After this disappointing result, I started to investigate my assets and managed to divide the weight of the app by 3.
And then I discovered something: the reason why the above result was disappointing was that my configuration didn't yet handle all the new icon sizes.
By adding the new sizes, the App size went up
App size: 29,1 MB compressed, 41,2 MB uncompressed
And it was actually with the Single Size that I was able to get back to a reasonable size.
App size: 22,2 MB compressed, 33,4 MB uncompressed
Conclusion
These errors happen especially when you haven't caught up on the latest sizes. I guess Xcode will try to make the bridge between the required sizes and what you offer, but sometimes finds itself in an inextricable situation and spouts these incomprehensible errors.
Anyway, with a little help on my part, Single Size turned out to be a no-brainer:
- less work to prepare the files
- smaller app size
So, in the end, I'll say: Well done Xcode!