Files
daily-notification-plugin/test-apps/ios-test-app/SETUP.md
Matthew Raymer d7fe746b6b feat(ios): add comprehensive requirements checking and improved CocoaPods detection
Enhanced iOS test app setup with better prerequisite handling:

Requirements Checker:
- Created check-requirements.sh script
- Verifies all prerequisites (macOS, Xcode, Ruby, CocoaPods, Node.js)
- Checks Ruby version (requires 3.1+)
- Detects CocoaPods in multiple locations (PATH, rbenv, gem bin)
- Validates UTF-8 encoding
- Provides installation instructions for missing items

Build Script Improvements:
- Enhanced CocoaPods detection (checks PATH, rbenv, gem bin)
- Better error messages with installation options
- Automatic LANG=en_US.UTF-8 export
- Uses detected pod command location

Documentation Updates:
- Expanded prerequisites section with versions
- Added rbenv recommendation
- Added quick requirements check step
- Clearer installation instructions

Fixes:
- Handles rbenv-based CocoaPods installation
- Works with system Ruby, rbenv, or Homebrew
- Provides helpful error messages

Result: Developers can easily verify and install all requirements
2025-11-11 19:36:47 -08:00

14 KiB

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

Required

  • macOS (iOS development requires macOS)
  • Xcode 15.0+ with Command Line Tools
    xcode-select --install  # If not installed
    
  • Ruby 3.1+ (required for CocoaPods)
    • Check version: ruby --version
    • If using system Ruby and version < 3.1, use rbenv (recommended)
  • CocoaPods (dependency manager)
  • Node.js 18+ and npm (for Capacitor CLI)
  • UTF-8 encoding (required for CocoaPods)
  • rbenv (Ruby version manager) - Makes Ruby/CocoaPods setup easier
  • Homebrew (package manager) - Simplifies installation

Quick Requirements Check

Run the requirements checker:

cd test-apps/ios-test-app
./scripts/check-requirements.sh

This will verify all prerequisites and provide installation instructions for missing items.

Quick Start

If ios/App already exists, copy it:

# 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

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:

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

First, check requirements:

cd test-apps/ios-test-app
./scripts/check-requirements.sh

Then install CocoaPods dependencies:

cd test-apps/ios-test-app/App
export LANG=en_US.UTF-8  # Required for CocoaPods

# Use the pod command found by check-requirements.sh, or:
# If using rbenv:
~/.rbenv/shims/pod install

# If using system Ruby:
pod install

# If using Homebrew:
pod install

Note: The build script will automatically detect and use the correct pod command location.

Step 3: Capacitor Configuration

Edit App/App/capacitor.config.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:

<key>UIBackgroundModes</key>
<array>
    <string>background-fetch</string>
    <string>background-processing</string>
    <string>remote-notification</string>
</array>

<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
    <string>com.timesafari.dailynotification.fetch</string>
    <string>com.timesafari.dailynotification.notify</string>
</array>

<key>NSUserNotificationsUsageDescription</key>
<string>This app uses notifications to deliver daily updates and reminders.</string>

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:

# 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

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

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

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:

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:

    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:

    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:

    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:

    grep DailyNotificationPlugin test-apps/ios-test-app/App/Podfile
    
  3. Check plugin registration:

    # Plugin should be in Pods project
    ls -la test-apps/ios-test-app/App/Pods/Local\ Podspecs/
    

CocoaPods Issues

  1. Encoding errors:

    export LANG=en_US.UTF-8
    ~/.rbenv/shims/pod install
    
  2. Clean reinstall:

    cd test-apps/ios-test-app/App
    pod deintegrate
    rm -rf Pods Podfile.lock
    pod install
    
  3. Ruby version issues:

    # 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: Product > Clean Build Folder (⌘⇧K)
    # Or command line:
    xcodebuild clean -workspace App.xcworkspace -scheme App
    
  2. Delete derived data:

    rm -rf ~/Library/Developer/Xcode/DerivedData
    
  3. Reset CocoaPods cache:

    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:

    cd ../../ios
    ./scripts/build-native.sh --platform ios
    
  2. Set up test app:

    cd test-apps/ios-test-app
    # Follow Quick Start section above
    
  3. Install dependencies:

    cd App
    export LANG=en_US.UTF-8
    ~/.rbenv/shims/pod install
    
  4. Build and run:

    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

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