feat(ios): add iOS deployment support and web assets parity
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
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
# iOS Build Process Quick Reference
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: November 4, 2025
|
||||
|
||||
## Two Different Test Apps
|
||||
|
||||
**Important**: There are two different iOS test apps:
|
||||
|
||||
1. **Native iOS Development App** (`ios/App`) - Simple Capacitor app for quick plugin testing
|
||||
2. **Vue 3 Test App** (`test-apps/daily-notification-test`) - Full-featured Vue 3 Capacitor app
|
||||
|
||||
---
|
||||
|
||||
## Vue 3 Test App (`test-apps/daily-notification-test`)
|
||||
|
||||
### 🚨 Critical Build Steps
|
||||
|
||||
```bash
|
||||
# 1. Build web assets
|
||||
npm run build
|
||||
|
||||
# 2. Sync with iOS project
|
||||
npx cap sync ios
|
||||
|
||||
# 3. 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
|
||||
|
||||
# 4. Install and launch
|
||||
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"
|
||||
```
|
||||
|
||||
### 🔄 Using Capacitor CLI (Simplest Method)
|
||||
|
||||
```bash
|
||||
cd test-apps/daily-notification-test
|
||||
|
||||
# Build and run in one command
|
||||
npx cap run ios
|
||||
|
||||
# This handles:
|
||||
# - Building web assets
|
||||
# - Syncing with iOS
|
||||
# - Building app
|
||||
# - Installing on simulator
|
||||
# - Launching app
|
||||
```
|
||||
|
||||
### 🛠️ Automated Build Script
|
||||
|
||||
```bash
|
||||
cd test-apps/daily-notification-test
|
||||
./scripts/build-and-deploy-ios.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Native iOS Development App (`ios/App`)
|
||||
|
||||
### 🚨 Critical Build Steps
|
||||
|
||||
```bash
|
||||
# 1. Build plugin
|
||||
cd /path/to/daily-notification-plugin
|
||||
./scripts/build-native.sh --platform ios
|
||||
|
||||
# 2. Install CocoaPods dependencies
|
||||
cd ios
|
||||
pod install
|
||||
|
||||
# 3. Build iOS app
|
||||
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 and launch
|
||||
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"
|
||||
```
|
||||
|
||||
### 🛠️ Automated Build Script
|
||||
|
||||
```bash
|
||||
cd /path/to/daily-notification-plugin
|
||||
./scripts/build-and-deploy-native-ios.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ iOS-Specific Requirements
|
||||
|
||||
**Prerequisites:**
|
||||
- macOS (required for iOS development)
|
||||
- Xcode installed (`xcode-select --install`)
|
||||
- CocoaPods installed (`gem install cocoapods`)
|
||||
- iOS Simulator runtime installed
|
||||
|
||||
**Common Issues:**
|
||||
- Simulator not booted: `xcrun simctl boot "iPhone 15 Pro"`
|
||||
- CocoaPods not installed: `sudo gem install cocoapods`
|
||||
- Platform components missing: `xcodebuild -downloadPlatform iOS`
|
||||
|
||||
## 🔍 Verification Checklist
|
||||
|
||||
After build, verify:
|
||||
|
||||
### For Vue 3 Test App:
|
||||
- [ ] Simulator is booted (`xcrun simctl list devices | grep Booted`)
|
||||
- [ ] CocoaPods dependencies installed (`cd ios && pod install`)
|
||||
- [ ] Web assets synced (`npx cap sync ios`)
|
||||
- [ ] App builds successfully (`xcodebuild ...`)
|
||||
- [ ] App installs on simulator (`xcrun simctl install`)
|
||||
- [ ] App launches (`xcrun simctl launch`)
|
||||
|
||||
### For Native iOS App:
|
||||
- [ ] Simulator is booted (`xcrun simctl list devices | grep Booted`)
|
||||
- [ ] Plugin built (`./scripts/build-native.sh --platform ios`)
|
||||
- [ ] CocoaPods dependencies installed (`cd ios && pod install`)
|
||||
- [ ] App builds successfully (`xcodebuild ...`)
|
||||
- [ ] App installs on simulator (`xcrun simctl install`)
|
||||
- [ ] App launches (`xcrun simctl launch`)
|
||||
|
||||
## 📱 Testing Commands
|
||||
|
||||
```bash
|
||||
# List available simulators
|
||||
xcrun simctl list devices available
|
||||
|
||||
# Boot simulator
|
||||
xcrun simctl boot "iPhone 15 Pro"
|
||||
|
||||
# Check if booted
|
||||
xcrun simctl list devices | grep Booted
|
||||
|
||||
# View logs
|
||||
xcrun simctl spawn booted log stream
|
||||
|
||||
# Uninstall app
|
||||
xcrun simctl uninstall booted com.timesafari.dailynotification.test # Vue 3 app
|
||||
xcrun simctl uninstall booted com.timesafari.dailynotification # Native app
|
||||
|
||||
# Reset simulator
|
||||
xcrun simctl erase booted
|
||||
```
|
||||
|
||||
## 🐛 Common Issues
|
||||
|
||||
| Issue | Symptom | Solution |
|
||||
|-------|---------|----------|
|
||||
| Simulator not found | `Unable to find destination` | Run `xcrun simctl list devices` to see available devices |
|
||||
| CocoaPods error | `pod: command not found` | Install CocoaPods: `gem install cocoapods` |
|
||||
| Build fails | `No such file or directory` | Run `pod install` in `ios/` directory |
|
||||
| Signing error | `Code signing required` | Add `CODE_SIGNING_REQUIRED=NO` to xcodebuild command |
|
||||
| App won't install | `Could not find application` | Verify app path exists and simulator is booted |
|
||||
| Vue app: assets not syncing | App shows blank screen | Run `npm run build && npx cap sync ios` |
|
||||
|
||||
---
|
||||
|
||||
**Remember**:
|
||||
- **Native iOS App** (`ios/App`) = Quick plugin testing, no web build needed
|
||||
- **Vue 3 Test App** (`test-apps/...`) = Full testing with UI, requires `npm run build`
|
||||
|
||||
Use `npx cap run ios` in the Vue 3 test app directory for the simplest workflow!
|
||||
|
||||
150
test-apps/daily-notification-test/scripts/build-and-deploy-ios.sh
Executable file
150
test-apps/daily-notification-test/scripts/build-and-deploy-ios.sh
Executable file
@@ -0,0 +1,150 @@
|
||||
#!/bin/bash
|
||||
# iOS Test App Build and Deploy Script
|
||||
# Builds and deploys the DailyNotification test app to iOS Simulator
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
log_step() {
|
||||
echo -e "${BLUE}[STEP]${NC} $1"
|
||||
}
|
||||
|
||||
# Check if we're in the test app directory
|
||||
if [ ! -f "package.json" ] || [ ! -d "ios" ]; then
|
||||
log_error "This script must be run from test-apps/daily-notification-test directory"
|
||||
log_info "Usage: cd test-apps/daily-notification-test && ./scripts/build-and-deploy-ios.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check prerequisites
|
||||
log_step "Checking prerequisites..."
|
||||
|
||||
if ! command -v xcodebuild &> /dev/null; then
|
||||
log_error "xcodebuild not found. Install Xcode command line tools:"
|
||||
log_info " xcode-select --install"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v pod &> /dev/null; then
|
||||
log_error "CocoaPods not found. Install with:"
|
||||
log_info " gem install cocoapods"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get simulator device (default to iPhone 15 Pro)
|
||||
SIMULATOR_DEVICE="${1:-iPhone 15 Pro}"
|
||||
log_info "Using simulator: $SIMULATOR_DEVICE"
|
||||
|
||||
# Boot simulator
|
||||
log_step "Booting simulator..."
|
||||
if xcrun simctl list devices | grep -q "$SIMULATOR_DEVICE.*Booted"; then
|
||||
log_info "Simulator already booted"
|
||||
else
|
||||
# Try to boot the device
|
||||
if xcrun simctl boot "$SIMULATOR_DEVICE" 2>/dev/null; then
|
||||
log_info "✓ Simulator booted"
|
||||
else
|
||||
log_warn "Could not boot simulator automatically"
|
||||
log_info "Opening Simulator app... (you may need to select device manually)"
|
||||
open -a Simulator
|
||||
sleep 5
|
||||
fi
|
||||
fi
|
||||
|
||||
# Build web assets
|
||||
log_step "Building web assets..."
|
||||
npm run build
|
||||
|
||||
# Sync with iOS
|
||||
log_step "Syncing with iOS project..."
|
||||
if ! npx cap sync ios; then
|
||||
log_error "Failed to sync with iOS project"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install CocoaPods dependencies
|
||||
log_step "Installing CocoaPods dependencies..."
|
||||
cd ios/App
|
||||
if [ ! -f "Podfile.lock" ] || [ "Podfile" -nt "Podfile.lock" ]; then
|
||||
pod install
|
||||
else
|
||||
log_info "CocoaPods dependencies up to date"
|
||||
fi
|
||||
|
||||
# Build iOS app
|
||||
log_step "Building iOS app..."
|
||||
WORKSPACE="App.xcworkspace"
|
||||
SCHEME="App"
|
||||
CONFIG="Debug"
|
||||
SDK="iphonesimulator"
|
||||
|
||||
xcodebuild -workspace "$WORKSPACE" \
|
||||
-scheme "$SCHEME" \
|
||||
-configuration "$CONFIG" \
|
||||
-sdk "$SDK" \
|
||||
-destination "platform=iOS Simulator,name=$SIMULATOR_DEVICE" \
|
||||
-derivedDataPath build/derivedData \
|
||||
CODE_SIGN_IDENTITY="" \
|
||||
CODE_SIGNING_REQUIRED=NO \
|
||||
CODE_SIGNING_ALLOWED=NO \
|
||||
clean build
|
||||
|
||||
# Find built app
|
||||
APP_PATH=$(find build/derivedData -name "*.app" -type d -path "*/Build/Products/*-iphonesimulator/*.app" | head -1)
|
||||
|
||||
if [ -z "$APP_PATH" ]; then
|
||||
log_error "Could not find built app"
|
||||
log_info "Searching in: build/derivedData"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Found app: $APP_PATH"
|
||||
|
||||
# Install app on simulator
|
||||
log_step "Installing app on simulator..."
|
||||
if xcrun simctl install booted "$APP_PATH"; then
|
||||
log_info "✓ App installed"
|
||||
else
|
||||
log_error "Failed to install app"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get bundle identifier
|
||||
BUNDLE_ID=$(plutil -extract CFBundleIdentifier raw App/Info.plist 2>/dev/null || echo "com.timesafari.dailynotification.test")
|
||||
log_info "Bundle ID: $BUNDLE_ID"
|
||||
|
||||
# Launch app
|
||||
log_step "Launching app..."
|
||||
if xcrun simctl launch booted "$BUNDLE_ID"; then
|
||||
log_info "✓ App launched"
|
||||
else
|
||||
log_warn "App may already be running"
|
||||
fi
|
||||
|
||||
log_info ""
|
||||
log_info "✅ Build and deploy complete!"
|
||||
log_info ""
|
||||
log_info "To view logs:"
|
||||
log_info " xcrun simctl spawn booted log stream"
|
||||
log_info ""
|
||||
log_info "To uninstall app:"
|
||||
log_info " xcrun simctl uninstall booted $BUNDLE_ID"
|
||||
|
||||
Reference in New Issue
Block a user