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:
161
scripts/build-and-deploy-native-ios.sh
Executable file
161
scripts/build-and-deploy-native-ios.sh
Executable file
@@ -0,0 +1,161 @@
|
||||
#!/bin/bash
|
||||
# Native iOS Development App Build and Deploy Script
|
||||
# Builds and deploys the ios/App development app to iOS Simulator
|
||||
# Similar to android/app - a simple Capacitor app for plugin development
|
||||
|
||||
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"
|
||||
}
|
||||
|
||||
# Get script directory
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
|
||||
# Check if we're in the project root
|
||||
if [ ! -d "$PROJECT_ROOT/ios/App" ]; then
|
||||
log_error "ios/App directory not found"
|
||||
log_info "This script must be run from the project root directory"
|
||||
log_info "Usage: cd /path/to/daily-notification-plugin && ./scripts/build-and-deploy-native-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 plugin
|
||||
log_step "Building plugin..."
|
||||
cd "$PROJECT_ROOT"
|
||||
if ! ./scripts/build-native.sh --platform ios; then
|
||||
log_error "Plugin build failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install CocoaPods dependencies
|
||||
log_step "Installing CocoaPods dependencies..."
|
||||
cd "$PROJECT_ROOT/ios"
|
||||
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 native iOS development app..."
|
||||
cd "$PROJECT_ROOT/ios/App"
|
||||
WORKSPACE="App.xcworkspace"
|
||||
SCHEME="App"
|
||||
CONFIG="Debug"
|
||||
SDK="iphonesimulator"
|
||||
|
||||
if ! 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; then
|
||||
log_error "iOS app build failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 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"
|
||||
find build/derivedData -name "*.app" -type d 2>/dev/null | head -5
|
||||
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")
|
||||
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"
|
||||
log_info ""
|
||||
log_info "Note: This is the native iOS development app (ios/App)"
|
||||
log_info "For the Vue 3 test app, use: test-apps/daily-notification-test/scripts/build-and-deploy-ios.sh"
|
||||
|
||||
@@ -7,6 +7,7 @@ set -e
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Logging functions
|
||||
@@ -22,6 +23,10 @@ log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
log_step() {
|
||||
echo -e "${BLUE}[STEP]${NC} $1"
|
||||
}
|
||||
|
||||
# Validation functions
|
||||
check_command() {
|
||||
if ! command -v $1 &> /dev/null; then
|
||||
@@ -31,9 +36,68 @@ check_command() {
|
||||
}
|
||||
|
||||
check_environment() {
|
||||
# Check for required tools
|
||||
local platform=$1
|
||||
|
||||
# Initialize NVM if available (for Node.js version management)
|
||||
if [ -s "$HOME/.nvm/nvm.sh" ]; then
|
||||
log_info "Loading NVM..."
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
|
||||
[ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion"
|
||||
|
||||
# Use default Node.js version if available
|
||||
if [ -f "$NVM_DIR/alias/default" ]; then
|
||||
DEFAULT_NODE=$(cat "$NVM_DIR/alias/default")
|
||||
if [ -n "$DEFAULT_NODE" ]; then
|
||||
nvm use default >/dev/null 2>&1 || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Use latest LTS if no default
|
||||
if ! command -v node &> /dev/null; then
|
||||
log_info "No default Node.js version set, using latest LTS..."
|
||||
nvm use --lts >/dev/null 2>&1 || nvm install --lts >/dev/null 2>&1 || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Common checks
|
||||
check_command "node"
|
||||
check_command "npm"
|
||||
|
||||
# Check Node.js version
|
||||
NODE_VERSION=$(node -v | cut -d. -f1 | tr -d 'v')
|
||||
if [ -z "$NODE_VERSION" ] || ! [[ "$NODE_VERSION" =~ ^[0-9]+$ ]]; then
|
||||
log_error "Could not determine Node.js version"
|
||||
log_error "Please install Node.js: nvm install --lts (if using NVM)"
|
||||
exit 1
|
||||
fi
|
||||
if [ "$NODE_VERSION" -lt 14 ]; then
|
||||
log_error "Node.js version 14 or higher is required (found: $NODE_VERSION)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Platform-specific checks
|
||||
case $platform in
|
||||
"android")
|
||||
check_environment_android
|
||||
;;
|
||||
"ios")
|
||||
check_environment_ios
|
||||
;;
|
||||
"all")
|
||||
check_environment_android
|
||||
check_environment_ios
|
||||
;;
|
||||
*)
|
||||
log_error "Invalid platform: $platform"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
check_environment_android() {
|
||||
log_step "Checking Android environment..."
|
||||
|
||||
check_command "java"
|
||||
|
||||
# Check for Gradle Wrapper instead of system gradle
|
||||
@@ -41,31 +105,98 @@ check_environment() {
|
||||
log_error "Gradle wrapper not found at android/gradlew"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check Node.js version
|
||||
NODE_VERSION=$(node -v | cut -d. -f1 | tr -d 'v')
|
||||
if [ "$NODE_VERSION" -lt 14 ]; then
|
||||
log_error "Node.js version 14 or higher is required"
|
||||
|
||||
# Check Java version (more robust parsing)
|
||||
JAVA_VERSION_OUTPUT=$(java -version 2>&1 | head -n 1)
|
||||
if [ -z "$JAVA_VERSION_OUTPUT" ]; then
|
||||
log_error "Could not determine Java version"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check Java version
|
||||
JAVA_VERSION=$(java -version 2>&1 | head -n 1 | cut -d'"' -f2 | cut -d. -f1)
|
||||
|
||||
# Try multiple parsing methods for different Java output formats
|
||||
JAVA_VERSION=$(echo "$JAVA_VERSION_OUTPUT" | grep -oE 'version "([0-9]+)' | grep -oE '[0-9]+' | head -1)
|
||||
|
||||
# Fallback: try to extract from "openjdk version" or "java version" format
|
||||
if [ -z "$JAVA_VERSION" ]; then
|
||||
JAVA_VERSION=$(echo "$JAVA_VERSION_OUTPUT" | sed -E 's/.*version "([0-9]+).*/\1/' | head -1)
|
||||
fi
|
||||
|
||||
# Validate we got a number
|
||||
if [ -z "$JAVA_VERSION" ] || ! [[ "$JAVA_VERSION" =~ ^[0-9]+$ ]]; then
|
||||
log_error "Could not parse Java version from: $JAVA_VERSION_OUTPUT"
|
||||
log_error "Please ensure Java is installed correctly"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$JAVA_VERSION" -lt 11 ]; then
|
||||
log_error "Java version 11 or higher is required"
|
||||
log_error "Java version 11 or higher is required (found: $JAVA_VERSION)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# Check for Android SDK
|
||||
if [ -z "$ANDROID_HOME" ]; then
|
||||
log_error "ANDROID_HOME environment variable is not set"
|
||||
log_error "Set it with: export ANDROID_HOME=/path/to/android/sdk"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "✓ Android environment OK (Java $JAVA_VERSION)"
|
||||
}
|
||||
|
||||
check_environment_ios() {
|
||||
log_step "Checking iOS environment..."
|
||||
|
||||
# Check for Xcode command line tools
|
||||
if ! command -v xcodebuild &> /dev/null; then
|
||||
log_error "xcodebuild not found. Install Xcode Command Line Tools:"
|
||||
log_error " xcode-select --install"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for CocoaPods
|
||||
if ! command -v pod &> /dev/null; then
|
||||
log_error "CocoaPods not found. Install with:"
|
||||
log_error " sudo gem install cocoapods"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for Swift
|
||||
if ! command -v swift &> /dev/null; then
|
||||
log_error "Swift compiler not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify workspace exists
|
||||
if [ ! -d "ios/DailyNotificationPlugin.xcworkspace" ]; then
|
||||
log_error "iOS workspace not found: ios/DailyNotificationPlugin.xcworkspace"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "✓ iOS environment OK"
|
||||
}
|
||||
|
||||
# Build functions
|
||||
build_typescript() {
|
||||
log_info "Building TypeScript..."
|
||||
|
||||
# Ensure npm dependencies are installed
|
||||
if [ ! -d "node_modules" ]; then
|
||||
log_step "Installing npm dependencies..."
|
||||
if ! npm install; then
|
||||
log_error "Failed to install npm dependencies"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# Check if package.json changed (compare with package-lock.json)
|
||||
if [ -f "package-lock.json" ] && [ "package.json" -nt "package-lock.json" ]; then
|
||||
log_step "package.json changed, updating dependencies..."
|
||||
if ! npm install; then
|
||||
log_error "Failed to update npm dependencies"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
npm run clean
|
||||
if ! npm run build; then
|
||||
log_error "TypeScript build failed"
|
||||
@@ -149,33 +280,6 @@ build_android() {
|
||||
# =============================================================================
|
||||
# AUTOMATIC FIX: capacitor.build.gradle for Plugin Development Projects
|
||||
# =============================================================================
|
||||
#
|
||||
# PROBLEM: The capacitor.build.gradle file is auto-generated by Capacitor CLI
|
||||
# and includes a line that tries to load a file that doesn't exist in plugin
|
||||
# development projects:
|
||||
# apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
|
||||
#
|
||||
# WHY THIS HAPPENS:
|
||||
# - This file is generated by 'npx cap sync', 'npx cap update', etc.
|
||||
# - It assumes a full Capacitor app with proper plugin integration
|
||||
# - Plugin development projects don't have the full Capacitor setup
|
||||
#
|
||||
# THE FIX:
|
||||
# - Comment out the problematic line to prevent build failures
|
||||
# - Add explanatory comment about why it's commented out
|
||||
# - This fix gets applied automatically every time the build script runs
|
||||
#
|
||||
# WHEN THIS FIX GETS OVERWRITTEN:
|
||||
# - Running 'npx cap sync' will regenerate the file and remove our fix
|
||||
# - Running 'npx cap update' will regenerate the file and remove our fix
|
||||
# - Running 'npx cap add android' will regenerate the file and remove our fix
|
||||
#
|
||||
# HOW TO RESTORE THE FIX:
|
||||
# - Run this build script again (it will reapply the fix automatically)
|
||||
# - Or run: ./scripts/fix-capacitor-build.sh
|
||||
# - Or manually comment out the problematic line
|
||||
#
|
||||
# =============================================================================
|
||||
|
||||
if [ -f "app/capacitor.build.gradle" ]; then
|
||||
if grep -q "^apply from: \"../capacitor-cordova-android-plugins/cordova.variables.gradle\"" "app/capacitor.build.gradle"; then
|
||||
@@ -237,6 +341,185 @@ build_android() {
|
||||
cd ..
|
||||
}
|
||||
|
||||
build_ios() {
|
||||
log_info "Building iOS..."
|
||||
|
||||
cd ios || exit 1
|
||||
|
||||
# Build configuration (define early for validation)
|
||||
SCHEME="DailyNotificationPlugin"
|
||||
CONFIG="Release"
|
||||
WORKSPACE="DailyNotificationPlugin.xcworkspace"
|
||||
|
||||
# Install CocoaPods dependencies
|
||||
log_step "Installing CocoaPods dependencies..."
|
||||
if [ ! -f "Podfile.lock" ] || [ "Podfile" -nt "Podfile.lock" ] || [ ! -d "Pods" ] || [ ! -d "Pods/Target Support Files" ]; then
|
||||
log_info "Podfile changed, Podfile.lock missing, or Pods incomplete - running pod install..."
|
||||
if ! pod install --repo-update; then
|
||||
log_error "Failed to install CocoaPods dependencies"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
log_info "Podfile.lock is up to date and Pods directory exists, skipping pod install"
|
||||
fi
|
||||
|
||||
# Quick Swift syntax validation (full validation happens during build)
|
||||
log_step "Validating Swift syntax..."
|
||||
cd Plugin
|
||||
SWIFT_FILES=$(find . -name "*.swift" -type f 2>/dev/null)
|
||||
if [ -z "$SWIFT_FILES" ]; then
|
||||
log_warn "No Swift files found in Plugin directory"
|
||||
else
|
||||
# Use swiftc with iOS SDK for basic syntax check
|
||||
IOS_SDK=$(xcrun --show-sdk-path --sdk iphoneos 2>/dev/null)
|
||||
if [ -n "$IOS_SDK" ]; then
|
||||
for swift_file in $SWIFT_FILES; do
|
||||
# Quick syntax check without full compilation
|
||||
if ! swiftc -sdk "$IOS_SDK" -target arm64-apple-ios16.0 -parse "$swift_file" 2>&1 | grep -q "error:"; then
|
||||
continue
|
||||
else
|
||||
log_warn "Syntax check found issues in $swift_file (will be caught during build)"
|
||||
# Don't exit - let xcodebuild catch real errors
|
||||
fi
|
||||
done
|
||||
else
|
||||
log_warn "Could not find iOS SDK, skipping syntax validation"
|
||||
fi
|
||||
fi
|
||||
cd ..
|
||||
|
||||
# Clean build
|
||||
log_step "Cleaning iOS build..."
|
||||
xcodebuild clean \
|
||||
-workspace "$WORKSPACE" \
|
||||
-scheme "$SCHEME" \
|
||||
-configuration "$CONFIG" \
|
||||
-sdk iphoneos \
|
||||
-destination 'generic/platform=iOS' \
|
||||
-quiet || {
|
||||
log_warn "Clean failed or unnecessary, continuing..."
|
||||
}
|
||||
|
||||
# Check if iOS device platform is available
|
||||
log_step "Checking iOS device platform availability..."
|
||||
BUILD_DEVICE=false
|
||||
|
||||
if xcodebuild -showsdks 2>&1 | grep -q "iOS.*iphoneos"; then
|
||||
IOS_SDK_VERSION=$(xcrun --show-sdk-version --sdk iphoneos 2>&1)
|
||||
log_info "Found iOS SDK: $IOS_SDK_VERSION"
|
||||
|
||||
# Check if platform components are installed by trying a dry-run
|
||||
DRY_RUN_OUTPUT=$(xcodebuild -workspace "$WORKSPACE" \
|
||||
-scheme "$SCHEME" \
|
||||
-destination 'generic/platform=iOS' \
|
||||
-dry-run 2>&1)
|
||||
|
||||
if echo "$DRY_RUN_OUTPUT" | grep -q "iOS.*is not installed"; then
|
||||
log_warn "iOS device platform components not installed"
|
||||
log_info "To install iOS device platform components, run:"
|
||||
log_info " xcodebuild -downloadPlatform iOS"
|
||||
log_info "Or via Xcode: Settings > Components > iOS $IOS_SDK_VERSION"
|
||||
log_info ""
|
||||
log_info "Building for iOS Simulator instead (sufficient for plugin development)"
|
||||
else
|
||||
BUILD_DEVICE=true
|
||||
fi
|
||||
else
|
||||
log_warn "iOS SDK not found"
|
||||
fi
|
||||
|
||||
# Build for device (iOS) if available
|
||||
if [ "$BUILD_DEVICE" = true ]; then
|
||||
log_step "Building for iOS device (arm64)..."
|
||||
BUILD_OUTPUT=$(xcodebuild build \
|
||||
-workspace "$WORKSPACE" \
|
||||
-scheme "$SCHEME" \
|
||||
-configuration "$CONFIG" \
|
||||
-sdk iphoneos \
|
||||
-destination 'generic/platform=iOS' \
|
||||
-derivedDataPath build/derivedData \
|
||||
CODE_SIGN_IDENTITY="" \
|
||||
CODE_SIGNING_REQUIRED=NO \
|
||||
CODE_SIGNING_ALLOWED=NO \
|
||||
2>&1)
|
||||
|
||||
if echo "$BUILD_OUTPUT" | grep -q "error.*iOS.*is not installed"; then
|
||||
log_warn "iOS device build failed - platform components not installed"
|
||||
echo "$BUILD_OUTPUT" > /tmp/xcodebuild_device.log
|
||||
log_info "Check build log: /tmp/xcodebuild_device.log"
|
||||
BUILD_DEVICE=false
|
||||
elif echo "$BUILD_OUTPUT" | grep -q "BUILD SUCCEEDED"; then
|
||||
log_info "✓ iOS device build completed"
|
||||
else
|
||||
log_warn "iOS device build completed with warnings"
|
||||
echo "$BUILD_OUTPUT" > /tmp/xcodebuild_device.log
|
||||
fi
|
||||
fi
|
||||
|
||||
# Build for simulator
|
||||
log_step "Building for iOS simulator..."
|
||||
SIMULATOR_BUILD_OUTPUT=$(xcodebuild build \
|
||||
-workspace "$WORKSPACE" \
|
||||
-scheme "$SCHEME" \
|
||||
-configuration "$CONFIG" \
|
||||
-sdk iphonesimulator \
|
||||
-destination 'generic/platform=iOS Simulator' \
|
||||
-derivedDataPath build/derivedData \
|
||||
CODE_SIGN_IDENTITY="" \
|
||||
CODE_SIGNING_REQUIRED=NO \
|
||||
CODE_SIGNING_ALLOWED=NO \
|
||||
2>&1)
|
||||
|
||||
if echo "$SIMULATOR_BUILD_OUTPUT" | grep -q "BUILD SUCCEEDED"; then
|
||||
log_info "✓ iOS simulator build completed successfully"
|
||||
elif echo "$SIMULATOR_BUILD_OUTPUT" | grep -q "error:"; then
|
||||
log_error "iOS simulator build failed"
|
||||
echo "$SIMULATOR_BUILD_OUTPUT" | grep -E "(error:|warning:)" | head -20
|
||||
exit 1
|
||||
else
|
||||
log_warn "iOS simulator build completed with warnings"
|
||||
echo "$SIMULATOR_BUILD_OUTPUT" | grep -E "(warning:|error:)" | head -10
|
||||
fi
|
||||
|
||||
# Find built frameworks
|
||||
DEVICE_FRAMEWORK=$(find build/derivedData -path "*/Build/Products/*-iphoneos/DailyNotificationPlugin.framework" -type d | head -1)
|
||||
SIMULATOR_FRAMEWORK=$(find build/derivedData -path "*/Build/Products/*-iphonesimulator/DailyNotificationPlugin.framework" -type d | head -1)
|
||||
|
||||
if [ -n "$DEVICE_FRAMEWORK" ]; then
|
||||
log_info "✓ Device framework: $DEVICE_FRAMEWORK"
|
||||
fi
|
||||
|
||||
if [ -n "$SIMULATOR_FRAMEWORK" ]; then
|
||||
log_info "✓ Simulator framework: $SIMULATOR_FRAMEWORK"
|
||||
fi
|
||||
|
||||
# Create universal framework (optional)
|
||||
if [ -n "$DEVICE_FRAMEWORK" ] && [ -n "$SIMULATOR_FRAMEWORK" ]; then
|
||||
log_step "Creating universal framework..."
|
||||
|
||||
UNIVERSAL_DIR="build/universal"
|
||||
mkdir -p "$UNIVERSAL_DIR"
|
||||
|
||||
# Copy device framework
|
||||
cp -R "$DEVICE_FRAMEWORK" "$UNIVERSAL_DIR/"
|
||||
|
||||
# Create universal binary
|
||||
UNIVERSAL_FRAMEWORK="$UNIVERSAL_DIR/DailyNotificationPlugin.framework/DailyNotificationPlugin"
|
||||
if lipo -create \
|
||||
"$DEVICE_FRAMEWORK/DailyNotificationPlugin" \
|
||||
"$SIMULATOR_FRAMEWORK/DailyNotificationPlugin" \
|
||||
-output "$UNIVERSAL_FRAMEWORK" 2>/dev/null; then
|
||||
log_info "✓ Universal framework: $UNIVERSAL_DIR/DailyNotificationPlugin.framework"
|
||||
else
|
||||
log_warn "Universal framework creation failed (may not be needed)"
|
||||
fi
|
||||
fi
|
||||
|
||||
cd ..
|
||||
|
||||
log_info "iOS build completed successfully!"
|
||||
}
|
||||
|
||||
# Main build process
|
||||
main() {
|
||||
log_info "Starting build process..."
|
||||
@@ -249,35 +532,53 @@ main() {
|
||||
BUILD_PLATFORM="$2"
|
||||
shift 2
|
||||
;;
|
||||
--help|-h)
|
||||
echo "Usage: $0 [--platform PLATFORM]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --platform PLATFORM Build platform: 'android', 'ios', or 'all' (default: all)"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 --platform android # Build Android only"
|
||||
echo " $0 --platform ios # Build iOS only"
|
||||
echo " $0 --platform all # Build both platforms"
|
||||
echo " $0 # Build both platforms (default)"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
log_error "Unknown option: $1"
|
||||
log_error "Use --help for usage information"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check environment
|
||||
check_environment
|
||||
|
||||
|
||||
# Check environment (platform-specific)
|
||||
check_environment "$BUILD_PLATFORM"
|
||||
|
||||
# Build TypeScript
|
||||
build_typescript
|
||||
|
||||
|
||||
# Build based on platform
|
||||
case $BUILD_PLATFORM in
|
||||
"android")
|
||||
build_android
|
||||
;;
|
||||
"ios")
|
||||
build_ios
|
||||
;;
|
||||
"all")
|
||||
build_android
|
||||
build_ios
|
||||
;;
|
||||
*)
|
||||
log_error "Invalid platform: $BUILD_PLATFORM. Use 'android' or 'all'"
|
||||
log_error "Invalid platform: $BUILD_PLATFORM. Use 'android', 'ios', or 'all'"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
log_info "Build completed successfully!"
|
||||
}
|
||||
|
||||
# Run main function with all arguments
|
||||
main "$@"
|
||||
main "$@"
|
||||
250
scripts/setup-ruby.sh
Executable file
250
scripts/setup-ruby.sh
Executable file
@@ -0,0 +1,250 @@
|
||||
#!/bin/bash
|
||||
# Ruby Version Manager (rbenv) Setup Script
|
||||
# Installs rbenv and Ruby 3.1+ for CocoaPods compatibility
|
||||
|
||||
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 rbenv is already installed
|
||||
if command -v rbenv &> /dev/null; then
|
||||
log_info "rbenv is already installed"
|
||||
RBENV_INSTALLED=true
|
||||
else
|
||||
log_step "Installing rbenv..."
|
||||
RBENV_INSTALLED=false
|
||||
fi
|
||||
|
||||
# Install rbenv via Homebrew (recommended on macOS)
|
||||
if [ "$RBENV_INSTALLED" = false ]; then
|
||||
if command -v brew &> /dev/null; then
|
||||
log_info "Installing rbenv via Homebrew..."
|
||||
brew install rbenv ruby-build
|
||||
|
||||
# Initialize rbenv in shell
|
||||
if [ -n "$ZSH_VERSION" ]; then
|
||||
SHELL_CONFIG="$HOME/.zshrc"
|
||||
else
|
||||
SHELL_CONFIG="$HOME/.bash_profile"
|
||||
fi
|
||||
|
||||
# Add rbenv initialization to shell config
|
||||
if ! grep -q "rbenv init" "$SHELL_CONFIG" 2>/dev/null; then
|
||||
log_info "Adding rbenv initialization to $SHELL_CONFIG..."
|
||||
echo '' >> "$SHELL_CONFIG"
|
||||
echo '# rbenv initialization' >> "$SHELL_CONFIG"
|
||||
echo 'eval "$(rbenv init - zsh)"' >> "$SHELL_CONFIG"
|
||||
fi
|
||||
|
||||
# Load rbenv in current session
|
||||
eval "$(rbenv init - zsh)"
|
||||
|
||||
log_info "✓ rbenv installed successfully"
|
||||
else
|
||||
log_warn "Homebrew not found. Installing rbenv manually..."
|
||||
|
||||
# Manual installation via git
|
||||
if [ ! -d "$HOME/.rbenv" ]; then
|
||||
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
|
||||
fi
|
||||
|
||||
if [ ! -d "$HOME/.rbenv/plugins/ruby-build" ]; then
|
||||
mkdir -p ~/.rbenv/plugins
|
||||
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
|
||||
fi
|
||||
|
||||
# Add to PATH
|
||||
export PATH="$HOME/.rbenv/bin:$PATH"
|
||||
eval "$(rbenv init - zsh)"
|
||||
|
||||
# Add to shell config
|
||||
if [ -n "$ZSH_VERSION" ]; then
|
||||
SHELL_CONFIG="$HOME/.zshrc"
|
||||
else
|
||||
SHELL_CONFIG="$HOME/.bash_profile"
|
||||
fi
|
||||
|
||||
if ! grep -q "rbenv init" "$SHELL_CONFIG" 2>/dev/null; then
|
||||
echo '' >> "$SHELL_CONFIG"
|
||||
echo '# rbenv initialization' >> "$SHELL_CONFIG"
|
||||
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> "$SHELL_CONFIG"
|
||||
echo 'eval "$(rbenv init - zsh)"' >> "$SHELL_CONFIG"
|
||||
fi
|
||||
|
||||
log_info "✓ rbenv installed manually"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Reload shell config
|
||||
log_step "Reloading shell configuration..."
|
||||
if [ -n "$ZSH_VERSION" ]; then
|
||||
source ~/.zshrc 2>/dev/null || true
|
||||
else
|
||||
source ~/.bash_profile 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Ensure rbenv is in PATH
|
||||
export PATH="$HOME/.rbenv/bin:$PATH"
|
||||
eval "$(rbenv init - zsh)" 2>/dev/null || eval "$(rbenv init - bash)" 2>/dev/null || true
|
||||
|
||||
# Check current Ruby version
|
||||
log_step "Checking current Ruby version..."
|
||||
CURRENT_RUBY=$(ruby -v 2>/dev/null | cut -d' ' -f2 | cut -d. -f1,2) || CURRENT_RUBY="unknown"
|
||||
|
||||
if [ "$CURRENT_RUBY" != "unknown" ]; then
|
||||
RUBY_MAJOR=$(echo "$CURRENT_RUBY" | cut -d. -f1)
|
||||
RUBY_MINOR=$(echo "$CURRENT_RUBY" | cut -d. -f2)
|
||||
|
||||
if [ "$RUBY_MAJOR" -ge 3 ] && [ "$RUBY_MINOR" -ge 1 ]; then
|
||||
log_info "✓ Ruby version $CURRENT_RUBY is already >= 3.1.0"
|
||||
log_info "You can proceed with CocoaPods installation"
|
||||
exit 0
|
||||
else
|
||||
log_warn "Current Ruby version: $CURRENT_RUBY (needs 3.1.0+)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if rbenv has a suitable Ruby version already installed
|
||||
log_step "Checking installed Ruby versions..."
|
||||
if rbenv versions | grep -qE "3\.(1|2|3|4)\."; then
|
||||
INSTALLED_RUBY=$(rbenv versions | grep -E "3\.(1|2|3|4)\." | tail -1 | sed 's/^[[:space:]]*//' | cut -d' ' -f1)
|
||||
log_info "Found installed Ruby version: $INSTALLED_RUBY"
|
||||
|
||||
# Set as global if not already set
|
||||
CURRENT_GLOBAL=$(rbenv global)
|
||||
if [ "$CURRENT_GLOBAL" != "$INSTALLED_RUBY" ]; then
|
||||
log_info "Setting $INSTALLED_RUBY as default..."
|
||||
rbenv global "$INSTALLED_RUBY"
|
||||
rbenv rehash
|
||||
fi
|
||||
|
||||
# Verify it works
|
||||
export PATH="$HOME/.rbenv/bin:$PATH"
|
||||
eval "$(rbenv init - zsh)" 2>/dev/null || eval "$(rbenv init - bash)" 2>/dev/null || true
|
||||
|
||||
if ruby -rpsych -e "true" 2>/dev/null; then
|
||||
VERIFIED_RUBY=$(ruby -v)
|
||||
log_info "✓ Ruby $VERIFIED_RUBY is working correctly"
|
||||
log_info ""
|
||||
log_info "Ruby setup complete!"
|
||||
log_info ""
|
||||
log_info "Next steps:"
|
||||
log_info " 1. Reload your shell: source ~/.zshrc"
|
||||
log_info " 2. Verify Ruby: ruby -v"
|
||||
log_info " 3. Install CocoaPods: gem install cocoapods"
|
||||
exit 0
|
||||
else
|
||||
log_warn "Installed Ruby $INSTALLED_RUBY found but psych extension not working"
|
||||
log_warn "May need to reinstall Ruby or install libyaml dependencies"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for libyaml dependency (required for psych extension)
|
||||
log_step "Checking for libyaml dependency..."
|
||||
LIBYAML_FOUND=false
|
||||
if command -v brew &> /dev/null; then
|
||||
if brew list libyaml &> /dev/null; then
|
||||
LIBYAML_FOUND=true
|
||||
log_info "✓ libyaml found via Homebrew"
|
||||
else
|
||||
log_warn "libyaml not installed. Installing via Homebrew..."
|
||||
if brew install libyaml; then
|
||||
LIBYAML_FOUND=true
|
||||
log_info "✓ libyaml installed successfully"
|
||||
else
|
||||
log_error "Failed to install libyaml via Homebrew"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# Check if libyaml headers exist in system locations
|
||||
if find /usr/local /opt /Library -name "yaml.h" 2>/dev/null | grep -q yaml.h; then
|
||||
LIBYAML_FOUND=true
|
||||
log_info "✓ libyaml headers found in system"
|
||||
else
|
||||
log_warn "libyaml not found. Ruby installation may fail."
|
||||
log_warn "Install libyaml via Homebrew: brew install libyaml"
|
||||
log_warn "Or install via MacPorts: sudo port install libyaml"
|
||||
fi
|
||||
fi
|
||||
|
||||
# List available Ruby versions
|
||||
log_step "Fetching available Ruby versions..."
|
||||
rbenv install --list | grep -E "^[[:space:]]*3\.[1-9]" | tail -5 || log_warn "Could not fetch Ruby versions list"
|
||||
|
||||
# Install Ruby 3.1.0 (preferred for compatibility)
|
||||
log_step "Installing Ruby 3.1.0..."
|
||||
if rbenv install 3.1.0; then
|
||||
log_info "✓ Ruby 3.1.0 installed successfully"
|
||||
|
||||
# Set as global default
|
||||
log_step "Setting Ruby 3.1.0 as default..."
|
||||
rbenv global 3.1.0
|
||||
|
||||
# Verify installation
|
||||
export PATH="$HOME/.rbenv/bin:$PATH"
|
||||
eval "$(rbenv init - zsh)" 2>/dev/null || eval "$(rbenv init - bash)" 2>/dev/null || true
|
||||
|
||||
NEW_RUBY=$(ruby -v)
|
||||
log_info "✓ Current Ruby version: $NEW_RUBY"
|
||||
|
||||
# Verify psych extension works
|
||||
if ruby -rpsych -e "true" 2>/dev/null; then
|
||||
log_info "✓ psych extension verified"
|
||||
else
|
||||
log_warn "psych extension may not be working correctly"
|
||||
log_warn "This may affect CocoaPods installation"
|
||||
fi
|
||||
|
||||
# Rehash to make Ruby available
|
||||
rbenv rehash
|
||||
|
||||
log_info ""
|
||||
log_info "Ruby setup complete!"
|
||||
log_info ""
|
||||
log_info "Next steps:"
|
||||
log_info " 1. Reload your shell: source ~/.zshrc"
|
||||
log_info " 2. Verify Ruby: ruby -v"
|
||||
log_info " 3. Install CocoaPods: gem install cocoapods"
|
||||
|
||||
else
|
||||
log_error "Failed to install Ruby 3.1.0"
|
||||
|
||||
if [ "$LIBYAML_FOUND" = false ]; then
|
||||
log_error ""
|
||||
log_error "Installation failed. This is likely due to missing libyaml dependency."
|
||||
log_error ""
|
||||
log_error "To fix:"
|
||||
if command -v brew &> /dev/null; then
|
||||
log_error " brew install libyaml"
|
||||
else
|
||||
log_error " Install Homebrew: /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""
|
||||
log_error " Then: brew install libyaml"
|
||||
fi
|
||||
log_error ""
|
||||
log_error "After installing libyaml, run this script again."
|
||||
else
|
||||
log_error "Installation failed. Please check your internet connection and try again."
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user