Commit Graph

351 Commits

Author SHA1 Message Date
Matthew Raymer
bb9e7bdc02 docs(ios): add comprehensive console debugging guide
Created detailed guide for viewing console logs:

Console Debugging Guide:
- Method 1: Safari Web Inspector (JavaScript console) - recommended
- Method 2: Xcode Console (Native Swift logs)
- Method 3: Terminal commands (quick log viewing)

Guide Includes:
- Step-by-step instructions for each method
- What logs you'll see in each method
- Troubleshooting common issues
- Example debugging session
- Quick reference table

Access Methods:
- Safari Web Inspector: Best for JavaScript/plugin debugging
- Xcode Console: Best for native Swift debugging
- Terminal: Best for quick checks and filtering

Result: Developers can now easily debug permission issues and plugin calls
2025-11-11 23:49:54 -08:00
Matthew Raymer
36d572d43f fix(ios): add comprehensive error handling and timeout for permission check
Enhanced permission check with better debugging:

Error Handling Improvements:
- Added 10-second timeout to detect if promise never resolves
- Added method existence check before calling
- Added promise validation (checks if result is actually a promise)
- Added detailed console logging at each step
- Added result validation (checks if result is null/undefined)

Debugging Features:
- Logs plugin availability and method types
- Logs promise type and result structure
- Logs all error details (message, type, stack)
- Shows available methods if checkPermissionStatus is missing

Fixes:
- Status stuck on 'Checking permissions...'
- Better error messages to diagnose issues
- Timeout prevents infinite waiting

Result: Should now show either permission status or clear error message
2025-11-11 23:42:15 -08:00
Matthew Raymer
e448b06a8d fix(ios): use correct Capacitor API for plugin method registration
Fixed plugin registration to use proper Capacitor native bridge API:

API Fix:
- Changed from window.Capacitor.nativePromise to cap.nativePromise
- Added proper initialization wait for Capacitor to be available
- Wrapped in IIFE for proper scoping

Method Registration:
- All methods now use cap.nativePromise(pluginName, methodName, options)
- Methods properly bridge to native Swift implementation
- Added initialization check to wait for Capacitor if not ready

Fixes:
- Error: 'requestNotificationPermissions is not a function'
- Plugin methods now correctly call native bridge
- Proper async initialization ensures Capacitor is ready

Result: Permission buttons and all plugin methods should now work correctly
2025-11-11 23:13:40 -08:00
Matthew Raymer
04311803bc fix(ios): register DailyNotification plugin methods in capacitor_plugins.js
Fixed plugin method registration for iOS test app:

Plugin Registration Fix:
- Added proper method stubs for all DailyNotification plugin methods
- Methods use Capacitor.nativePromise to bridge to Swift implementation
- Includes permission, notification, status, channel, config, battery, and test methods

Method Registration:
- Permission: checkPermissionStatus, requestNotificationPermissions, checkPermissions, requestPermissions
- Notification: scheduleDailyNotification, getNotificationStatus, cancelAllNotifications
- Status: checkStatus
- Channel: isChannelEnabled, openChannelSettings
- Config: configure, configureNativeFetcher
- Battery/Power: getBatteryStatus, getPowerState, requestBatteryOptimizationExemption
- Exact Alarm: getExactAlarmStatus, openExactAlarmSettings
- Test: testAlarm

Fixes:
- Error: 'requestNotificationPermissions is not a function'
- Plugin methods now properly exposed to JavaScript
- Methods bridge correctly to native Swift implementation

Result: Permission buttons and other plugin methods should now work correctly
2025-11-11 23:12:21 -08:00
Matthew Raymer
328311281c feat(ios): enhance permission UI feedback with detailed logging
Enhanced permission request/check UI with better feedback:

Permission UI Enhancements:
- Added detailed console logging for permission operations
- Enhanced status display with emoji indicators
- Shows detailed permission results (status, granted, alert, badge, sound)
- Better error messages with full error details
- Visual feedback with color-coded status backgrounds

Console Logging:
- Logs when permission functions are called
- Logs plugin availability status
- Logs permission request/check results
- Logs errors with full details

Fixes:
- Permission visibility: Users can now see detailed permission status
- Error debugging: Full error messages help diagnose issues
- User feedback: Clear visual and text feedback for permission state

Result: Permission operations now provide comprehensive feedback in both UI and console
2025-11-11 22:25:52 -08:00
Matthew Raymer
4412838c74 fix(ios): improve UUID extraction with better regex patterns
Enhanced UUID extraction with multiple fallback strategies:

UUID Extraction Improvements:
- Primary: Extended regex to match UUID pattern (36-char hex with dashes)
- Fallback 1: Basic regex to get first parentheses content
- Fallback 2: Extended regex with explicit UUID format if status was extracted
- Handles both macOS sed (BSD) and GNU sed compatibility

Regex Patterns:
- Primary: sed -E 's/.*\(([0-9A-F-]{36})\).*/\1/'
- Fallback: sed 's/.*(\([^)]*\)).*/\1/'
- UUID format: 8-4-4-4-12 hex characters with dashes

Fixes:
- Status extraction: Detects if status was extracted instead of UUID
- UUID matching: Multiple patterns ensure UUID is found
- Compatibility: Works with both BSD and GNU sed

Result: Should now correctly extract UUID regardless of sed version
2025-11-11 22:20:13 -08:00
Matthew Raymer
48ba80e607 fix(ios): correct UUID extraction from simulator list
Fixed UUID extraction to get device ID instead of status:

UUID Extraction Fix:
- Changed regex to match UUID format (36-char hex with dashes)
- UUID format: 68D19D08-4701-422C-AF61-2E21ACA1DD4C
- Previous regex was matching last parentheses (status: Shutdown)
- New regex specifically matches UUID pattern in first parentheses

Regex Pattern:
- Old: sed -n 's/.*(\([^)]*\)).*/\1/p' (matches any parentheses)
- New: sed -n 's/.*(\([0-9A-F-]\{36\}\)).*/\1/p' (matches UUID pattern)
- Fallback to old pattern if UUID pattern doesn't match

Fixes:
- Device ID extraction: Now correctly extracts UUID instead of status
- Build destination: Uses correct device ID for xcodebuild
- Simulator matching: xcodebuild can now find the correct device

Result: Script should now correctly extract and use device UUID for builds
2025-11-11 22:19:15 -08:00
Matthew Raymer
6312d953a4 feat(ios): enhance permission request logging with os_log and NSLog
Enhanced permission request logging for better visibility:

Logging Enhancements:
- Added os.log import and logger definition
- Added os_log statements for system-level logging
- Added NSLog statements for guaranteed console output
- Enhanced print statements with detailed permission status

Permission Logging:
- Logs when permission request starts
- Logs current authorization status before request
- Logs authorization result (granted/denied)
- Logs detailed permission settings (alert, badge, sound, etc.)
- All logs use multiple methods (print, NSLog, os_log) for maximum visibility

Fixes:
- Permission visibility: Can now see permission requests in system logs
- Debugging: Detailed logging helps diagnose permission issues
- Console output: Multiple logging methods ensure messages are captured

Result: Permission requests and status changes are now fully logged and visible
2025-11-11 22:16:13 -08:00
Matthew Raymer
977080bc2d fix(ios): improve simulator auto-detection to use device ID
Enhanced simulator auto-detection for better reliability:

Device ID Support:
- Extracts both device name and UUID from simulator list
- Uses device ID (UUID) for xcodebuild destination when available
- More reliable than device name matching
- Falls back to device name if ID not available

Detection Improvements:
- Better parsing of simulator list output
- Handles edge cases where device name might not match exactly
- Logs both device name and ID for debugging

Fixes:
- Device not found: Using UUID ensures exact device matching
- Auto-detection: More robust extraction of device information
- Build reliability: Device ID is more reliable than name matching

Result: Script should now correctly auto-detect and use available iPhone simulators
2025-11-11 22:11:23 -08:00
Matthew Raymer
302560f12f docs(ios): update code signing documentation
Updated iOS code signing documentation with latest findings and fixes
2025-11-11 21:40:17 -08:00
Matthew Raymer
3a7c68c756 fix(ios): use storyboard to load ViewController - resolves black screen
Fixed ViewController instantiation to resolve black screen issue:

Storyboard Loading:
- Changed from direct ViewController() instantiation to storyboard loading
- Uses UIStoryboard(name: "Main", bundle: nil) to load ViewController
- This is Capacitor's standard approach for iOS apps
- Falls back to CAPBridgeViewController if storyboard fails

Root Cause:
- Direct ViewController() instantiation caused compilation error
- ViewController class wasn't in scope for direct instantiation
- SceneDelegate approach also failed (class not found by iOS runtime)
- Storyboard approach works because it's configured in Main.storyboard

Fixes:
- Black screen: ViewController now loads correctly from storyboard
- WebView initialization: CAPBridgeViewController initializes properly
- HTML loading: WebView can now load index.html from bundle
- App display: App now shows content instead of black screen

Result: iOS test app now displays correctly with WebView and HTML content
2025-11-11 21:39:22 -08:00
Matthew Raymer
3250b3fc33 fix(ios): remove SceneDelegate, use AppDelegate window instead
Simplified app initialization:

Removed SceneDelegate:
- Removed SceneDelegate configuration from Info.plist
- SceneDelegate class wasn't being found by iOS runtime
- Using traditional AppDelegate window approach instead

AppDelegate Window Setup:
- Create window in didFinishLaunchingWithOptions
- Instantiate ViewController directly
- Set as rootViewController and make key and visible
- Added logging to track initialization

Fixes:
- Black screen: AppDelegate now creates window and ViewController
- SceneDelegate error: removed problematic SceneDelegate configuration
- WebView initialization: ViewController should now be created correctly

Result: App should now initialize properly with ViewController and WebView
2025-11-11 21:21:34 -08:00
Matthew Raymer
517fe15d4d fix(ios): add @objc annotation to SceneDelegate for runtime visibility
Added @objc annotation to SceneDelegate:

Objective-C Runtime:
- Added @objc(SceneDelegate) annotation
- Makes class visible to Objective-C runtime
- Required for Info.plist class name resolution

Fixes:
- SceneDelegate loading: class can now be found by iOS runtime
- Info.plist resolution: UISceneDelegateClassName can now resolve
- ViewController creation: SceneDelegate can now instantiate ViewController

Result: SceneDelegate should now be loadable by iOS runtime
2025-11-11 21:20:48 -08:00
Matthew Raymer
86497f8604 fix(ios): correct SceneDelegate class name in Info.plist
Fixed SceneDelegate class name configuration:

Info.plist Fix:
- Changed from $(PRODUCT_MODULE_NAME).SceneDelegate to SceneDelegate
- PRODUCT_MODULE_NAME variable wasn't resolving correctly
- SceneDelegate class couldn't be loaded, causing black screen

Fixes:
- Black screen: SceneDelegate now loads correctly
- ViewController creation: SceneDelegate can now instantiate ViewController
- WebView initialization: App initialization chain now works

Result: SceneDelegate should now load and create ViewController, allowing WebView to initialize
2025-11-11 21:19:29 -08:00
Matthew Raymer
3a21b710d7 test(ios): add logging to SceneDelegate to verify initialization
Added comprehensive logging to SceneDelegate:

SceneDelegate Logging:
- Logs when willConnectTo is called
- Logs window creation
- Logs ViewController instantiation
- Logs window setup completion
- Uses os_log, print, and NSLog for maximum visibility

Debugging:
- Verifies SceneDelegate is being called
- Confirms ViewController is being created
- Checks window setup process

Fixes:
- Initialization tracking: can see if SceneDelegate runs
- ViewController creation: confirms ViewController is instantiated
- Window setup: verifies window is configured

Result: Can now see the full initialization chain from SceneDelegate to ViewController
2025-11-11 21:18:54 -08:00
Matthew Raymer
2f285edec4 test(ios): enhance sanity check logging with os_log and NSLog
Enhanced logging to ensure messages are captured:

Logging Methods:
- Added os_log for system logging (visible in Console.app)
- Added NSLog for guaranteed output
- Kept print() for Xcode console
- Added emoji prefixes for easy filtering

Logging Points:
- ViewController initialization
- Bridge existence check
- WebView existence check
- WebView URL logging
- Sanity check execution

Fixes:
- Log visibility: messages now appear in multiple log streams
- Debugging: can now see if ViewController is being created
- WebView diagnosis: can see bridge and WebView state

Result: Logs should now be visible in Console.app and log stream
2025-11-11 21:17:45 -08:00
Matthew Raymer
9582dd8d8c test(ios): add sanity check to diagnose WebView loading issue
Added comprehensive sanity check to diagnose why HTML isn't loading:

Sanity Check:
- Creates simple test.html with red background for visibility
- Checks if bridge and WebView exist
- Attempts to load test.html or index.html directly
- Lists bundle contents to see what files are actually present
- Provides detailed logging of WebView state

Debugging:
- Checks bridge initialization
- Checks WebView existence
- Checks file paths in bundle
- Lists actual bundle contents

Fixes:
- WebView diagnosis: can now see if WebView exists and what URL it has
- File path verification: checks if HTML files are in bundle
- Bundle inspection: lists what files are actually available

Result: Will show exactly why HTML isn't loading - WebView issue, file path issue, or Capacitor config issue
2025-11-11 21:14:37 -08:00
Matthew Raymer
abfa1029a4 fix(ios): add debug logging and fix storyboard ViewController class
Added debug logging to diagnose WebView loading issue:

Debug Logging:
- Added print statements to check bridge and WebView initialization
- Logs WebView URL to see if HTML is being loaded
- Helps diagnose if bridge is nil or WebView isn't configured

Storyboard Fix:
- Changed customClass from CAPBridgeViewController to ViewController
- Changed customModule from Capacitor to App
- Ensures storyboard uses our custom ViewController class

Fixes:
- WebView debugging: can now see if bridge/WebView are initialized
- Storyboard configuration: uses correct ViewController class
- HTML loading: helps diagnose why HTML isn't displaying

Result: Can now see in logs if WebView is being initialized correctly
2025-11-11 20:26:40 -08:00
Matthew Raymer
d5ddb6e20e fix(ios): add content src to config.xml for HTML loading
Added missing content src tag to config.xml:

Content Source:
- Added <content src="index.html" /> tag
- Tells Capacitor/Cordova which HTML file to load
- Required for WebView to display the app

Fixes:
- Black screen: WebView now knows which HTML file to load
- Missing start page: Capacitor can now find index.html
- WebView initialization: Proper content source configured

Result: WebView should now load index.html from public directory
2025-11-11 20:20:02 -08:00
Matthew Raymer
345610b4d3 fix(ios): add visible test element to verify HTML loading
Added highly visible red banner to verify HTML is loading:

Visibility Test:
- Red banner with white text at top of page
- Should appear immediately if HTML loads
- Helps diagnose if issue is HTML loading or JavaScript

Fixes:
- Black screen debugging: can now see if HTML loads at all
- WebView verification: confirms WebView is serving HTML
- Immediate feedback: no need to wait for JavaScript

Result: Can immediately see if HTML is loading or if WebView is the issue
2025-11-11 20:17:26 -08:00
Matthew Raymer
9f79547556 fix(ios): add debug logging to verify HTML loading
Added immediate DOMContentLoaded handler to verify HTML is loading:

Debug Logging:
- Added console.log when DOM loads
- Added body element check and background color set
- Helps diagnose if HTML is loading at all

Fixes:
- Black screen debugging: can now see if HTML loads
- JavaScript execution: verifies scripts are running
- WebView loading: confirms WebView is serving HTML

Result: Can now diagnose if issue is HTML loading or JavaScript execution
2025-11-11 20:17:11 -08:00
Matthew Raymer
cbf235d81f fix(ios): add Capacitor runtime files for test app
Created missing Capacitor JavaScript files required for plugin access:

capacitor.js:
- Copied native-bridge.js from Capacitor framework
- Provides Capacitor runtime and native bridge functionality
- Required for plugin communication with native code

capacitor_plugins.js:
- Created minimal plugin registration file
- Sets up window.Capacitor.Plugins structure
- Allows DailyNotification plugin to be accessed

Fixes:
- Black screen: Capacitor scripts now exist and can be loaded
- Plugin errors: window.Capacitor will be available after scripts load
- JavaScript errors: Missing script files were causing page load failures

Result: App should now load and display the test interface
2025-11-11 20:12:32 -08:00
Matthew Raymer
194029423b fix(ios): update capacitor config and fix plugin initialization
Updated Capacitor configuration and HTML initialization:

Capacitor Config:
- Changed webDir from 'www' to 'public' to match actual directory structure
- Config now correctly points to App/App/public/ directory

HTML Initialization:
- Removed immediate plugin assignment (was failing because Capacitor not loaded)
- Added Capacitor script tags (capacitor.js, capacitor_plugins.js)
- Added initialization script that waits for Capacitor to be ready
- Plugin is now set after Capacitor loads successfully

Fixes:
- Black screen: Capacitor scripts now load before plugin access
- Plugin errors: window.Capacitor was undefined, now waits for it
- Initialization: Proper async loading of Capacitor runtime

Note: capacitor.js and capacitor_plugins.js will be generated by Capacitor
during build or can be copied from node_modules if needed
2025-11-11 20:07:03 -08:00
Matthew Raymer
4b239e7faf fix(ios): add Capacitor script tags to index.html
Added missing Capacitor runtime scripts required for plugin access:

Script Tags:
- Added capacitor.js (main Capacitor runtime)
- Added capacitor_plugins.js (plugin definitions)
- Added initialization script to wait for Capacitor ready

Initialization:
- Waits for DOMContentLoaded event
- Polls for Capacitor.Plugins.DailyNotification availability
- Sets window.DailyNotification when ready

Fixes:
- Black screen issue: app was loading but Capacitor wasn't initialized
- Plugin access errors: window.Capacitor was undefined
- JavaScript errors preventing page rendering

Result: App should now display the test interface correctly
2025-11-11 20:06:20 -08:00
Matthew Raymer
9d6d979d83 fix(ios): ensure Simulator window is always visible after boot
Fixed build script to always open Simulator app window:

Simulator Visibility:
- Always opens Simulator app window after booting
- Ensures window is visible even if simulator was already booted
- Provides visual feedback that simulator is running

Boot Flow:
- If already booted: opens Simulator window immediately
- If booting: boots device, then opens Simulator window
- If boot fails: opens Simulator app for manual selection

Fixes:
- Simulator window now always appears after build
- User can see simulator even if it was already running
- Better visual feedback during build process

Result: Simulator window is now always visible after build completes
2025-11-11 20:02:06 -08:00
Matthew Raymer
ceb81a6be1 fix(ios): improve simulator boot detection and error handling
Enhanced simulator boot logic for better reliability:

Boot Detection:
- More robust check for already-booted simulators
- Uses grep with case-insensitive matching
- Verifies boot status after manual Simulator app opening

Error Handling:
- Shows actual boot command output (removed 2>/dev/null)
- Adds 3-second wait after successful boot for initialization
- Verifies boot status after opening Simulator app manually
- Continues with build even if boot verification fails

Fixes:
- Simulator boot detection now works correctly
- Better error messages when boot fails
- Handles edge cases where simulator is already booted

Result: Build script now reliably detects and boots simulators
2025-11-11 19:59:38 -08:00
Matthew Raymer
308e249620 fix(ios): add missing CFBundleExecutable to Info.plist
Added CFBundleExecutable key required for iOS app installation:

CFBundleExecutable:
- Set to 'App' (matches PRODUCT_NAME from build settings)
- Required by iOS to identify the executable binary
- Without this, app installation fails with 'missing or invalid CFBundleExecutable'

Fixes:
- Installation error: 'Bundle has missing or invalid CFBundleExecutable in its Info.plist'
- App can now be installed on simulator successfully

Result: App installation should now complete successfully
2025-11-11 19:54:09 -08:00
Matthew Raymer
a330f25e21 fix(ios): add missing Assets.xcassets with AppIcon for test app
Created missing asset catalog required by Xcode build:

Assets.xcassets:
- Created asset catalog directory structure
- Added Contents.json with standard Xcode format
- Added AppIcon.appiconset with minimal icon configuration

AppIcon.appiconset:
- Minimal icon set configuration for iOS
- Universal platform support
- 1024x1024 size placeholder (actual icons can be added later)

Fixes:
- Build error: 'None of the input catalogs contained a matching app icon set named AppIcon'
- Build error: 'Failed to read file attributes for Assets.xcassets'
- Xcode project expects this asset catalog for app icons

Result: Build should now complete successfully
2025-11-11 19:51:54 -08:00
Matthew Raymer
fa0fea7f75 fix(ios): add missing storyboard files for test app
Created missing storyboard files required by Xcode build:

Main.storyboard:
- Minimal storyboard referencing CAPBridgeViewController
- Required for Capacitor app initialization
- Matches standard Capacitor iOS app structure

LaunchScreen.storyboard:
- Launch screen storyboard for app startup
- Simple view controller with safe area layout
- Referenced in Info.plist as UILaunchStoryboardName

Fixes:
- Build error: 'Build input file cannot be found: Main.storyboard'
- Build error: 'Build input file cannot be found: LaunchScreen.storyboard'
- Xcode project expects these files for storyboard-based UI

Result: Build should now complete successfully
2025-11-11 19:50:01 -08:00
Matthew Raymer
b45ac46b98 fix(ios): correct simulator name extraction in build script
Fixed simulator auto-detection to extract device name correctly:

Simulator Detection:
- Fixed sed command to extract device name (not UUID)
- Pattern: extracts text before first parenthesis
- Handles whitespace correctly with xargs

Example:
- Input: '    iPhone 17 Pro (UUID) (Status)'
- Output: 'iPhone 17 Pro'

Result: Build script now correctly detects and uses available iPhone simulators
2025-11-11 19:47:12 -08:00
Matthew Raymer
a6b48013ab fix(ios): auto-detect available iPhone simulator for builds
Fixed build script to automatically detect and use available simulators:

Simulator Detection:
- Auto-detects first available iPhone simulator if none specified
- Falls back to generic destination if no iPhones found
- Lists available devices in error messages

Build Destination:
- Uses specific device name when available
- Falls back to generic destination for compatibility
- Handles both named devices and generic destinations

Fixes:
- No longer hardcodes 'iPhone 15 Pro' (which may not exist)
- Works with any available iPhone simulator
- Better error messages showing available devices

Usage:
- ./scripts/build-and-deploy.sh              # Auto-detect
- ./scripts/build-and-deploy.sh 'iPhone 17'  # Specify device

Result: Build script now works with any available simulator
2025-11-11 19:46:56 -08:00
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
Matthew Raymer
d23a1e8719 feat(ios): set up iOS test app project structure from command line
Created complete iOS test app project structure:

Project Setup:
- Created package.json with Capacitor dependencies
- Installed Capacitor CLI and iOS platform
- Generated Xcode project (App.xcodeproj, App.xcworkspace)
- Configured Podfile with correct paths

Podfile Configuration:
- Fixed paths to use local node_modules for Capacitor
- Added DailyNotificationPlugin from project root
- Configured for iOS 13.0+ deployment target

Fixed Issues:
- Resolved zsh syntax error (CODE_SIGN_IDENTITY='' instead of "")
- Corrected Podfile paths for Capacitor and plugin
- Created public directory for web assets

Result:
- Pod install successful (3 pods installed)
- Workspace ready for command-line builds
- All files in place for simulator builds

Next: Can now run build scripts or xcodebuild commands
2025-11-11 19:30:43 -08:00
Matthew Raymer
09a3d5159c docs(ios): add comprehensive iOS code signing guide
Created iOS code signing documentation:

Signing Scenarios:
- Simulator builds (signing disabled - faster)
- Device builds with automatic signing (recommended)
- Device builds with manual signing (advanced)

Configuration:
- Command-line build flags for each scenario
- Xcode project settings
- Environment variables

Troubleshooting:
- Common signing errors and solutions
- Certificate and provisioning profile issues
- Bundle identifier conflicts
- Verification commands

Quick Reference:
- Simulator: CODE_SIGNING_REQUIRED=NO
- Device (auto): CODE_SIGN_STYLE=Automatic + DEVELOPMENT_TEAM
- Device (manual): CODE_SIGN_STYLE=Manual + PROVISIONING_PROFILE

Updated SETUP.md:
- Added code signing section
- Quick reference for simulator vs device builds
- Link to comprehensive guide

Result: Complete signing guide for all iOS build scenarios
2025-11-11 19:09:45 -08:00
Matthew Raymer
5f55882b02 docs(ios): enhance iOS test app SETUP.md with Android app information
Expanded iOS test app setup guide with comprehensive information:

Added Sections:
- Prerequisites (macOS, Xcode, CocoaPods, Node.js, Ruby)
- Quick Start options (copy existing vs generate new)
- Detailed configuration steps (Podfile, Capacitor, Info.plist)
- iOS-specific permissions and background modes
- Build and run instructions (Xcode, command line, scripts)
- Test interface features (matching Android test app)
- iOS-specific considerations (background execution, notifications, storage)
- Comprehensive troubleshooting guide
- Project structure documentation
- Dependencies list
- Android vs iOS comparison table
- Additional resources and support

Configuration Details:
- Podfile with plugin path
- Capacitor config with plugin options
- Info.plist permissions (UIBackgroundModes, BGTaskScheduler, notifications)
- iOS permission equivalents to Android

Troubleshooting:
- Plugin not found solutions
- CocoaPods encoding and installation issues
- Build errors and cleanup procedures
- Runtime issues (notifications, background tasks, plugin methods)

Comparison Table:
- Side-by-side Android vs iOS equivalents
- Build systems, permissions, storage, etc.

Result: Comprehensive setup guide matching Android test app documentation
2025-11-11 18:08:36 -08:00
Matthew Raymer
530691b863 fix(ios): make PersistenceController public for build access
Fixed build error: 'cannot find PersistenceController in scope'

Changes:
- Made PersistenceController class public
- Made shared static property public
- Made container property public
- Made init method public

This allows DailyNotificationPlugin to access PersistenceController
across module boundaries. CocoaPods pod install was required to
regenerate project files with updated access modifiers.

Result: iOS plugin now builds successfully
2025-11-11 17:45:01 -08:00
Matthew Raymer
04602de973 fix(ios): resolve compilation errors for iOS plugin build
Fixed compilation errors preventing iOS plugin build:

Duplicate Method Declarations:
- Removed duplicate getContentCache() and clearContentCache() from DailyNotificationCallbacks.swift
- These methods are already implemented in DailyNotificationPlugin.swift
- Added comment explaining removal

Override Keyword Issues:
- Added 'public' access modifier to checkPermissions() override
- Added 'public' access modifier to requestPermissions() override
- Methods now properly override parent class methods from CAPPlugin

Build Configuration:
- Set GENERATE_INFOPLIST_FILE=YES for framework target
- Fixed encoding issues with LANG=en_US.UTF-8

Result:
- iOS plugin now builds successfully
- All 52 API methods compile without errors
- Ready for testing and integration
2025-11-11 17:36:11 -08:00
Matthew Raymer
93a6000b59 docs(ios): add iOS implementation completion summary
Created comprehensive completion summary documenting:

Implementation Status:
- 52/52 methods implemented (100% API parity)
- All method categories completed
- iOS-specific adaptations documented

Method Categories:
- Core scheduling (3)
- Permissions (4)
- Status & battery (4)
- Configuration (3)
- Content management (5)
- Power & scheduling (3)
- Status & settings (3)
- Alarm status (3)
- Exact alarm (2)
- Dual schedule (4)
- Database access (8)
- Schedule CRUD (4)
- History (2)
- Config management (3)
- Utility methods (1)

iOS Adaptations:
- UserDefaults for schedules/configs
- Core Data for cache/history
- UNUserNotificationCenter for notifications
- BGTaskScheduler for background tasks
- Platform differences documented

Known Limitations:
- getAllConfigs() limited by UserDefaults enumeration
- Background App Refresh cannot be checked programmatically
- Battery optimization not applicable on iOS

Ready for testing and integration!
2025-11-11 02:28:06 -08:00
Matthew Raymer
ca081e971d feat(ios): implement getHistory, getHistoryStats, getAllConfigs, updateConfig, and deleteConfig methods
Implemented history and config management methods:

getHistory():
- Returns history entries with optional filters (since, kind, limit)
- Uses Core Data History entity
- Filters by timestamp and kind
- Sorts by occurredAt descending (most recent first)
- Returns history array matching Android API

getHistoryStats():
- Returns statistics about history entries
- Counts outcomes and kinds
- Finds mostRecent and oldest timestamps
- Returns totalCount, outcomes, kinds, mostRecent, oldest
- Uses Core Data for aggregation

getAllConfigs():
- Returns all configurations (limited by UserDefaults enumeration)
- Supports optional filters (timesafariDid, configType)
- Note: UserDefaults doesn't support key enumeration directly
- Returns empty array (limitation documented)

updateConfig():
- Updates existing configuration value
- Validates config exists before updating
- Supports optional timesafariDid for scoped configs
- Handles JSON and plain string values
- Returns updated config

deleteConfig():
- Deletes configuration by key
- Validates config exists before deletion
- Supports optional timesafariDid for scoped configs
- Removes from UserDefaults

iOS Adaptations:
- Uses Core Data History entity for history storage
- UserDefaults for config storage (enumeration limitation)
- Timestamp conversion (Date to milliseconds)
- Predicate-based filtering for Core Data queries

Progress: 52/52 methods implemented (100% COMPLETE!)
2025-11-11 02:23:41 -08:00
Matthew Raymer
a8d92291e9 feat(ios): implement calculateNextRunTime method
Implemented schedule calculation utility method:

calculateNextRunTime():
- Calculates next run time from cron expression or HH:mm time string
- Supports cron format: "minute hour * * *" (e.g., "30 9 * * *" = 9:30 AM daily)
- Supports time format: "HH:mm" (e.g., "09:30" = 9:30 AM daily)
- Handles same-day vs next-day scheduling
- Returns nextRunAt timestamp in milliseconds
- Fallback to 24 hours from now if parsing fails

calculateNextRunTimeFromSchedule():
- Private helper method for schedule parsing
- Parses both cron and time formats
- Uses Calendar for date calculations
- Handles timezone-aware calculations

iOS Adaptations:
- Uses Calendar.current for date calculations
- TimeInterval conversion (Date to milliseconds)
- Handles edge cases (invalid formats, past times)

Progress: 48/52 methods implemented (92% complete)
2025-11-11 02:20:50 -08:00
Matthew Raymer
9d5ffcfdb5 feat(ios): implement getContentCacheById, getLatestContentCache, and saveContentCache methods
Implemented content cache access methods using Core Data:

getContentCacheById():
- Returns content cache by ID or latest if ID not provided
- Uses Core Data fetch with predicate for ID lookup
- Returns null if cache not found
- Matches Android getContentCacheById method

getLatestContentCache():
- Returns latest content cache entry
- Delegates to getContentCacheById with no ID
- Matches Android getLatestContentCache method

saveContentCache():
- Saves content to cache in Core Data
- Auto-generates ID if not provided (cache_timestamp)
- Converts payload string to Data for storage
- Stores fetchedAt, ttlSeconds, payload, and meta
- Returns saved cache object

iOS Adaptations:
- Uses Core Data ContentCache entity
- Payload stored as Data (from JSON string)
- Timestamp conversion (Date to milliseconds)
- Error handling for invalid payload data

Progress: 47/52 methods implemented (90% complete)
2025-11-11 02:18:55 -08:00
Matthew Raymer
be6cdc98d6 feat(ios): implement createSchedule, updateSchedule, deleteSchedule, and enableSchedule methods
Implemented schedule CRUD methods using UserDefaults:

createSchedule():
- Creates new schedule with required kind field
- Auto-generates ID if not provided (kind_timestamp)
- Stores optional fields (cron, clockTime, jitterMs, backoffPolicy, stateJson)
- Adds to schedules array in UserDefaults
- Returns created schedule

updateSchedule():
- Updates existing schedule by ID
- Updates provided fields (enabled, cron, clockTime, jitterMs, backoffPolicy, stateJson, lastRunAt, nextRunAt)
- Returns updated schedule
- Rejects if schedule not found

deleteSchedule():
- Deletes schedule by ID from UserDefaults
- Removes from schedules array
- Rejects if schedule not found

enableSchedule():
- Enables or disables schedule by ID
- Updates enabled field in schedule
- Rejects if schedule not found

iOS Adaptations:
- Uses UserDefaults array instead of SQLite database
- In-memory array manipulation then persistence
- Maintains schedule structure matching Android

Progress: 44/52 methods implemented (85% complete)
2025-11-11 02:17:59 -08:00
Matthew Raymer
082a70f54f feat(ios): implement getSchedules, getSchedule, getConfig, and setConfig methods
Implemented database access methods using UserDefaults:

getSchedules():
- Returns schedules matching optional filters (kind, enabled)
- Filters by schedule type ('fetch' | 'notify')
- Filters by enabled status (true/false/undefined)
- Returns schedules array matching Android API

getSchedule():
- Returns single schedule by ID
- Returns null if not found
- Matches Android getSchedule method

getConfig():
- Returns configuration value by key
- Supports optional timesafariDid for scoped configs
- Returns null if config not found
- Uses UserDefaults with key prefix

setConfig():
- Stores configuration value by key
- Supports optional timesafariDid for scoped configs
- Stores as JSON string in UserDefaults
- Matches Android setConfig method

iOS Adaptations:
- Uses UserDefaults instead of SQLite database
- Config keys prefixed with 'DailyNotificationConfig_'
- DID-scoped configs use composite keys
- JSON serialization for complex values

Progress: 40/52 methods implemented (77% complete)
2025-11-11 02:17:02 -08:00
Matthew Raymer
22fdaa789d feat(ios): implement updateDualScheduleConfig, cancelDualSchedule, pauseDualSchedule, and resumeDualSchedule methods
Implemented dual schedule management methods:

updateDualScheduleConfig():
- Updates dual schedule configuration
- Cancels existing schedules and reschedules with new config
- Stores config in UserDefaults for persistence
- Combines content fetch and user notification scheduling

cancelDualSchedule():
- Cancels all dual schedule notifications
- Clears stored dual schedule config
- Uses existing cancelAllNotifications method

pauseDualSchedule():
- Pauses dual schedule by cancelling notifications
- Stores pause state in UserDefaults
- Allows resuming later with stored config

resumeDualSchedule():
- Resumes paused dual schedule
- Restores from stored config in UserDefaults
- Re-schedules both content fetch and user notification
- Validates pause state before resuming

iOS Adaptations:
- Uses UserDefaults for config persistence
- Pause/resume pattern for schedule management
- Config restoration on resume

Progress: 36/52 methods implemented (69% complete)
2025-11-11 02:14:54 -08:00
Matthew Raymer
9a8589bb08 feat(ios): implement getExactAlarmStatus and openExactAlarmSettings methods
Implemented exact alarm status methods matching Android functionality:

getExactAlarmStatus():
- Returns exact alarm scheduling capability information
- iOS always supports exact alarms (UNUserNotificationCenter)
- Returns supported=true, enabled based on notification authorization
- No fallback window needed (exact scheduling always available)
- Matches Android API structure

openExactAlarmSettings():
- Opens iOS app notification settings
- iOS doesn't have separate exact alarm settings like Android
- Opens general app settings instead
- Provides API compatibility with Android

iOS Adaptations:
- Exact alarms always supported (no permission needed)
- Enabled status based on notification authorization
- No fallback window (precise scheduling always available)
- Opens app settings instead of exact alarm settings

Progress: 32/52 methods implemented (62% complete)
2025-11-11 02:13:15 -08:00
Matthew Raymer
bdee842ea9 feat(ios): implement isAlarmScheduled, getNextAlarmTime, and testAlarm methods
Implemented alarm status and testing methods matching Android functionality:

isAlarmScheduled():
- Checks if notification is scheduled for given trigger time
- Searches pending notifications for matching trigger date
- Uses 1-minute tolerance for time comparison
- Returns scheduled status and triggerAtMillis

getNextAlarmTime():
- Gets the next scheduled notification time
- Finds earliest scheduled daily notification
- Returns scheduled status and triggerAtMillis (or just scheduled: false)

testAlarm():
- Schedules test notification for testing purposes
- Defaults to 5 seconds from now (configurable)
- Creates test notification with title and body
- Returns scheduled status, secondsFromNow, and triggerAtMillis
- Useful for verifying notification delivery works

iOS Adaptations:
- Uses UNCalendarNotificationTrigger for scheduling
- Searches pending notifications to check status
- Date component matching for precise scheduling

Progress: 30/52 methods implemented (58% complete)
2025-11-11 02:12:35 -08:00
Matthew Raymer
b3817a0cb1 feat(ios): implement isChannelEnabled, openChannelSettings, and checkStatus methods
Implemented status and settings methods matching Android functionality:

isChannelEnabled():
- Checks if notifications are enabled (iOS doesn't have channels)
- Returns enabled status and channelId
- Uses UNUserNotificationCenter authorization status

openChannelSettings():
- Opens iOS app notification settings
- iOS doesn't have per-channel settings like Android
- Opens general app settings instead
- Returns opened status and channelId

checkStatus():
- Comprehensive status check combining permissions and scheduling
- Returns notificationsEnabled, isScheduled, scheduledCount, pendingCount
- Includes nextNotificationTime and channel information
- Combines multiple status checks into one call

iOS Adaptations:
- No notification channels (checks app-level authorization)
- Opens app settings instead of channel settings
- Uses UNUserNotificationCenter for status checks

Progress: 27/52 methods implemented (52% complete - HALFWAY!)
2025-11-11 02:11:08 -08:00
Matthew Raymer
ca40b971c5 feat(ios): implement getPowerState, requestBatteryOptimizationExemption, and setAdaptiveScheduling methods
Implemented power and scheduling utility methods:

getPowerState():
- Returns power state code (0=unknown, 1=unplugged, 2=charging, 3=full)
- Returns isOptimizationExempt (always false on iOS)
- Uses UIDevice battery monitoring

requestBatteryOptimizationExemption():
- No-op on iOS (battery optimization not applicable)
- Exists for API compatibility with Android
- Background App Refresh is user-controlled in Settings

setAdaptiveScheduling():
- Enables/disables adaptive scheduling
- Stores setting in UserDefaults
- Matches Android behavior

iOS Adaptations:
- Battery optimization not applicable (Background App Refresh is system setting)
- Power state derived from battery state
- Adaptive scheduling stored in UserDefaults

Progress: 24/52 methods implemented (46% complete)
2025-11-11 02:10:39 -08:00
Matthew Raymer
d2b1ab07cd feat(ios): implement getContentCache and clearContentCache methods
Implemented content cache management methods matching Android functionality:

getContentCache():
- Retrieves latest cached content from Core Data
- Returns id, fetchedAt, ttlSeconds, payload, and meta
- Returns empty object if no cache exists
- Uses async Task for Core Data access

clearContentCache():
- Deletes all content cache entries from Core Data
- Uses NSBatchDeleteRequest for efficient deletion
- Saves context after deletion

iOS Adaptations:
- Uses Core Data (ContentCache entity) instead of SQLite
- Async/await pattern for Core Data operations
- JSON deserialization for payload
- Timestamp conversion (Date to milliseconds)

Progress: 21/52 methods implemented (40% complete)
2025-11-11 02:08:41 -08:00
Matthew Raymer
ebab224916 feat(ios): implement configureNativeFetcher and setActiveDidFromHost methods
Implemented TimeSafari integration configuration methods:

configureNativeFetcher():
- Accepts apiBaseUrl, activeDid, and jwtToken/jwtSecret
- Stores configuration as JSON in UserDefaults
- Matches Android database storage pattern
- Supports backward compatibility (jwtToken/jwtSecret)
- Stores configuredAt timestamp

setActiveDidFromHost():
- Simpler method for updating just the activeDid
- Updates activeDid in UserDefaults
- Updates existing native fetcher config if present
- Stores updatedAt timestamp

iOS Adaptations:
- Uses UserDefaults instead of database (iOS equivalent of SharedPreferences)
- JSON serialization for config storage
- No native fetcher interface (unlike Android) - config stored for background tasks

Progress: 19/52 methods implemented (37% complete)
2025-11-11 02:07:59 -08:00