# iOS Test App Setup Guide **Author**: Matthew Raymer **Date**: 2025-11-12 **Status**: Active ## Overview This guide explains how to set up the standalone iOS test app for the DailyNotification plugin. The iOS test app mirrors the Android test app (`android-test-app`) functionality and provides a comprehensive testing environment for all plugin features. ## Prerequisites - macOS with Xcode 15.0 or later - CocoaPods installed (`gem install cocoapods` or via rbenv) - Node.js 18+ (for Capacitor CLI) - iOS 13.0+ deployment target - Ruby 3.1+ (for CocoaPods) ## Quick Start ### Option 1: Use Existing Structure (Recommended) If `ios/App` already exists, copy it: ```bash # From project root cd test-apps/ios-test-app cp -r ../../ios/App ./App cd App export LANG=en_US.UTF-8 ~/.rbenv/shims/pod install # or: pod install if in PATH ``` Then update configuration files (see Configuration section below). ### Option 2: Generate with Capacitor CLI ```bash cd test-apps/ios-test-app npx @capacitor/create-app@latest App --template blank ``` Then follow the configuration steps below. ## Configuration ### Step 1: Podfile Configuration Edit `App/Podfile`: ```ruby platform :ios, '13.0' use_frameworks! source 'https://cdn.cocoapods.org/' def capacitor_pods pod 'Capacitor', :path => '../../../node_modules/@capacitor/ios' pod 'CapacitorCordova', :path => '../../../node_modules/@capacitor/ios' pod 'DailyNotificationPlugin', :path => '../../../ios' end target 'App' do capacitor_pods end ``` ### Step 2: Install CocoaPods Dependencies ```bash cd test-apps/ios-test-app/App export LANG=en_US.UTF-8 # Required for CocoaPods ~/.rbenv/shims/pod install # or: pod install if in PATH ``` **Note**: If `pod` command is not found, use the full path: `~/.rbenv/shims/pod` or ensure CocoaPods is in your PATH. ### Step 3: Capacitor Configuration Edit `App/App/capacitor.config.json`: ```json { "appId": "com.timesafari.dailynotification", "appName": "DailyNotification Test App", "webDir": "public", "server": { "iosScheme": "capacitor" }, "plugins": { "DailyNotification": { "fetchUrl": "https://api.example.com/daily-content", "scheduleTime": "09:00", "enableNotifications": true, "debugMode": true } } } ``` ### Step 4: Info.plist Configuration Edit `App/App/Info.plist` to include required permissions and background modes: ```xml UIBackgroundModes background-fetch background-processing remote-notification BGTaskSchedulerPermittedIdentifiers com.timesafari.dailynotification.fetch com.timesafari.dailynotification.notify NSUserNotificationsUsageDescription This app uses notifications to deliver daily updates and reminders. ``` **Key iOS Permissions** (equivalent to Android): - **Notifications**: `NSUserNotificationsUsageDescription` (like Android's `POST_NOTIFICATIONS`) - **Background Fetch**: `UIBackgroundModes` with `background-fetch` (like Android's WorkManager) - **Background Processing**: `UIBackgroundModes` with `background-processing` - **Exact Alarms**: Always supported on iOS via `UNUserNotificationCenter` (no permission needed) ### Step 5: Copy Test Interface Copy the test HTML from Android test app: ```bash # From project root cp test-apps/android-test-app/app/src/main/assets/public/index.html \ test-apps/ios-test-app/App/App/public/index.html ``` The test interface provides: - Plugin availability testing - Configuration management - Status checking - Notification scheduling - Permission management - Channel/notification settings (iOS: app-level) - Comprehensive status checks ## Build and Run ### Using Xcode (Recommended for Development) ```bash cd test-apps/ios-test-app/App open App.xcworkspace # Then build and run in Xcode (⌘R) ``` **Important**: Always open the `.xcworkspace` file, not the `.xcodeproj` file, when using CocoaPods. ### Using Command Line ```bash cd test-apps/ios-test-app/App export LANG=en_US.UTF-8 # List available simulators xcrun simctl list devices available | grep -i iphone # Build for simulator xcodebuild -workspace App.xcworkspace \ -scheme App \ -configuration Debug \ -sdk iphonesimulator \ -destination 'platform=iOS Simulator,name=iPhone 17 Pro' \ clean build # Build and run on simulator xcodebuild -workspace App.xcworkspace \ -scheme App \ -configuration Debug \ -sdk iphonesimulator \ -destination 'platform=iOS Simulator,name=iPhone 17 Pro' \ build \ && xcrun simctl boot "iPhone 17 Pro" 2>/dev/null || true \ && xcrun simctl install booted "$(xcodebuild -workspace App.xcworkspace -scheme App -configuration Debug -sdk iphonesimulator -showBuildSettings | grep -m 1 "BUILT_PRODUCTS_DIR" | sed 's/.*= *//')/App.app" \ && xcrun simctl launch booted com.timesafari.dailynotification ``` ### Using Build Script ```bash cd test-apps/ios-test-app ./scripts/build-and-deploy.sh ``` ## Plugin Registration The plugin is automatically registered via Capacitor when included in `Podfile`. No manual registration needed in: - `AppDelegate.swift` (Android equivalent: `PluginApplication.java`) - `ViewController.swift` (Android equivalent: `MainActivity.java`) Capacitor automatically discovers and registers plugins from CocoaPods. ## Test Interface Features The test interface (`App/App/public/index.html`) provides comprehensive testing for: ### Basic Plugin Tests - **Test Plugin**: Verify plugin is loaded and accessible - **Configure Plugin**: Set plugin configuration - **Check Status**: Get current plugin status ### Notification Tests - **Test Notification**: Send immediate test notification - **Schedule Notification**: Schedule daily notification - **Show Reminder**: Display reminder notification ### Permission Management - **Check Permissions**: Check notification authorization status - **Request Permissions**: Request notification permissions - **Exact Alarm Settings**: Open notification settings (iOS: app-level settings) ### Channel Management (iOS: App-Level) - **Check Channel Status**: Check if notifications are enabled - **Open Channel Settings**: Open app notification settings - **Comprehensive Status**: Get full status including permissions, schedules, and battery ## iOS-Specific Considerations ### Background Execution iOS handles background execution differently than Android: - **Background Fetch**: Uses `BGTaskScheduler` (similar to Android's WorkManager) - **Background Processing**: Limited time budget (typically 30 seconds) - **Background App Refresh**: User-controlled system setting (cannot be checked programmatically) ### Notification Scheduling - **UNUserNotificationCenter**: Always supports exact alarms (no permission needed) - **Daily Repeats**: Use `UNCalendarNotificationTrigger` with `repeats: true` - **Background Tasks**: Use `BGAppRefreshTask` for prefetch operations ### Permissions - **Notifications**: Single app-level permission (no channels like Android) - **Exact Alarms**: Always supported, no permission needed - **Battery Optimization**: Not applicable (Background App Refresh is system setting) ### Storage - **UserDefaults**: For schedules and configuration (like Android's SharedPreferences) - **Core Data**: For content cache and history (like Android's Room database) ## Code Signing ### Simulator Builds (Default) **No signing required** - The build scripts automatically disable signing for simulator builds: ```bash CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO ``` This is handled automatically by the build scripts. ### Device Builds **For physical devices, you need proper signing:** 1. **Open project in Xcode:** ```bash cd test-apps/ios-test-app/App open App.xcworkspace ``` 2. **Configure signing:** - Select project in navigator - Select target "App" - Go to "Signing & Capabilities" tab - Check "Automatically manage signing" - Select your Team (Apple Developer account) 3. **Build for device:** ```bash xcodebuild -workspace App.xcworkspace \ -scheme App \ -sdk iphoneos \ -configuration Debug \ -destination 'generic/platform=iOS' \ CODE_SIGN_STYLE=Automatic \ DEVELOPMENT_TEAM="YOUR_TEAM_ID" \ clean build ``` **See `docs/IOS_CODE_SIGNING.md` for complete signing guide.** ## Troubleshooting ### Plugin Not Found 1. **Ensure plugin is built**: ```bash cd ../../ios export LANG=en_US.UTF-8 xcodebuild -workspace DailyNotificationPlugin.xcworkspace \ -scheme DailyNotificationPlugin \ -sdk iphonesimulator \ -destination 'generic/platform=iOS Simulator' \ GENERATE_INFOPLIST_FILE=YES \ clean build ``` 2. **Verify Podfile includes plugin**: ```bash grep DailyNotificationPlugin test-apps/ios-test-app/App/Podfile ``` 3. **Check plugin registration**: ```bash # Plugin should be in Pods project ls -la test-apps/ios-test-app/App/Pods/Local\ Podspecs/ ``` ### CocoaPods Issues 1. **Encoding errors**: ```bash export LANG=en_US.UTF-8 ~/.rbenv/shims/pod install ``` 2. **Clean reinstall**: ```bash cd test-apps/ios-test-app/App pod deintegrate rm -rf Pods Podfile.lock pod install ``` 3. **Ruby version issues**: ```bash # Ensure Ruby 3.1+ is available ruby --version # Use rbenv if needed rbenv install 3.1.0 rbenv local 3.1.0 ``` ### Build Errors 1. **Clean build folder**: ```bash # In Xcode: Product > Clean Build Folder (⌘⇧K) # Or command line: xcodebuild clean -workspace App.xcworkspace -scheme App ``` 2. **Delete derived data**: ```bash rm -rf ~/Library/Developer/Xcode/DerivedData ``` 3. **Reset CocoaPods cache**: ```bash pod cache clean --all pod install ``` 4. **Info.plist errors**: - Ensure `GENERATE_INFOPLIST_FILE=YES` is set for framework targets - Verify all required keys are present in `Info.plist` ### Runtime Issues 1. **Notifications not appearing**: - Check notification permissions in iOS Settings - Verify Background App Refresh is enabled - Check console logs for errors 2. **Background tasks not running**: - Background App Refresh must be enabled in iOS Settings - Tasks have limited execution time (typically 30 seconds) - System may delay or skip tasks based on usage patterns 3. **Plugin methods not found**: - Verify plugin is built and included in Pods - Check Capacitor bridge is initialized - Review console logs for registration errors ## Project Structure ``` test-apps/ios-test-app/ ├── App/ │ ├── App/ │ │ ├── AppDelegate.swift # App lifecycle (Android: PluginApplication.java) │ │ ├── ViewController.swift # Main view (Android: MainActivity.java) │ │ ├── SceneDelegate.swift # Scene lifecycle (iOS 13+) │ │ ├── Info.plist # Permissions & config (Android: AndroidManifest.xml) │ │ ├── capacitor.config.json # Capacitor config │ │ └── public/ │ │ └── index.html # Test interface │ ├── App.xcworkspace # Workspace (includes Pods) │ ├── Podfile # CocoaPods dependencies │ └── Podfile.lock # Locked versions ├── scripts/ │ └── build-and-deploy.sh # Build automation ├── README.md # Overview └── SETUP.md # This file ``` ## Dependencies The iOS test app requires: - **Capacitor**: Core framework - **CapacitorCordova**: Cordova compatibility - **DailyNotificationPlugin**: The plugin being tested Additional iOS dependencies (managed by plugin): - **UserNotifications**: Notification scheduling - **BackgroundTasks**: Background execution - **CoreData**: Persistent storage ## Comparison with Android Test App | Feature | Android | iOS | |---------|---------|-----| | **App Entry** | `MainActivity.java` | `ViewController.swift` | | **Lifecycle** | `PluginApplication.java` | `AppDelegate.swift` | | **Manifest** | `AndroidManifest.xml` | `Info.plist` | | **Build System** | Gradle | Xcode + CocoaPods | | **Dependencies** | `build.gradle` | `Podfile` | | **Permissions** | Runtime + Manifest | Info.plist + Runtime | | **Background** | WorkManager | BGTaskScheduler | | **Notifications** | NotificationManager | UNUserNotificationCenter | | **Storage** | Room + SharedPreferences | Core Data + UserDefaults | | **Channels** | Multiple channels | App-level only | ## Next Steps 1. **Build plugin**: ```bash cd ../../ios ./scripts/build-native.sh --platform ios ``` 2. **Set up test app**: ```bash cd test-apps/ios-test-app # Follow Quick Start section above ``` 3. **Install dependencies**: ```bash cd App export LANG=en_US.UTF-8 ~/.rbenv/shims/pod install ``` 4. **Build and run**: ```bash open App.xcworkspace # Build and run in Xcode ``` 5. **Test functionality**: - Use test interface to verify all plugin methods - Test notification scheduling - Verify permissions work correctly - Test background tasks (requires Background App Refresh enabled) ## Additional Resources - [iOS Plugin Implementation Guide](../../docs/IOS_IMPLEMENTATION_COMPLETE.md) - [iOS Build Quick Reference](../../docs/IOS_BUILD_QUICK_REFERENCE.md) - [CocoaPods Installation Guide](../../docs/COCOAPODS_INSTALLATION.md) - [iOS Setup Requirements](../../docs/IOS_SETUP_REQUIREMENTS.md) - [Android Test App](../../android-test-app/) - For comparison ## Support For issues or questions: 1. Check troubleshooting section above 2. Review iOS plugin documentation 3. Compare with Android test app implementation 4. Check Xcode console logs for detailed errors