13 KiB
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:
- Native iOS Development App (
ios/App) - Simple Capacitor app for plugin development - 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
# 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
# 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
# Open Simulator app (allows visual interaction)
open -a Simulator
3. Build the Plugin
# 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
# 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
# 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
# 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
# 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
# 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
# List available iOS simulators
xcrun simctl list devices available
2. Boot a Simulator
# Boot a specific simulator device
xcrun simctl boot "iPhone 15 Pro"
# Or open Simulator UI
open -a Simulator
3. Build the Plugin
# 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
# 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
# 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
# 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
# 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
# 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)
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:
#!/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:
cd test-apps/daily-notification-test
./scripts/build-and-deploy-ios.sh
Method 3: Manual Xcode Build
# 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
# 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
# Shutdown specific device
xcrun simctl shutdown "iPhone 15 Pro"
# Shutdown all devices
xcrun simctl shutdown all
Reset Simulator
# 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
# 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
# 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
# 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
# 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
# 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
# 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
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)