feat(build): add iOS support to build-native.sh
Adds iOS platform support to the unified build script, enabling building of test-apps/daily-notification-test for iOS alongside existing Android support. Changes: - Add build_plugin_for_test_app_ios() to build iOS test app - Add build_ios() function for iOS platform handling - Make environment checks conditional based on target platform - Add get_pod_command() helper to handle CocoaPods via rbenv - Update main() to accept --platform ios and include iOS in "all" This aligns the script with BUILDING.md documentation (lines 71, 75) which implied iOS support was already available. The iOS build process mirrors Android: creates plugin symlink, builds Vue app, syncs Capacitor iOS (handles Podfile fixes), and builds with xcodebuild for simulator. Platform-specific environment checks allow iOS-only builds without requiring Android toolchain, and vice versa.
This commit is contained in:
@@ -25,22 +25,34 @@ log_error() {
|
||||
# Validation functions
|
||||
check_command() {
|
||||
if ! command -v $1 &> /dev/null; then
|
||||
# Try rbenv shims for pod command
|
||||
if [ "$1" = "pod" ] && [ -f "$HOME/.rbenv/shims/pod" ]; then
|
||||
log_info "Found pod in rbenv shims"
|
||||
return 0
|
||||
fi
|
||||
log_error "$1 is not installed. Please install it first."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_environment() {
|
||||
# Check for required tools
|
||||
check_command "node"
|
||||
check_command "npm"
|
||||
check_command "java"
|
||||
|
||||
# Check for Gradle Wrapper instead of system gradle
|
||||
if [ ! -f "android/gradlew" ]; then
|
||||
log_error "Gradle wrapper not found at android/gradlew"
|
||||
# Get pod command (handles rbenv)
|
||||
get_pod_command() {
|
||||
if command -v pod &> /dev/null; then
|
||||
echo "pod"
|
||||
elif [ -f "$HOME/.rbenv/shims/pod" ]; then
|
||||
echo "$HOME/.rbenv/shims/pod"
|
||||
else
|
||||
log_error "CocoaPods (pod) not found. Please install CocoaPods first."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_environment() {
|
||||
local PLATFORM=$1
|
||||
|
||||
# Check for required tools (always needed)
|
||||
check_command "node"
|
||||
check_command "npm"
|
||||
|
||||
# Check Node.js version
|
||||
NODE_VERSION=$(node -v | cut -d. -f1 | tr -d 'v')
|
||||
@@ -49,17 +61,34 @@ check_environment() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check Java version
|
||||
JAVA_VERSION=$(java -version 2>&1 | head -n 1 | cut -d'"' -f2 | cut -d. -f1)
|
||||
if [ "$JAVA_VERSION" -lt 11 ]; then
|
||||
log_error "Java version 11 or higher is required"
|
||||
exit 1
|
||||
# Platform-specific checks
|
||||
if [ "$PLATFORM" = "android" ] || [ "$PLATFORM" = "all" ]; then
|
||||
check_command "java"
|
||||
|
||||
# Check for Gradle Wrapper instead of system gradle
|
||||
if [ ! -f "android/gradlew" ]; then
|
||||
log_error "Gradle wrapper not found at android/gradlew"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check Java version
|
||||
JAVA_VERSION=$(java -version 2>&1 | head -n 1 | cut -d'"' -f2 | cut -d. -f1)
|
||||
if [ "$JAVA_VERSION" -lt 11 ]; then
|
||||
log_error "Java version 11 or higher is required"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for Android SDK
|
||||
if [ -z "$ANDROID_HOME" ]; then
|
||||
log_error "ANDROID_HOME environment variable is not set"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for Android SDK
|
||||
if [ -z "$ANDROID_HOME" ]; then
|
||||
log_error "ANDROID_HOME environment variable is not set"
|
||||
exit 1
|
||||
if [ "$PLATFORM" = "ios" ] || [ "$PLATFORM" = "all" ]; then
|
||||
# iOS checks are done in build_ios() function
|
||||
# to avoid failing if iOS tools aren't available when building Android only
|
||||
:
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -117,6 +146,113 @@ build_plugin_for_test_app() {
|
||||
cd ../../..
|
||||
}
|
||||
|
||||
build_plugin_for_test_app_ios() {
|
||||
log_info "Building iOS test app..."
|
||||
|
||||
# Ensure symlink is in place FIRST (before building)
|
||||
# The test app expects the plugin at node_modules/@timesafari/daily-notification-plugin
|
||||
SYMLINK="test-apps/daily-notification-test/node_modules/@timesafari/daily-notification-plugin"
|
||||
if [ ! -L "$SYMLINK" ] || [ ! -e "$SYMLINK" ]; then
|
||||
log_info "Creating symlink to plugin..."
|
||||
mkdir -p "$(dirname "$SYMLINK")"
|
||||
rm -f "$SYMLINK"
|
||||
ln -sf "../../../" "$SYMLINK"
|
||||
fi
|
||||
|
||||
# Navigate to test app directory
|
||||
cd test-apps/daily-notification-test || exit 1
|
||||
|
||||
# Build Vue app
|
||||
log_info "Building Vue app..."
|
||||
if ! npm run build; then
|
||||
log_error "Vue app build failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Sync Capacitor iOS (handles Podfile fixes and pod install)
|
||||
log_info "Syncing Capacitor iOS..."
|
||||
if ! npm run cap:sync:ios; then
|
||||
log_error "Capacitor iOS sync failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Build with xcodebuild
|
||||
cd ios/App || exit 1
|
||||
|
||||
# Find workspace
|
||||
if [ -d "App.xcworkspace" ]; then
|
||||
WORKSPACE="App.xcworkspace"
|
||||
SCHEME="App"
|
||||
elif [ -d "App.xcodeproj" ]; then
|
||||
PROJECT="App.xcodeproj"
|
||||
SCHEME="App"
|
||||
else
|
||||
log_error "No Xcode workspace or project found in ios/App"
|
||||
log_info "Expected: App.xcworkspace or App.xcodeproj"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Auto-detect available iPhone simulator
|
||||
log_info "Detecting available iPhone simulator..."
|
||||
SIMULATOR_LINE=$(xcrun simctl list devices available 2>&1 | grep -i "iPhone" | head -1)
|
||||
|
||||
if [ -n "$SIMULATOR_LINE" ]; then
|
||||
# Extract device ID (UUID in parentheses)
|
||||
SIMULATOR_ID=$(echo "$SIMULATOR_LINE" | sed -E 's/.*\(([A-F0-9-]+)\).*/\1/')
|
||||
# Extract device name (everything before the first parenthesis)
|
||||
SIMULATOR_NAME=$(echo "$SIMULATOR_LINE" | sed -E 's/^[[:space:]]*([^(]+).*/\1/' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||
|
||||
if [ -n "$SIMULATOR_ID" ] && [ "$SIMULATOR_ID" != "Shutdown" ] && [ "$SIMULATOR_ID" != "Booted" ]; then
|
||||
DESTINATION="platform=iOS Simulator,id=$SIMULATOR_ID"
|
||||
log_info "Building for iOS Simulator ($SIMULATOR_NAME, ID: $SIMULATOR_ID)..."
|
||||
elif [ -n "$SIMULATOR_NAME" ]; then
|
||||
DESTINATION="platform=iOS Simulator,name=$SIMULATOR_NAME"
|
||||
log_info "Building for iOS Simulator ($SIMULATOR_NAME)..."
|
||||
else
|
||||
DESTINATION="platform=iOS Simulator,name=iPhone 14"
|
||||
log_warn "Using default simulator destination: iPhone 14"
|
||||
fi
|
||||
else
|
||||
DESTINATION="platform=iOS Simulator,name=iPhone 14"
|
||||
log_warn "No iPhone simulators found, using default: iPhone 14"
|
||||
fi
|
||||
|
||||
# Build for simulator
|
||||
log_info "Building iOS app for simulator..."
|
||||
if [ -n "$WORKSPACE" ]; then
|
||||
if ! xcodebuild build \
|
||||
-workspace "$WORKSPACE" \
|
||||
-scheme "$SCHEME" \
|
||||
-configuration Debug \
|
||||
-sdk iphonesimulator \
|
||||
-destination "$DESTINATION" \
|
||||
CODE_SIGN_IDENTITY="" \
|
||||
CODE_SIGNING_REQUIRED=NO \
|
||||
CODE_SIGNING_ALLOWED=NO; then
|
||||
log_error "iOS build failed"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if ! xcodebuild build \
|
||||
-project "$PROJECT" \
|
||||
-scheme "$SCHEME" \
|
||||
-configuration Debug \
|
||||
-sdk iphonesimulator \
|
||||
-destination "$DESTINATION" \
|
||||
CODE_SIGN_IDENTITY="" \
|
||||
CODE_SIGNING_REQUIRED=NO \
|
||||
CODE_SIGNING_ALLOWED=NO; then
|
||||
log_error "iOS build failed"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
log_info "iOS build successful!"
|
||||
log_info "App built in DerivedData. To run: xcrun simctl boot <simulator-id> && xcrun simctl install booted <app-path>"
|
||||
|
||||
cd ../../..
|
||||
}
|
||||
|
||||
build_android() {
|
||||
log_info "Building Android..."
|
||||
|
||||
@@ -225,6 +361,65 @@ build_android() {
|
||||
cd ..
|
||||
}
|
||||
|
||||
build_ios() {
|
||||
log_info "Building iOS..."
|
||||
|
||||
# Check iOS-specific requirements
|
||||
check_command "xcodebuild"
|
||||
check_command "pod"
|
||||
|
||||
# Check for Xcode
|
||||
if ! xcodebuild -version &> /dev/null; then
|
||||
log_error "Xcode is not installed or not properly configured"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Detect project type
|
||||
if [ -d "test-apps/daily-notification-test" ]; then
|
||||
log_info "Detected test app. Building plugin and test app together..."
|
||||
build_plugin_for_test_app_ios
|
||||
return 0
|
||||
fi
|
||||
|
||||
# For plugin-only builds, navigate to iOS directory
|
||||
cd ios || exit 1
|
||||
|
||||
log_warn "This appears to be a plugin development project"
|
||||
log_warn "iOS plugin source code has been built successfully"
|
||||
log_warn "To test the plugin, use it in a Capacitor app instead"
|
||||
|
||||
# Install CocoaPods dependencies if Podfile exists
|
||||
if [ -f "Podfile" ]; then
|
||||
log_info "Installing CocoaPods dependencies..."
|
||||
POD_CMD=$(get_pod_command)
|
||||
if ! $POD_CMD install; then
|
||||
log_error "CocoaPods installation failed"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Build plugin framework (if workspace exists)
|
||||
if [ -d "DailyNotificationPlugin.xcworkspace" ]; then
|
||||
log_info "Building iOS plugin framework..."
|
||||
if ! xcodebuild build \
|
||||
-workspace DailyNotificationPlugin.xcworkspace \
|
||||
-scheme DailyNotificationPlugin \
|
||||
-configuration Release \
|
||||
-sdk iphoneos \
|
||||
CODE_SIGN_IDENTITY="" \
|
||||
CODE_SIGNING_REQUIRED=NO \
|
||||
CODE_SIGNING_ALLOWED=NO; then
|
||||
log_error "iOS plugin build failed"
|
||||
exit 1
|
||||
fi
|
||||
log_info "iOS plugin build successful"
|
||||
else
|
||||
log_warn "No Xcode workspace found - plugin may need to be built in a host app"
|
||||
fi
|
||||
|
||||
cd ..
|
||||
}
|
||||
|
||||
# Main build process
|
||||
main() {
|
||||
log_info "Starting build process..."
|
||||
@@ -244,22 +439,26 @@ main() {
|
||||
esac
|
||||
done
|
||||
|
||||
# Check environment
|
||||
check_environment
|
||||
|
||||
# Build TypeScript
|
||||
# Build TypeScript (needed for all platforms)
|
||||
build_typescript
|
||||
|
||||
# Check environment (after parsing platform so we can check conditionally)
|
||||
check_environment "$BUILD_PLATFORM"
|
||||
|
||||
# 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
|
||||
|
||||
Reference in New Issue
Block a user