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.
 
 
 
 
 
 

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:

  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

# 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)