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
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
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)
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)
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)
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)
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)
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!)
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)
Implemented battery status method matching Android functionality:
getBatteryStatus():
- Gets battery level (0-100%) using UIDevice
- Detects charging state (charging or full)
- Maps battery state to power state code (0=unknown, 1=unplugged, 2=charging, 3=full)
- Returns isOptimizationExempt (always false on iOS - no battery optimization)
- Enables battery monitoring automatically
iOS Adaptations:
- Uses UIDevice.current for battery information
- Battery optimization not applicable on iOS (Background App Refresh is system setting)
- Returns -1 for battery level if unknown
Progress: 16/52 methods implemented (31% complete)
Implemented main scheduling method for iOS plugin, matching Android functionality:
Core Features:
- Permission checking and requesting (iOS notification authorization)
- Time parsing (HH:mm format) with validation
- Next run time calculation (handles same-day and next-day scheduling)
- UNUserNotificationCenter scheduling with daily repeat
- Priority/interruption level support (iOS 15.0+)
- Prefetch scheduling 5 minutes before notification (BGTaskScheduler)
- Schedule storage in UserDefaults
Implementation Details:
- Checks notification authorization status before scheduling
- Requests permission if not granted (equivalent to Android exact alarm permission)
- Parses time string and calculates next occurrence
- Creates UNCalendarNotificationTrigger for daily repeat
- Schedules BGAppRefreshTask for prefetch 5 minutes before
- Stores schedule metadata in UserDefaults for persistence
Matches Android API:
- Same parameter structure (time, title, body, sound, priority, url)
- Same behavior (daily repeat, prefetch scheduling)
- iOS-specific adaptations (UNUserNotificationCenter vs AlarmManager)
This is the first critical method implementation (10/52 methods now complete).
Fixed critical compilation errors preventing iOS plugin build:
- Updated logger API calls from logger.debug(TAG, msg) to logger.log(.debug, msg)
across all iOS plugin files to match DailyNotificationLogger interface
- Fixed async/await concurrency in makeConditionalRequest using semaphore pattern
- Fixed NotificationContent immutability by creating new instances instead of mutation
- Changed private access control to internal for extension-accessible methods
- Added iOS 15.0+ availability checks for interruptionLevel property
- Fixed static member references using Self.MEMBER_NAME syntax
- Added missing .scheduling case to exhaustive switch statement
- Fixed variable initialization in retry state closures
Added DailyNotificationStorage.swift implementation matching Android pattern.
Updated build scripts with improved error reporting and full log visibility.
iOS plugin now compiles successfully. All build errors resolved.
Add comprehensive iOS build and deployment infrastructure with command-line
tooling, documentation, and web assets synchronization.
Changes:
- Update Capacitor dependencies to v6.0 in podspec
- Add iOS build support to build-native.sh with NVM integration
- Sync iOS web assets to match www/ source directory
- Create deployment scripts for both native iOS app and Vue 3 test app
- Add comprehensive iOS simulator deployment documentation
- Document web assets parity requirements between Android and iOS
This enables:
- Command-line iOS builds without Xcode UI
- Automated deployment to iOS simulators
- Consistent web assets across platforms
- Clear separation between native iOS app (ios/App) and Vue 3 test app
Files modified:
- ios/DailyNotificationPlugin.podspec (Capacitor 6.0)
- ios/App/App/public/index.html (synced from www/)
- scripts/build-native.sh (iOS build support)
Files added:
- docs/WEB_ASSETS_PARITY.md
- docs/standalone-ios-simulator-guide.md
- scripts/build-and-deploy-native-ios.sh
- test-apps/daily-notification-test/docs/IOS_BUILD_QUICK_REFERENCE.md
- test-apps/daily-notification-test/scripts/build-and-deploy-ios.sh
- Remove echo() method from DailyNotificationPlugin.java
- Update Android test app to show 'Plugin is loaded and ready!' instead of echo test
- Update web test app to remove echo method call
- Update iOS test app to remove echo method call
- Update documentation to remove echo test references
- Replace echo test with simple plugin availability check
The echo test was only used for initial plugin verification and is no longer
needed since the plugin now has comprehensive notification functionality.
This simplifies the codebase and removes unnecessary test code.
- Create missing capacitor-cordova-android-plugins directory and build files
- Add cordova.variables.gradle with proper variable definitions
- Create www directory with functional test web app
- Add capacitor.config.ts with plugin configuration
- Fix test file package names from com.getcapacitor.myapp to com.timesafari.dailynotification
- Move test files to correct package directories
- Test app now builds successfully and creates APK
- Capacitor sync now works (Android portion)
- Build script handles both plugin and test app builds
The android/app test app is now fully functional and can be used
to test the DailyNotification plugin in a real Android environment.
- Add static daily reminders to README.md core features and API reference
- Create detailed usage guide in USAGE.md with examples and best practices
- Add version 2.1.0 changelog entry documenting new reminder functionality
- Create examples/static-daily-reminders.ts with complete usage examples
- Update test-apps README to include reminder testing capabilities
The static daily reminder feature provides simple daily notifications
without network content dependency, supporting cross-platform scheduling
with rich customization options.
- Add complete iOS plugin implementation with BGTaskScheduler integration
- Implement Core Data model mirroring Android SQLite schema (ContentCache, Schedule, Callback, History)
- Add background task handlers for content fetch and notification delivery
- Implement TTL-at-fire logic with Core Data persistence
- Add callback management with HTTP and local callback support
- Include comprehensive error handling and structured logging
- Add Info.plist configuration for background tasks and permissions
- Support for dual scheduling with BGAppRefreshTask and BGProcessingTask
BREAKING CHANGE: iOS implementation requires iOS 13.0+ and background task permissions
- Add DailyNotificationPerformanceOptimizer for Android with comprehensive optimization
- Add DailyNotificationPerformanceOptimizer for iOS with Swift performance management
- Implement database query optimization with indexes and PRAGMA settings
- Add memory usage monitoring with automatic cleanup and thresholds
- Implement object pooling for frequently used objects to reduce allocation
- Add battery usage tracking and background CPU optimization
- Add network request optimization and efficiency monitoring
- Add comprehensive performance metrics and reporting
- Add production-ready optimization with stress testing support
- Add phase3-3-performance-optimization.ts usage examples
This implements Phase 3.3 performance optimization for production reliability:
- Database indexes for query optimization (slot_id, fetched_at, status, etc.)
- Memory monitoring with warning/critical thresholds and automatic cleanup
- Object pooling for String, Data, and other frequently used objects
- Battery optimization with background CPU usage minimization
- Network request batching and efficiency improvements
- Comprehensive performance metrics tracking and reporting
- Production-ready optimization with configurable thresholds
- Cross-platform implementation (Android + iOS)
Files: 3 changed, 1200+ insertions(+)
- Add GLOSSARY.md with core terminology and cross-references
- Add implementation-roadmap.md with 3-phase development plan
- Add notification-system.md with Native-First architecture spec
- Update ios/Plugin/README.md to reflect actual vs planned implementation status
This establishes the foundation for implementing shared SQLite storage,
TTL-at-fire enforcement, rolling window safety, and platform completion
as outlined in the phased roadmap.
Files: 4 changed, 807 insertions(+), 13 deletions(-)
Description:
- Add battery status and power state monitoring
- Implement adaptive scheduling based on battery levels
- Add maintenance worker for background tasks
- Enhance logging with structured DailyNotificationLogger
- Add configuration management with DailyNotificationConfig
- Define constants in DailyNotificationConstants
- Improve error handling and recovery mechanisms
Testing:
- Add comprehensive test coverage for battery optimization
- Add test coverage for power state management
- Add test coverage for maintenance tasks
- Add test coverage for configuration management
- Add test coverage for constants validation
Documentation:
- Add comprehensive file-level documentation
- Add method-level documentation
- Add test documentation
- Add configuration documentation
This commit improves the iOS implementation's reliability and battery
efficiency by adding robust error handling, logging, and configuration
management to make the plugin more maintainable and debuggable.
- Add build scripts for Android and iOS platforms
- Remove duplicate web implementation (src/web.ts)
- Add proper TypeScript configuration
- Add module documentation to index.ts
- Clean up package.json scripts
This commit improves the project structure and build process by:
1. Adding dedicated build scripts for native platforms
2. Removing redundant web implementation
3. Adding proper TypeScript configuration with strict mode
4. Improving code documentation
5. Organizing package.json scripts
The changes maintain backward compatibility while improving
the development experience and code quality.