From 6d221ee1cad28681d979584970fb77b57a5a2166 Mon Sep 17 00:00:00 2001 From: Jose Olarte III Date: Thu, 16 Jul 2026 18:34:22 +0800 Subject: [PATCH] Install optional iOS Dark/Tinted app icons after capacitor-assets generate. Post-process AppIcon.appiconset so appearance variants are reapplied on every iOS build without changing the existing asset generation flow. --- scripts/build-ios.sh | 113 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 109 insertions(+), 4 deletions(-) diff --git a/scripts/build-ios.sh b/scripts/build-ios.sh index eac5f9a5..6479f8aa 100755 --- a/scripts/build-ios.sh +++ b/scripts/build-ios.sh @@ -192,6 +192,113 @@ check_ios_resources() { log_success "iOS resource check completed" } +# iOS app icon appearance variants (Dark, Tinted, …). +# Luminosity appearance values match Apple's asset catalog format (iOS 18+). +readonly _IOS_APP_ICON_APPEARANCE_LUMINOSITY="luminosity" +readonly _IOS_APP_ICON_APPEARANCE_DARK="dark" +readonly _IOS_APP_ICON_APPEARANCE_TINTED="tinted" + +# Each row: source_file|luminosity_value|dest_filename +# To add a variant: append one row and place the source PNG under resources/ios/. +readonly _IOS_APP_ICON_APPEARANCE_VARIANTS=( + "resources/ios/icon/icon-dark.png|${_IOS_APP_ICON_APPEARANCE_DARK}|AppIcon-Dark.png" + "resources/ios/icon/icon-tinted.png|${_IOS_APP_ICON_APPEARANCE_TINTED}|AppIcon-Tinted.png" +) + +# Update AppIcon.appiconset/Contents.json with one 1024×1024 appearance entry. +# Preserves all other images (including capacitor-assets output); replaces any +# existing entry for the same luminosity appearance. +_update_appicon_contents_for_appearance() { + local contents_json="$1" + local dest_filename="$2" + local luminosity_value="$3" + + local tmp_file + tmp_file="$(mktemp)" + + if ! jq --arg filename "$dest_filename" \ + --arg appearance "$_IOS_APP_ICON_APPEARANCE_LUMINOSITY" \ + --arg value "$luminosity_value" \ + ' + .images |= map(select((.appearances[0].value // "") != $value)) + | .images += [{ + "appearances": [{ + "appearance": $appearance, + "value": $value + }], + "filename": $filename, + "idiom": "universal", + "platform": "ios", + "size": "1024x1024" + }] + ' "$contents_json" > "$tmp_file"; then + rm -f "$tmp_file" + log_error "Failed to update AppIcon Contents.json for appearance: $luminosity_value" + return 1 + fi + + mv "$tmp_file" "$contents_json" +} + +# Install one appearance variant when its source PNG exists. +_apply_ios_app_icon_appearance_variant() { + local appiconset_dir="$1" + local contents_json="$2" + local source_file="$3" + local luminosity_value="$4" + local dest_filename="$5" + + if [ ! -f "$source_file" ]; then + log_info "iOS app icon appearance variant not found ($source_file) — skipping" + return 0 + fi + + if [ ! -d "$appiconset_dir" ]; then + log_warn "AppIcon.appiconset not found — skipping appearance variant ($luminosity_value)" + return 0 + fi + + if ! cp "$source_file" "$appiconset_dir/$dest_filename"; then + log_error "Failed to copy $source_file to $appiconset_dir/$dest_filename" + return 1 + fi + + log_info "Installed iOS app icon appearance variant: $luminosity_value ($dest_filename)" + _update_appicon_contents_for_appearance "$contents_json" "$dest_filename" "$luminosity_value" +} + +# Post-process capacitor-assets iOS icons: copy optional Dark/Tinted sources and +# register them in AppIcon.appiconset/Contents.json. +apply_ios_app_icon_appearances() { + local appiconset_dir="ios/App/App/Assets.xcassets/AppIcon.appiconset" + local contents_json="$appiconset_dir/Contents.json" + + if [ ! -f "$contents_json" ]; then + log_info "AppIcon Contents.json not found — skipping appearance variants" + return 0 + fi + + if ! command -v jq &> /dev/null; then + log_error "jq is required to install iOS app icon appearance variants (install with: brew install jq)" + return 1 + fi + + local variant source_file luminosity_value dest_filename + for variant in "${_IOS_APP_ICON_APPEARANCE_VARIANTS[@]}"; do + IFS='|' read -r source_file luminosity_value dest_filename <<< "$variant" + _apply_ios_app_icon_appearance_variant \ + "$appiconset_dir" "$contents_json" \ + "$source_file" "$luminosity_value" "$dest_filename" + done +} + +# Generate iOS assets (capacitor-assets), then apply optional appearance variants. +generate_ios_assets() { + ensure_ios_capacitor_asset_directories + npx capacitor-assets generate --ios + apply_ios_app_icon_appearances +} + # Function to clean iOS build clean_ios_build() { log_info "Cleaning iOS build artifacts..." @@ -424,8 +531,7 @@ fi # Handle assets-only mode if [ "$ASSETS_ONLY" = true ]; then log_info "Assets-only mode: generating assets" - ensure_ios_capacitor_asset_directories - safe_execute "Generating assets" "npx capacitor-assets generate --ios" || exit 7 + safe_execute "Generating assets" "generate_ios_assets" || exit 7 log_success "Assets generation completed successfully!" exit 0 fi @@ -574,8 +680,7 @@ safe_execute "Installing CocoaPods dependencies" "run_pod_install_with_workaroun safe_execute "Syncing with Capacitor" "run_cap_sync_with_workaround" || exit 6 # Step 7: Generate assets -ensure_ios_capacitor_asset_directories -safe_execute "Generating assets" "npx capacitor-assets generate --ios" || exit 7 +safe_execute "Generating assets" "generate_ios_assets" || exit 7 # Step 8: Build iOS app safe_execute "Building iOS app" "build_ios_app" || exit 5