diff --git a/test-apps/ios-test-app/SETUP.md b/test-apps/ios-test-app/SETUP.md index 9672692..43842fd 100644 --- a/test-apps/ios-test-app/SETUP.md +++ b/test-apps/ios-test-app/SETUP.md @@ -1,22 +1,50 @@ # iOS Test App Setup Guide **Author**: Matthew Raymer -**Date**: 2025-11-04 +**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. +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. -## Option 1: Use Capacitor CLI (Recommended) +## Prerequisites -### Step 1: Generate iOS App +- 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 ``` -### Step 2: Configure Plugin +Then follow the configuration steps below. + +## Configuration + +### Step 1: Podfile Configuration Edit `App/Podfile`: @@ -24,6 +52,8 @@ Edit `App/Podfile`: 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' @@ -35,18 +65,17 @@ target 'App' do end ``` -### Step 3: Install Dependencies +### Step 2: Install CocoaPods Dependencies ```bash -cd App -pod install +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 ``` -### Step 4: Copy Test Interface +**Note**: If `pod` command is not found, use the full path: `~/.rbenv/shims/pod` or ensure CocoaPods is in your PATH. -Copy the test HTML from `test-apps/android-test-app/app/src/main/assets/public/index.html` to `App/App/public/index.html`. - -### Step 5: Configure Capacitor +### Step 3: Capacitor Configuration Edit `App/App/capacitor.config.json`: @@ -55,51 +84,106 @@ Edit `App/App/capacitor.config.json`: "appId": "com.timesafari.dailynotification", "appName": "DailyNotification Test App", "webDir": "public", + "server": { + "iosScheme": "capacitor" + }, "plugins": { "DailyNotification": { - "debugMode": true, - "enableNotifications": true + "fetchUrl": "https://api.example.com/daily-content", + "scheduleTime": "09:00", + "enableNotifications": true, + "debugMode": true } } } ``` -## Option 2: Copy from ios/App (Quick Start) +### Step 4: Info.plist Configuration -If `ios/App` already exists, you can copy it: +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 -r ios/App test-apps/ios-test-app/App -cd test-apps/ios-test-app/App -pod install +cp test-apps/android-test-app/app/src/main/assets/public/index.html \ + test-apps/ios-test-app/App/App/public/index.html ``` -Then update: -- `App/Info.plist` - Bundle ID: `com.timesafari.dailynotification` -- `App/capacitor.config.json` - App ID and name -- `App/public/index.html` - Copy test interface from Android test app +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 +### Using Xcode (Recommended for Development) ```bash cd test-apps/ios-test-app/App open App.xcworkspace -# Then build and run in Xcode +# 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 15 Pro' \ + -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 @@ -111,46 +195,251 @@ cd test-apps/ios-test-app ## Plugin Registration -The plugin is automatically registered via Capacitor when included in `Podfile`. No manual registration needed. +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`) -## Test Interface +Capacitor automatically discovers and registers plugins from CocoaPods. -The test interface (`App/App/public/index.html`) provides buttons for: +## Test Interface Features -- Plugin availability testing -- Configuration -- Status checking -- Notification scheduling -- Permission management +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) ## Troubleshooting ### Plugin Not Found -Ensure plugin is built: -```bash -./scripts/build-native.sh --platform ios -``` +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 -```bash -cd test-apps/ios-test-app/App -pod deintegrate -pod install -``` +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 in Xcode (⌘⇧K) -2. Delete derived data: `rm -rf ~/Library/Developer/Xcode/DerivedData` -3. Rebuild +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: `./scripts/build-native.sh --platform ios` -2. Generate or copy iOS app structure -3. Install CocoaPods dependencies -4. Build and run in Xcode or simulator -5. Test plugin functionality +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