You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							449 lines
						
					
					
						
							13 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							449 lines
						
					
					
						
							13 KiB
						
					
					
				| #!/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 from .env file if it exists | |
| load_env_file ".env" | |
| 
 | |
| # 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: 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 5: Sync with Capacitor | |
| safe_execute "Syncing with Capacitor" "npx cap sync ios" || exit 6 | |
| 
 | |
| # Step 6: Generate assets | |
| safe_execute "Generating assets" "npx capacitor-assets generate --ios" || exit 7 | |
| 
 | |
| # Step 7: Build iOS app | |
| safe_execute "Building iOS app" "build_ios_app" || exit 5 | |
| 
 | |
| # Step 8: 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 9: Auto-run app if requested | |
| if [ "$AUTO_RUN" = true ]; then | |
|     safe_execute "Auto-running iOS app" "auto_run_ios_app" || exit 9 | |
| fi | |
| 
 | |
| # Step 10: 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  |