Add comprehensive iOS build and deployment infrastructure with command-line tooling, documentation, and web assets synchronization. Changes: - Update Capacitor dependencies to v6.0 in podspec - Add iOS build support to build-native.sh with NVM integration - Sync iOS web assets to match www/ source directory - Create deployment scripts for both native iOS app and Vue 3 test app - Add comprehensive iOS simulator deployment documentation - Document web assets parity requirements between Android and iOS This enables: - Command-line iOS builds without Xcode UI - Automated deployment to iOS simulators - Consistent web assets across platforms - Clear separation between native iOS app (ios/App) and Vue 3 test app Files modified: - ios/DailyNotificationPlugin.podspec (Capacitor 6.0) - ios/App/App/public/index.html (synced from www/) - scripts/build-native.sh (iOS build support) Files added: - docs/WEB_ASSETS_PARITY.md - docs/standalone-ios-simulator-guide.md - scripts/build-and-deploy-native-ios.sh - test-apps/daily-notification-test/docs/IOS_BUILD_QUICK_REFERENCE.md - test-apps/daily-notification-test/scripts/build-and-deploy-ios.sh
549 lines
13 KiB
Markdown
549 lines
13 KiB
Markdown
# Running iOS Apps in Standalone Simulator (Without Xcode UI)
|
|
|
|
**Author**: Matthew Raymer
|
|
**Last Updated**: 2025-11-04
|
|
**Version**: 1.0.0
|
|
|
|
## Overview
|
|
|
|
This guide demonstrates how to run DailyNotification plugin test apps in a standalone iOS Simulator without using Xcode UI. This method is useful for development, CI/CD pipelines, and command-line workflows.
|
|
|
|
**There are two different test apps:**
|
|
1. **Native iOS Development App** (`ios/App`) - Simple Capacitor app for plugin development
|
|
2. **Vue 3 Test App** (`test-apps/daily-notification-test`) - Full-featured Vue 3 Capacitor app for comprehensive testing
|
|
|
|
## Prerequisites
|
|
|
|
### Required Software
|
|
- **Xcode** with command line tools (`xcode-select --install`)
|
|
- **iOS Simulator** (included with Xcode)
|
|
- **CocoaPods** (`gem install cocoapods`)
|
|
- **Node.js** and **npm** (for TypeScript compilation)
|
|
- **Capacitor CLI** (`npm install -g @capacitor/cli`) - for Vue 3 test app
|
|
|
|
### System Requirements
|
|
- **macOS** (required for iOS development)
|
|
- **RAM**: 4GB minimum, 8GB recommended
|
|
- **Storage**: 5GB free space for simulator and dependencies
|
|
|
|
---
|
|
|
|
## Scenario 1: Native iOS Development App (`ios/App`)
|
|
|
|
The `ios/App` directory contains a simple Capacitor-based development app, similar to `android/app`. This is used for quick plugin testing and development.
|
|
|
|
### Step-by-Step Process
|
|
|
|
#### 1. Check Available Simulators
|
|
|
|
```bash
|
|
# List available iOS simulators
|
|
xcrun simctl list devices available
|
|
|
|
# Example output:
|
|
# iPhone 15 Pro (iOS 17.0)
|
|
# iPhone 14 (iOS 16.4)
|
|
# iPad Pro (12.9-inch) (iOS 17.0)
|
|
```
|
|
|
|
#### 2. Boot a Simulator
|
|
|
|
```bash
|
|
# Boot a specific simulator device
|
|
xcrun simctl boot "iPhone 15 Pro"
|
|
|
|
# Or boot by device ID
|
|
xcrun simctl boot <DEVICE_ID>
|
|
|
|
# Verify simulator is running
|
|
xcrun simctl list devices | grep Booted
|
|
```
|
|
|
|
**Alternative: Open Simulator UI**
|
|
```bash
|
|
# Open Simulator app (allows visual interaction)
|
|
open -a Simulator
|
|
```
|
|
|
|
#### 3. Build the Plugin
|
|
|
|
```bash
|
|
# Navigate to project directory
|
|
cd /path/to/daily-notification-plugin
|
|
|
|
# Build plugin for iOS
|
|
./scripts/build-native.sh --platform ios
|
|
```
|
|
|
|
**What this does:**
|
|
- Compiles TypeScript to JavaScript
|
|
- Builds iOS native code (Swift)
|
|
- Creates plugin framework
|
|
- Builds for simulator
|
|
|
|
#### 4. Build Native iOS Development App
|
|
|
|
```bash
|
|
# Navigate to iOS directory
|
|
cd ios
|
|
|
|
# Install CocoaPods dependencies
|
|
pod install
|
|
|
|
# Build the development app for simulator
|
|
cd App
|
|
xcodebuild -workspace App.xcworkspace \
|
|
-scheme App \
|
|
-configuration Debug \
|
|
-sdk iphonesimulator \
|
|
-destination 'platform=iOS Simulator,name=iPhone 15 Pro' \
|
|
-derivedDataPath build/derivedData \
|
|
CODE_SIGN_IDENTITY="" \
|
|
CODE_SIGNING_REQUIRED=NO \
|
|
CODE_SIGNING_ALLOWED=NO \
|
|
clean build
|
|
```
|
|
|
|
#### 5. Install App on Simulator
|
|
|
|
```bash
|
|
# Find the built app
|
|
APP_PATH=$(find build/derivedData -name "*.app" -type d -path "*/Build/Products/*-iphonesimulator/*.app" | head -1)
|
|
|
|
# Install app on simulator
|
|
xcrun simctl install booted "$APP_PATH"
|
|
```
|
|
|
|
#### 6. Launch the App
|
|
|
|
```bash
|
|
# Get bundle identifier from Info.plist
|
|
BUNDLE_ID=$(plutil -extract CFBundleIdentifier raw App/Info.plist)
|
|
|
|
# Launch the app
|
|
xcrun simctl launch booted "$BUNDLE_ID"
|
|
|
|
# Example:
|
|
# xcrun simctl launch booted com.timesafari.dailynotification
|
|
```
|
|
|
|
#### 7. Monitor App Logs
|
|
|
|
```bash
|
|
# View all logs
|
|
xcrun simctl spawn booted log stream
|
|
|
|
# Filter for specific processes
|
|
xcrun simctl spawn booted log stream --predicate 'processImagePath contains "App"'
|
|
|
|
# View system logs
|
|
log stream --predicate 'processImagePath contains "App"' --level debug
|
|
```
|
|
|
|
### Complete Command Sequence for Native iOS App
|
|
|
|
```bash
|
|
# 1. Boot simulator
|
|
xcrun simctl boot "iPhone 15 Pro" || open -a Simulator
|
|
|
|
# 2. Build plugin
|
|
cd /path/to/daily-notification-plugin
|
|
./scripts/build-native.sh --platform ios
|
|
|
|
# 3. Build native iOS app
|
|
cd ios
|
|
pod install
|
|
cd App
|
|
xcodebuild -workspace App.xcworkspace \
|
|
-scheme App \
|
|
-configuration Debug \
|
|
-sdk iphonesimulator \
|
|
-destination 'platform=iOS Simulator,name=iPhone 15 Pro' \
|
|
CODE_SIGN_IDENTITY="" \
|
|
CODE_SIGNING_REQUIRED=NO \
|
|
CODE_SIGNING_ALLOWED=NO
|
|
|
|
# 4. Install app
|
|
APP_PATH=$(find build/derivedData -name "*.app" -type d | head -1)
|
|
xcrun simctl install booted "$APP_PATH"
|
|
|
|
# 5. Launch app
|
|
BUNDLE_ID=$(plutil -extract CFBundleIdentifier raw App/Info.plist)
|
|
xcrun simctl launch booted "$BUNDLE_ID"
|
|
```
|
|
|
|
---
|
|
|
|
## Scenario 2: Vue 3 Test App (`test-apps/daily-notification-test`)
|
|
|
|
The `test-apps/daily-notification-test` directory contains a full-featured Vue 3 Capacitor app with comprehensive testing interface, similar to the Android test app.
|
|
|
|
### Step-by-Step Process
|
|
|
|
#### 1. Check Available Simulators
|
|
|
|
```bash
|
|
# List available iOS simulators
|
|
xcrun simctl list devices available
|
|
```
|
|
|
|
#### 2. Boot a Simulator
|
|
|
|
```bash
|
|
# Boot a specific simulator device
|
|
xcrun simctl boot "iPhone 15 Pro"
|
|
|
|
# Or open Simulator UI
|
|
open -a Simulator
|
|
```
|
|
|
|
#### 3. Build the Plugin
|
|
|
|
```bash
|
|
# Navigate to project directory
|
|
cd /path/to/daily-notification-plugin
|
|
|
|
# Build plugin for iOS
|
|
./scripts/build-native.sh --platform ios
|
|
```
|
|
|
|
#### 4. Set Up Vue 3 Test App iOS Project
|
|
|
|
```bash
|
|
# Navigate to test app
|
|
cd test-apps/daily-notification-test
|
|
|
|
# Install dependencies
|
|
npm install
|
|
|
|
# Add iOS platform (if not already added)
|
|
npx cap add ios
|
|
|
|
# Sync web assets with iOS project
|
|
npx cap sync ios
|
|
```
|
|
|
|
#### 5. Build Vue 3 Test App
|
|
|
|
```bash
|
|
# Build web assets (Vue 3 app)
|
|
npm run build
|
|
|
|
# Sync with iOS project
|
|
npx cap sync ios
|
|
|
|
# Build iOS app for simulator
|
|
cd ios/App
|
|
xcodebuild -workspace App.xcworkspace \
|
|
-scheme App \
|
|
-configuration Debug \
|
|
-sdk iphonesimulator \
|
|
-destination 'platform=iOS Simulator,name=iPhone 15 Pro' \
|
|
-derivedDataPath build/derivedData \
|
|
CODE_SIGN_IDENTITY="" \
|
|
CODE_SIGNING_REQUIRED=NO \
|
|
CODE_SIGNING_ALLOWED=NO
|
|
```
|
|
|
|
#### 6. Install App on Simulator
|
|
|
|
```bash
|
|
# Find the built app
|
|
APP_PATH=$(find build/derivedData -name "*.app" -type d -path "*/Build/Products/*-iphonesimulator/*.app" | head -1)
|
|
|
|
# Install app on simulator
|
|
xcrun simctl install booted "$APP_PATH"
|
|
```
|
|
|
|
#### 7. Launch the App
|
|
|
|
```bash
|
|
# Get bundle identifier
|
|
BUNDLE_ID=$(plutil -extract CFBundleIdentifier raw App/Info.plist)
|
|
|
|
# Launch the app
|
|
xcrun simctl launch booted "$BUNDLE_ID"
|
|
|
|
# Example:
|
|
# xcrun simctl launch booted com.timesafari.dailynotification.test
|
|
```
|
|
|
|
### Complete Command Sequence for Vue 3 Test App
|
|
|
|
```bash
|
|
# 1. Boot simulator
|
|
xcrun simctl boot "iPhone 15 Pro" || open -a Simulator
|
|
|
|
# 2. Build plugin
|
|
cd /path/to/daily-notification-plugin
|
|
./scripts/build-native.sh --platform ios
|
|
|
|
# 3. Set up Vue 3 test app
|
|
cd test-apps/daily-notification-test
|
|
npm install
|
|
npm run build
|
|
|
|
# 4. Sync with iOS
|
|
npx cap sync ios
|
|
|
|
# 5. Build iOS app
|
|
cd ios/App
|
|
xcodebuild -workspace App.xcworkspace \
|
|
-scheme App \
|
|
-configuration Debug \
|
|
-sdk iphonesimulator \
|
|
-destination 'platform=iOS Simulator,name=iPhone 15 Pro' \
|
|
CODE_SIGN_IDENTITY="" \
|
|
CODE_SIGNING_REQUIRED=NO \
|
|
CODE_SIGNING_ALLOWED=NO
|
|
|
|
# 6. Install app
|
|
APP_PATH=$(find build/derivedData -name "*.app" -type d | head -1)
|
|
xcrun simctl install booted "$APP_PATH"
|
|
|
|
# 7. Launch app
|
|
BUNDLE_ID=$(plutil -extract CFBundleIdentifier raw App/Info.plist)
|
|
xcrun simctl launch booted "$BUNDLE_ID"
|
|
```
|
|
|
|
---
|
|
|
|
## Alternative Methods
|
|
|
|
### Method 1: Using Capacitor CLI (Vue 3 Test App Only)
|
|
|
|
```bash
|
|
cd test-apps/daily-notification-test
|
|
|
|
# Build and run in one command
|
|
npx cap run ios
|
|
|
|
# This will:
|
|
# - Build the plugin
|
|
# - Sync web assets
|
|
# - Build and install app
|
|
# - Launch in simulator
|
|
```
|
|
|
|
**Note**: This method only works for the Vue 3 test app, not the native iOS development app.
|
|
|
|
### Method 2: Using Automated Scripts
|
|
|
|
#### For Native iOS App (`ios/App`)
|
|
|
|
Create `scripts/build-and-deploy-native-ios.sh`:
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
set -e
|
|
|
|
echo "🔨 Building plugin..."
|
|
cd /path/to/daily-notification-plugin
|
|
./scripts/build-native.sh --platform ios
|
|
|
|
echo "📱 Booting simulator..."
|
|
xcrun simctl boot "iPhone 15 Pro" 2>/dev/null || open -a Simulator
|
|
|
|
echo "🏗️ Building native iOS app..."
|
|
cd ios
|
|
pod install
|
|
cd App
|
|
xcodebuild -workspace App.xcworkspace \
|
|
-scheme App \
|
|
-configuration Debug \
|
|
-sdk iphonesimulator \
|
|
-destination 'platform=iOS Simulator,name=iPhone 15 Pro' \
|
|
CODE_SIGN_IDENTITY="" \
|
|
CODE_SIGNING_REQUIRED=NO \
|
|
CODE_SIGNING_ALLOWED=NO
|
|
|
|
APP_PATH=$(find build/derivedData -name "*.app" -type d | head -1)
|
|
xcrun simctl install booted "$APP_PATH"
|
|
BUNDLE_ID=$(plutil -extract CFBundleIdentifier raw App/Info.plist)
|
|
xcrun simctl launch booted "$BUNDLE_ID"
|
|
```
|
|
|
|
#### For Vue 3 Test App
|
|
|
|
Use the existing script:
|
|
```bash
|
|
cd test-apps/daily-notification-test
|
|
./scripts/build-and-deploy-ios.sh
|
|
```
|
|
|
|
### Method 3: Manual Xcode Build
|
|
|
|
```bash
|
|
# Open project in Xcode
|
|
open ios/App/App.xcworkspace # For native app
|
|
# OR
|
|
open test-apps/daily-notification-test/ios/App/App.xcworkspace # For Vue 3 app
|
|
|
|
# Then:
|
|
# 1. Select simulator target
|
|
# 2. Click Run button (⌘R)
|
|
# 3. App builds and launches automatically
|
|
```
|
|
|
|
---
|
|
|
|
## Simulator Management
|
|
|
|
### List Available Devices
|
|
|
|
```bash
|
|
# List all devices
|
|
xcrun simctl list devices
|
|
|
|
# List only available devices
|
|
xcrun simctl list devices available
|
|
|
|
# List booted devices
|
|
xcrun simctl list devices | grep Booted
|
|
```
|
|
|
|
### Shutdown Simulator
|
|
|
|
```bash
|
|
# Shutdown specific device
|
|
xcrun simctl shutdown "iPhone 15 Pro"
|
|
|
|
# Shutdown all devices
|
|
xcrun simctl shutdown all
|
|
```
|
|
|
|
### Reset Simulator
|
|
|
|
```bash
|
|
# Erase all content and settings
|
|
xcrun simctl erase "iPhone 15 Pro"
|
|
|
|
# Reset and boot
|
|
xcrun simctl erase "iPhone 15 Pro" && xcrun simctl boot "iPhone 15 Pro"
|
|
```
|
|
|
|
### Delete App from Simulator
|
|
|
|
```bash
|
|
# Uninstall app (replace with correct bundle ID)
|
|
xcrun simctl uninstall booted com.timesafari.dailynotification
|
|
# OR for Vue 3 test app:
|
|
xcrun simctl uninstall booted com.timesafari.dailynotification.test
|
|
|
|
# Or reset entire simulator
|
|
xcrun simctl erase booted
|
|
```
|
|
|
|
---
|
|
|
|
## Comparison: Native iOS App vs Vue 3 Test App
|
|
|
|
| Feature | Native iOS App (`ios/App`) | Vue 3 Test App (`test-apps/...`) |
|
|
|---------|---------------------------|----------------------------------|
|
|
| **Purpose** | Quick plugin development testing | Comprehensive testing with UI |
|
|
| **Frontend** | Simple HTML/Capacitor | Vue 3 with full UI |
|
|
| **Build Steps** | Plugin + iOS build | Plugin + Vue build + iOS build |
|
|
| **Capacitor Sync** | Not required | Required (`npx cap sync ios`) |
|
|
| **Best For** | Quick native testing | Full integration testing |
|
|
| **Bundle ID** | `com.timesafari.dailynotification` | `com.timesafari.dailynotification.test` |
|
|
|
|
---
|
|
|
|
## Comparison with Android
|
|
|
|
| Task | Android Native App | iOS Native App | Vue 3 Test App (iOS) |
|
|
|------|-------------------|----------------|---------------------|
|
|
| List devices | `emulator -list-avds` | `xcrun simctl list devices` | `xcrun simctl list devices` |
|
|
| Boot device | `emulator -avd <name>` | `xcrun simctl boot <name>` | `xcrun simctl boot <name>` |
|
|
| Install app | `adb install <apk>` | `xcrun simctl install booted <app>` | `xcrun simctl install booted <app>` |
|
|
| Launch app | `adb shell am start` | `xcrun simctl launch booted <bundle>` | `xcrun simctl launch booted <bundle>` |
|
|
| View logs | `adb logcat` | `xcrun simctl spawn booted log stream` | `xcrun simctl spawn booted log stream` |
|
|
| Build command | `./gradlew assembleDebug` | `xcodebuild -workspace ...` | `xcodebuild -workspace ...` |
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Simulator Won't Boot
|
|
|
|
```bash
|
|
# Check Xcode command line tools
|
|
xcode-select -p
|
|
|
|
# Reinstall command line tools
|
|
sudo xcode-select --reset
|
|
|
|
# Verify simulator runtime
|
|
xcrun simctl runtime list
|
|
```
|
|
|
|
### Build Fails
|
|
|
|
```bash
|
|
# Clean build folder
|
|
cd ios/App # or ios/App for Vue 3 app
|
|
xcodebuild clean -workspace App.xcworkspace -scheme App
|
|
|
|
# Reinstall CocoaPods dependencies
|
|
cd ../.. # Back to ios/ directory
|
|
pod install --repo-update
|
|
|
|
# Rebuild
|
|
cd App
|
|
xcodebuild -workspace App.xcworkspace -scheme App -configuration Debug
|
|
```
|
|
|
|
### App Won't Install
|
|
|
|
```bash
|
|
# Check if simulator is booted
|
|
xcrun simctl list devices | grep Booted
|
|
|
|
# Verify app path exists
|
|
ls -la ios/App/build/derivedData/Build/Products/Debug-iphonesimulator/
|
|
|
|
# Check bundle identifier
|
|
plutil -extract CFBundleIdentifier raw ios/App/App/Info.plist
|
|
```
|
|
|
|
### Vue 3 App: Web Assets Not Syncing
|
|
|
|
```bash
|
|
# Rebuild web assets
|
|
cd test-apps/daily-notification-test
|
|
npm run build
|
|
|
|
# Force sync
|
|
npx cap sync ios --force
|
|
|
|
# Verify assets are synced
|
|
ls -la ios/App/App/public/
|
|
```
|
|
|
|
### Logs Not Showing
|
|
|
|
```bash
|
|
# Use Console.app for better log viewing
|
|
open -a Console
|
|
|
|
# Or use log command with filters
|
|
log stream --predicate 'processImagePath contains "App"' --level debug --style compact
|
|
```
|
|
|
|
---
|
|
|
|
## Additional Resources
|
|
|
|
- [Capacitor iOS Documentation](https://capacitorjs.com/docs/ios)
|
|
- [Xcode Command Line Tools](https://developer.apple.com/xcode/resources/)
|
|
- [Simulator Documentation](https://developer.apple.com/documentation/xcode/running-your-app-in-the-simulator-or-on-a-device)
|
|
|
|
---
|
|
|
|
**Note**: iOS development requires macOS. This guide assumes you're running on a Mac with Xcode installed.
|
|
|
|
**Key Distinction**:
|
|
- **`ios/App`** = Native iOS development app (simple, for quick testing)
|
|
- **`test-apps/daily-notification-test`** = Vue 3 test app (full-featured, for comprehensive testing)
|
|
|