Implement iOS Share Extension to enable native image sharing from Photos and other apps directly into TimeSafari. Users can now share images from the iOS share sheet, which will open in SharedPhotoView for use as gifts or profile pictures. iOS Native Implementation: - Add TimeSafariShareExtension target with ShareViewController - Configure App Groups for data sharing between extension and main app - Implement ShareViewController to process shared images and convert to base64 - Store shared image data in App Group UserDefaults - Add ShareImageBridge utility to read shared data from App Group - Update AppDelegate to handle shared-photo deep link and bridge data to JS JavaScript Integration: - Add checkAndStoreNativeSharedImage() in main.capacitor.ts to read shared images from native layer via temporary file bridge - Convert base64 data to data URL format for compatibility with base64ToBlob - Integrate with existing SharedPhotoView component - Add "shared-photo" to deep link validation schema Build System: - Integrate Xcode 26 / CocoaPods compatibility workaround into build-ios.sh - Add run_pod_install_with_workaround() for explicit pod install - Add run_cap_sync_with_workaround() for Capacitor sync (which runs pod install internally) - Automatically detect project format version 70 and apply workaround - Remove standalone pod-install-workaround.sh script Code Cleanup: - Remove verbose debug logs from ShareViewController, AppDelegate, and main.capacitor.ts - Retain essential logger calls for production debugging Documentation: - Add ios-share-extension-setup.md with manual Xcode setup instructions - Add ios-share-extension-git-commit-guide.md for version control best practices - Add ios-share-implementation-status.md tracking implementation progress - Add native-share-target-implementation.md with overall architecture - Add xcode-26-cocoapods-workaround.md documenting the compatibility issue The implementation uses a temporary file bridge (AppDelegate writes to Documents directory, JS reads via Capacitor Filesystem plugin) as a workaround for Capacitor plugin auto-discovery issues. This can be improved in the future by properly registering ShareImagePlugin in Capacitor's plugin registry.
606 lines
20 KiB
Bash
Executable File
606 lines
20 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# build-ios.sh
|
|
# Author: Matthew Raymer
|
|
# Description: iOS build script for TimeSafari application
|
|
# Date: 2025-07-11
|
|
|
|
# Exit on any error
|
|
set -e
|
|
|
|
# Source common utilities
|
|
source "$(dirname "$0")/common.sh"
|
|
|
|
# Default values
|
|
BUILD_MODE="development"
|
|
BUILD_TYPE="debug"
|
|
OPEN_STUDIO=false
|
|
BUILD_IPA=false
|
|
BUILD_APP=false
|
|
CLEAN_ONLY=false
|
|
SYNC_ONLY=false
|
|
ASSETS_ONLY=false
|
|
DEPLOY_APP=false
|
|
AUTO_RUN=false
|
|
CUSTOM_API_IP=""
|
|
|
|
# Function to print iOS-specific usage
|
|
print_ios_usage() {
|
|
echo "Usage: $0 [options]"
|
|
echo ""
|
|
echo "iOS Build Options:"
|
|
echo " --dev, --development Build for development environment"
|
|
echo " --test Build for testing environment"
|
|
echo " --prod, --production Build for production environment"
|
|
echo " --debug Build debug app (default)"
|
|
echo " --release Build release app"
|
|
echo " --studio Open Xcode after build"
|
|
echo " --ipa Build IPA file"
|
|
echo " --app Build app bundle"
|
|
echo " --clean Clean build artifacts only"
|
|
echo " --sync Sync Capacitor only"
|
|
echo " --assets Generate assets only"
|
|
echo " --deploy Deploy app to connected device"
|
|
echo " --auto-run Auto-run app after build"
|
|
echo " --api-ip <ip> Custom IP address for claim API (uses Capacitor default)"
|
|
echo ""
|
|
echo "Common Options:"
|
|
echo " -h, --help Show this help message"
|
|
echo " -v, --verbose Enable verbose logging"
|
|
echo ""
|
|
echo "Examples:"
|
|
echo " $0 --dev --studio # Development build + open Xcode"
|
|
echo " $0 --prod --ipa # Production IPA build"
|
|
echo " $0 --test --app # Testing app build"
|
|
echo " $0 --test --auto-run # Test build + auto-run"
|
|
echo " $0 --clean # Clean only"
|
|
echo " $0 --sync # Sync only"
|
|
echo " $0 --deploy # Build and deploy to device"
|
|
echo " $0 --dev # Dev build with Capacitor default"
|
|
echo " $0 --dev --api-ip 192.168.1.100 # Dev build with custom API IP"
|
|
echo ""
|
|
}
|
|
|
|
# Function to parse iOS-specific arguments
|
|
parse_ios_args() {
|
|
local args=("$@")
|
|
local i=0
|
|
|
|
while [ $i -lt ${#args[@]} ]; do
|
|
local arg="${args[$i]}"
|
|
|
|
case $arg in
|
|
--dev|--development)
|
|
BUILD_MODE="development"
|
|
;;
|
|
--test)
|
|
BUILD_MODE="test"
|
|
;;
|
|
--prod|--production)
|
|
BUILD_MODE="production"
|
|
;;
|
|
--debug)
|
|
BUILD_TYPE="debug"
|
|
;;
|
|
--release)
|
|
BUILD_TYPE="release"
|
|
;;
|
|
--studio)
|
|
OPEN_STUDIO=true
|
|
;;
|
|
--ipa)
|
|
BUILD_IPA=true
|
|
;;
|
|
--app)
|
|
BUILD_APP=true
|
|
;;
|
|
--clean)
|
|
CLEAN_ONLY=true
|
|
;;
|
|
--sync)
|
|
SYNC_ONLY=true
|
|
;;
|
|
--assets)
|
|
ASSETS_ONLY=true
|
|
;;
|
|
--deploy)
|
|
DEPLOY_APP=true
|
|
;;
|
|
--auto-run)
|
|
AUTO_RUN=true
|
|
;;
|
|
--api-ip)
|
|
if [ $((i + 1)) -lt ${#args[@]} ]; then
|
|
CUSTOM_API_IP="${args[$((i + 1))]}"
|
|
i=$((i + 1)) # Skip the next argument
|
|
else
|
|
log_error "Error: --api-ip requires an IP address"
|
|
exit 1
|
|
fi
|
|
;;
|
|
--api-ip=*)
|
|
CUSTOM_API_IP="${arg#*=}"
|
|
;;
|
|
-h|--help)
|
|
print_ios_usage
|
|
exit 0
|
|
;;
|
|
-v|--verbose)
|
|
set -x
|
|
;;
|
|
*)
|
|
log_warn "Unknown argument: $arg"
|
|
;;
|
|
esac
|
|
i=$((i + 1))
|
|
done
|
|
}
|
|
|
|
# Function to validate iOS environment
|
|
validate_ios_environment() {
|
|
log_info "Validating iOS build environment..."
|
|
|
|
# Check for Xcode
|
|
if ! command -v xcodebuild &> /dev/null; then
|
|
log_error "Xcode not found. Please install Xcode and command line tools."
|
|
exit 1
|
|
fi
|
|
|
|
# Check for iOS Simulator
|
|
if ! command -v xcrun &> /dev/null; then
|
|
log_error "Xcode command line tools not found. Please install with: xcode-select --install"
|
|
exit 1
|
|
fi
|
|
|
|
# Check for Capacitor
|
|
if ! command -v npx &> /dev/null; then
|
|
log_error "npx not found. Please install Node.js and npm."
|
|
exit 1
|
|
fi
|
|
|
|
# Check for iOS platform
|
|
if [ ! -d "ios" ]; then
|
|
log_error "iOS platform not found. Please run: npx cap add ios"
|
|
exit 1
|
|
fi
|
|
|
|
log_success "iOS build environment validated"
|
|
}
|
|
|
|
# Function to check iOS resources
|
|
check_ios_resources() {
|
|
log_info "Checking iOS resources..."
|
|
|
|
# Check for required assets
|
|
if [ ! -f "assets/icon.png" ]; then
|
|
log_warn "App icon not found at assets/icon.png"
|
|
fi
|
|
|
|
if [ ! -f "assets/splash.png" ]; then
|
|
log_warn "Splash screen not found at assets/splash.png"
|
|
fi
|
|
|
|
# Check for iOS-specific files
|
|
if [ ! -f "ios/App/App/Info.plist" ]; then
|
|
log_warn "Info.plist not found"
|
|
fi
|
|
|
|
if [ ! -f "ios/App/App/AppDelegate.swift" ]; then
|
|
log_warn "AppDelegate.swift not found"
|
|
fi
|
|
|
|
log_success "iOS resource check completed"
|
|
}
|
|
|
|
# Function to clean iOS build
|
|
clean_ios_build() {
|
|
log_info "Cleaning iOS build artifacts..."
|
|
|
|
# Clean Xcode build (temporary output directory)
|
|
if [ -d "ios/App/build" ]; then
|
|
rm -rf ios/App/build/
|
|
log_debug "Cleaned ios/App/build/"
|
|
fi
|
|
|
|
# Clean DerivedData
|
|
if [ -d "ios/App/DerivedData" ]; then
|
|
rm -rf ios/App/DerivedData/
|
|
log_debug "Cleaned ios/App/DerivedData/"
|
|
fi
|
|
|
|
# Clean Capacitor (using npm script instead of invalid cap clean command)
|
|
npm run clean:ios || true
|
|
|
|
log_success "iOS build cleaned"
|
|
}
|
|
|
|
# Function to build iOS app
|
|
build_ios_app() {
|
|
local build_config=""
|
|
local scheme="App"
|
|
local destination=""
|
|
|
|
if [ "$BUILD_TYPE" = "debug" ]; then
|
|
build_config="Debug"
|
|
destination="platform=iOS Simulator,name=iPhone 15 Pro"
|
|
else
|
|
build_config="Release"
|
|
destination="platform=iOS,id=auto"
|
|
fi
|
|
|
|
log_info "Building iOS app (${build_config})..."
|
|
|
|
cd ios/App
|
|
|
|
# Build the app
|
|
xcodebuild -workspace App.xcworkspace \
|
|
-scheme "$scheme" \
|
|
-configuration "$build_config" \
|
|
-destination "$destination" \
|
|
build \
|
|
CODE_SIGN_IDENTITY="" \
|
|
CODE_SIGNING_REQUIRED=NO \
|
|
CODE_SIGNING_ALLOWED=NO
|
|
|
|
cd ../..
|
|
|
|
log_success "iOS app built successfully"
|
|
}
|
|
|
|
# Function to deploy to device
|
|
deploy_ios_app() {
|
|
log_info "Deploy-app mode: building app and deploying to device"
|
|
|
|
# Check for connected device
|
|
local devices=$(xcrun devicectl list devices --json | grep -c '"state":"booted"' || echo "0")
|
|
if [ "$devices" -eq 0 ]; then
|
|
log_error "No iOS device connected. Please connect a device and try again."
|
|
exit 1
|
|
fi
|
|
|
|
# Build app for device
|
|
BUILD_TYPE="debug"
|
|
build_ios_app
|
|
|
|
# Get device ID
|
|
local device_id=$(xcrun devicectl list devices --json | grep -o '"identifier":"[^"]*"' | head -1 | cut -d'"' -f4)
|
|
|
|
if [ -z "$device_id" ]; then
|
|
log_error "Could not find device ID. Please ensure device is connected and unlocked."
|
|
exit 1
|
|
fi
|
|
|
|
# Install app on device
|
|
log_info "Installing app on device..."
|
|
xcrun devicectl device install app --device "$device_id" ios/App/build/Debug-iphoneos/App.app
|
|
|
|
log_success "iOS app deployed successfully to device!"
|
|
log_info "You can now run the app with: npx cap run ios"
|
|
}
|
|
|
|
# Function to auto-run iOS app
|
|
auto_run_ios_app() {
|
|
log_step "Auto-running iOS app..."
|
|
|
|
# Check if we're in debug mode (simulator) or release mode (device)
|
|
if [ "$BUILD_TYPE" = "debug" ]; then
|
|
log_info "Launching iOS Simulator and installing app"
|
|
safe_execute "Launching app" "npx cap run ios" || {
|
|
log_error "Failed to launch iOS app on simulator"
|
|
return 1
|
|
}
|
|
else
|
|
log_info "Building and installing on real device"
|
|
# For release builds, we need to use a different approach
|
|
# since npx cap run ios is primarily for simulators
|
|
log_warn "Auto-run for release builds requires manual device setup"
|
|
log_info "Please use Xcode to run the app on your device"
|
|
return 1
|
|
fi
|
|
|
|
log_success "iOS app launched successfully!"
|
|
}
|
|
|
|
# Parse command line arguments
|
|
parse_ios_args "$@"
|
|
|
|
# Print build header
|
|
print_header "TimeSafari iOS Build Process"
|
|
log_info "Starting iOS build process at $(date)"
|
|
log_info "Build mode: $BUILD_MODE"
|
|
log_info "Build type: $BUILD_TYPE"
|
|
|
|
# Setup environment for Capacitor build
|
|
setup_build_env "capacitor" "$BUILD_MODE"
|
|
|
|
# Override API servers for iOS development when custom IP is specified
|
|
if [ "$BUILD_MODE" = "development" ] && [ -n "$CUSTOM_API_IP" ]; then
|
|
# Use custom IP for physical device development
|
|
export VITE_DEFAULT_ENDORSER_API_SERVER="http://${CUSTOM_API_IP}:3000"
|
|
export VITE_DEFAULT_PARTNER_API_SERVER="http://${CUSTOM_API_IP}:3000"
|
|
log_info "iOS development mode: Using custom IP ${CUSTOM_API_IP} for physical device"
|
|
fi
|
|
|
|
# Setup application directories
|
|
setup_app_directories
|
|
|
|
# Load environment-specific .env file if it exists
|
|
env_file=".env.$BUILD_MODE"
|
|
if [ -f "$env_file" ]; then
|
|
load_env_file "$env_file"
|
|
else
|
|
log_debug "No $env_file file found, using default environment"
|
|
fi
|
|
|
|
# Load .env file if it exists (fallback)
|
|
if [ -f ".env" ]; then
|
|
load_env_file ".env"
|
|
fi
|
|
|
|
# Validate iOS environment
|
|
validate_ios_environment
|
|
|
|
# Handle clean-only mode
|
|
if [ "$CLEAN_ONLY" = true ]; then
|
|
log_info "Clean-only mode: cleaning build artifacts"
|
|
clean_ios_build
|
|
safe_execute "Cleaning dist directory" "clean_build_artifacts dist" || exit 1
|
|
log_success "Clean completed successfully!"
|
|
exit 0
|
|
fi
|
|
|
|
# Handle sync-only mode
|
|
if [ "$SYNC_ONLY" = true ]; then
|
|
log_info "Sync-only mode: syncing with Capacitor"
|
|
safe_execute "Syncing with Capacitor" "npx cap sync ios" || exit 6
|
|
log_success "Sync completed successfully!"
|
|
exit 0
|
|
fi
|
|
|
|
# Handle assets-only mode
|
|
if [ "$ASSETS_ONLY" = true ]; then
|
|
log_info "Assets-only mode: generating assets"
|
|
safe_execute "Generating assets" "npx capacitor-assets generate --ios" || exit 7
|
|
log_success "Assets generation completed successfully!"
|
|
exit 0
|
|
fi
|
|
|
|
# Handle deploy-app mode
|
|
if [ "$DEPLOY_APP" = true ]; then
|
|
deploy_ios_app
|
|
exit 0
|
|
fi
|
|
|
|
# Step 1: Check iOS resources
|
|
check_ios_resources
|
|
|
|
# Step 2: Clean iOS build
|
|
safe_execute "Cleaning iOS build" "clean_ios_build" || exit 1
|
|
|
|
# Step 3: Clean dist directory
|
|
log_info "Cleaning dist directory..."
|
|
clean_build_artifacts "dist"
|
|
|
|
# Step 4: Run TypeScript type checking for test and production builds
|
|
if [ "$BUILD_MODE" = "production" ] || [ "$BUILD_MODE" = "test" ]; then
|
|
log_info "Running TypeScript type checking for $BUILD_MODE mode..."
|
|
|
|
if ! measure_time npm run type-check; then
|
|
log_error "TypeScript type checking failed for $BUILD_MODE mode!"
|
|
exit 2
|
|
fi
|
|
|
|
log_success "TypeScript type checking completed for $BUILD_MODE mode"
|
|
else
|
|
log_debug "Skipping TypeScript type checking for development mode"
|
|
fi
|
|
|
|
# Step 5: Build Capacitor version with mode
|
|
if [ "$BUILD_MODE" = "development" ]; then
|
|
safe_execute "Building Capacitor version (development)" "npm run build:capacitor" || exit 3
|
|
elif [ "$BUILD_MODE" = "test" ]; then
|
|
safe_execute "Building Capacitor version (test)" "npm run build:capacitor -- --mode test" || exit 3
|
|
elif [ "$BUILD_MODE" = "production" ]; then
|
|
safe_execute "Building Capacitor version (production)" "npm run build:capacitor -- --mode production" || exit 3
|
|
fi
|
|
|
|
# Step 6: Install CocoaPods dependencies (with Xcode 26 workaround)
|
|
# ===================================================================
|
|
# WORKAROUND: Xcode 26 / CocoaPods Compatibility Issue
|
|
# ===================================================================
|
|
# Xcode 26 uses project format version 70, but CocoaPods' xcodeproj gem
|
|
# (1.27.0) only supports up to version 56. This causes pod install to fail.
|
|
#
|
|
# This workaround temporarily downgrades the project format to 56, runs
|
|
# pod install, then restores it to 70. Xcode will automatically upgrade
|
|
# it back to 70 when opened, which is fine.
|
|
#
|
|
# NOTE: Both explicit pod install AND Capacitor sync (which runs pod install
|
|
# internally) need this workaround. See run_pod_install_with_workaround()
|
|
# and run_cap_sync_with_workaround() functions below.
|
|
#
|
|
# TO REMOVE THIS WORKAROUND IN THE FUTURE:
|
|
# 1. Check if xcodeproj gem has been updated: bundle exec gem list xcodeproj
|
|
# 2. Test if pod install works without the workaround
|
|
# 3. If it works, remove both workaround functions below
|
|
# 4. Replace with:
|
|
# - safe_execute "Installing CocoaPods dependencies" "cd ios/App && bundle exec pod install && cd ../.." || exit 6
|
|
# - safe_execute "Syncing with Capacitor" "npx cap sync ios" || exit 6
|
|
# 5. Update this comment to indicate the workaround has been removed
|
|
# ===================================================================
|
|
run_pod_install_with_workaround() {
|
|
local PROJECT_FILE="ios/App/App.xcodeproj/project.pbxproj"
|
|
|
|
log_info "Installing CocoaPods dependencies (with Xcode 26 workaround)..."
|
|
|
|
# Check if project file exists
|
|
if [ ! -f "$PROJECT_FILE" ]; then
|
|
log_error "Project file not found: $PROJECT_FILE"
|
|
return 1
|
|
fi
|
|
|
|
# Check current format version
|
|
local current_version=$(grep "objectVersion" "$PROJECT_FILE" | head -1 | grep -o "[0-9]\+" || echo "")
|
|
|
|
if [ -z "$current_version" ]; then
|
|
log_error "Could not determine project format version"
|
|
return 1
|
|
fi
|
|
|
|
log_debug "Current project format version: $current_version"
|
|
|
|
# Only apply workaround if format is 70
|
|
if [ "$current_version" = "70" ]; then
|
|
log_debug "Applying Xcode 26 workaround: temporarily downgrading to format 56"
|
|
|
|
# Downgrade to format 56 (supported by CocoaPods)
|
|
if ! sed -i '' 's/objectVersion = 70;/objectVersion = 56;/' "$PROJECT_FILE"; then
|
|
log_error "Failed to downgrade project format"
|
|
return 1
|
|
fi
|
|
|
|
# Run pod install
|
|
log_info "Running pod install..."
|
|
if ! (cd ios/App && bundle exec pod install && cd ../..); then
|
|
log_error "pod install failed"
|
|
# Try to restore format even on failure
|
|
sed -i '' 's/objectVersion = 56;/objectVersion = 70;/' "$PROJECT_FILE" || true
|
|
return 1
|
|
fi
|
|
|
|
# Restore to format 70
|
|
log_debug "Restoring project format to 70..."
|
|
if ! sed -i '' 's/objectVersion = 56;/objectVersion = 70;/' "$PROJECT_FILE"; then
|
|
log_warn "Failed to restore project format to 70 (Xcode will upgrade it automatically)"
|
|
fi
|
|
|
|
log_success "CocoaPods dependencies installed successfully"
|
|
else
|
|
# Format is not 70, run pod install normally
|
|
log_debug "Project format is $current_version, running pod install normally"
|
|
if ! (cd ios/App && bundle exec pod install && cd ../..); then
|
|
log_error "pod install failed"
|
|
return 1
|
|
fi
|
|
log_success "CocoaPods dependencies installed successfully"
|
|
fi
|
|
}
|
|
|
|
safe_execute "Installing CocoaPods dependencies" "run_pod_install_with_workaround" || exit 6
|
|
|
|
# Step 6.5: Sync with Capacitor (also needs workaround since it runs pod install internally)
|
|
# Capacitor sync internally runs pod install, so we need to apply the workaround here too
|
|
run_cap_sync_with_workaround() {
|
|
local PROJECT_FILE="ios/App/App.xcodeproj/project.pbxproj"
|
|
|
|
# Check current format version
|
|
local current_version=$(grep "objectVersion" "$PROJECT_FILE" | head -1 | grep -o "[0-9]\+" || echo "")
|
|
|
|
if [ -z "$current_version" ]; then
|
|
log_error "Could not determine project format version for Capacitor sync"
|
|
return 1
|
|
fi
|
|
|
|
# Only apply workaround if format is 70
|
|
if [ "$current_version" = "70" ]; then
|
|
log_debug "Applying Xcode 26 workaround for Capacitor sync: temporarily downgrading to format 56"
|
|
|
|
# Downgrade to format 56 (supported by CocoaPods)
|
|
if ! sed -i '' 's/objectVersion = 70;/objectVersion = 56;/' "$PROJECT_FILE"; then
|
|
log_error "Failed to downgrade project format for Capacitor sync"
|
|
return 1
|
|
fi
|
|
|
|
# Run Capacitor sync (which will run pod install internally)
|
|
log_info "Running Capacitor sync..."
|
|
if ! npx cap sync ios; then
|
|
log_error "Capacitor sync failed"
|
|
# Try to restore format even on failure
|
|
sed -i '' 's/objectVersion = 56;/objectVersion = 70;/' "$PROJECT_FILE" || true
|
|
return 1
|
|
fi
|
|
|
|
# Restore to format 70
|
|
log_debug "Restoring project format to 70 after Capacitor sync..."
|
|
if ! sed -i '' 's/objectVersion = 56;/objectVersion = 70;/' "$PROJECT_FILE"; then
|
|
log_warn "Failed to restore project format to 70 (Xcode will upgrade it automatically)"
|
|
fi
|
|
|
|
log_success "Capacitor sync completed successfully"
|
|
else
|
|
# Format is not 70, run sync normally
|
|
log_debug "Project format is $current_version, running Capacitor sync normally"
|
|
if ! npx cap sync ios; then
|
|
log_error "Capacitor sync failed"
|
|
return 1
|
|
fi
|
|
log_success "Capacitor sync completed successfully"
|
|
fi
|
|
}
|
|
|
|
safe_execute "Syncing with Capacitor" "run_cap_sync_with_workaround" || exit 6
|
|
|
|
# Step 7: Generate assets
|
|
safe_execute "Generating assets" "npx capacitor-assets generate --ios" || exit 7
|
|
|
|
# Step 8: Build iOS app
|
|
safe_execute "Building iOS app" "build_ios_app" || exit 5
|
|
|
|
# Step 9: Build IPA/App if requested
|
|
if [ "$BUILD_IPA" = true ]; then
|
|
log_info "Building IPA package..."
|
|
cd ios/App
|
|
xcodebuild -workspace App.xcworkspace \
|
|
-scheme App \
|
|
-configuration Release \
|
|
-archivePath build/App.xcarchive \
|
|
archive \
|
|
CODE_SIGN_IDENTITY="" \
|
|
CODE_SIGNING_REQUIRED=NO \
|
|
CODE_SIGNING_ALLOWED=NO
|
|
|
|
xcodebuild -exportArchive \
|
|
-archivePath build/App.xcarchive \
|
|
-exportPath build/ \
|
|
-exportOptionsPlist exportOptions.plist
|
|
cd ../..
|
|
log_success "IPA package built successfully"
|
|
fi
|
|
|
|
if [ "$BUILD_APP" = true ]; then
|
|
log_info "Building app bundle..."
|
|
# App bundle is already built in step 7
|
|
log_success "App bundle built successfully"
|
|
fi
|
|
|
|
# Step 10: Auto-run app if requested
|
|
if [ "$AUTO_RUN" = true ]; then
|
|
safe_execute "Auto-running iOS app" "auto_run_ios_app" || exit 9
|
|
fi
|
|
|
|
# Step 11: Open Xcode if requested
|
|
if [ "$OPEN_STUDIO" = true ]; then
|
|
safe_execute "Opening Xcode" "npx cap open ios" || exit 8
|
|
fi
|
|
|
|
# Print build summary
|
|
log_success "iOS build completed successfully!"
|
|
log_info "Build mode: $BUILD_MODE"
|
|
log_info "Build type: $BUILD_TYPE"
|
|
if [ "$BUILD_IPA" = true ]; then
|
|
log_info "IPA build: completed"
|
|
fi
|
|
if [ "$BUILD_APP" = true ]; then
|
|
log_info "App build: completed"
|
|
fi
|
|
if [ "$AUTO_RUN" = true ]; then
|
|
log_info "Auto-run: completed"
|
|
fi
|
|
if [ "$OPEN_STUDIO" = true ]; then
|
|
log_info "Xcode: opened"
|
|
fi
|
|
|
|
print_footer "iOS Build"
|
|
|
|
# Exit with success
|
|
exit 0 |