Emit the iOS launch image set whole - #320
Conversation
installIosSplashScreen() writes Contents.json and copies in the app's splash variants, but never clears what was there first, so the set is the union of every build that came before it. A variant the app has dropped keeps shipping, and a file written by something other than core survives into a set that no longer lists it — including the bitmap-beside-"Any" scale combination the asset compiler rejects, which the code immediately above already goes out of its way to avoid. Clear the set before writing it. Only when there is artwork to replace it with: the installed project ships a default set, and an app with no splash of its own keeps it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
shanerbaner82
left a comment
There was a problem hiding this comment.
Nice, focused fix. Two cleanup boundaries need handling before merge:
- Guard a symlinked
LaunchImage.imageset; recursive deletion can erase the link target. - Cover custom → no splash, which currently leaves the previous custom image shipping.
Once those edges are covered, this should be straightforward to merge.
768f876 to
6977942
Compare
|
Both edges are covered. Symlinked set. Custom → no splash. The early Two tests added for these; both fail against the previous revision (the symlink one shows the target's file erased). Full unit suite green. |
LaunchImage.imageset may be a symlink into artwork the app maintains elsewhere. File::deleteDirectory() gates on is_dir(), which resolves the link — it guards nested symlinks but not the top-level path, so clearing through one erases the target's contents. Unlink the link instead, and give core a real directory back. An app that drops its splash artwork keeps shipping the last custom image, because the "no variants found" path returns before the set is touched. That path now restores the set a fresh install ships. Clearing to nothing is not an option: LaunchScreen.storyboard and SplashView.swift both reference the LaunchImage asset. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
6977942 to
44586fc
Compare
Follow-up to #159, which was closed with an invitation to raise anything in core that made building the plugin harder. The splash behavior now lives in unlocnl/nativephp-enhanced-splash; this is one of the things that turned up while building it.
It stands on its own as a bug, though — no plugin needed to hit it.
installIosSplashScreen()writesContents.jsonand copies the app's splash variants intoLaunchImage.imageset, but never clears the directory first. The set that ends up in the build is therefore the union of every build that came before it.Two consequences:
A dropped variant keeps shipping. Remove
public/splash-dark@3x.pngand rebuild: it is gone fromContents.json, but the file is still in the image set and still in the app.Content core did not write survives into a set that no longer lists it. This is the one that bites plugins. A plugin that substitutes a vector launch image writes
splash.svginto the set; the next build rewritesContents.jsonto list the PNGs again and leaves the.svgsitting there. That is exactly the mixed bitmap / "Any" scale combination the code immediately above this goes out of its way to avoid:The change
Clear the image set before writing it, so it is emitted whole.
Only when there is artwork to replace it with — the clear sits after the
empty($foundVariants)early return, not before it. The installed project ships a defaultLaunchImage.imageset, and an app with no splash of its own keeps it.Why this helps plugins
A plugin that replaces a generated asset needs to be able to put it back when its config changes. For files core installs verbatim it can copy core's own copy back. For this set there is no such source — it is generated from the app's
public/splash*.png— so today a plugin has to snapshot core's output into a private directory inside the build tree on first run, purely so it can restore it later. That stash is only necessary because the next build does not start clean.With this change it does: whatever a plugin writes into the set, core takes the set back whole on the next build, and an app with no artwork keeps the shipped default. In the plugin this came out of, it removed the entire stash mechanism.
Testing
tests/Unit/Concerns/InstallsSplashScreenTest.php— covers the dropped variant, foreign content, and the default set being left alone when the app ships no splash. The first two fail without the change.