Implement checkPermissionStatus() and requestNotificationPermissions() methods for iOS plugin, matching Android functionality. Fix compilation errors across plugin files and add comprehensive build/test infrastructure. Key Changes: - Add checkPermissionStatus() and requestNotificationPermissions() methods - Fix 13+ categories of Swift compilation errors (type conversions, logger API, access control, async/await, etc.) - Create DailyNotificationScheduler, DailyNotificationStorage, DailyNotificationStateActor, and DailyNotificationErrorCodes components - Fix CoreData initialization to handle missing model gracefully for Phase 1 - Add iOS test app build script with simulator auto-detection - Update directive with lessons learned from build and permission work Build Status: ✅ BUILD SUCCEEDED Test App: ✅ Ready for iOS Simulator testing Files Modified: - doc/directives/0003-iOS-Android-Parity-Directive.md (lessons learned) - ios/Plugin/DailyNotificationPlugin.swift (Phase 1 methods) - ios/Plugin/DailyNotificationModel.swift (CoreData fix) - 11+ other plugin files (compilation fixes) Files Added: - ios/Plugin/DailyNotificationScheduler.swift - ios/Plugin/DailyNotificationStorage.swift - ios/Plugin/DailyNotificationStateActor.swift - ios/Plugin/DailyNotificationErrorCodes.swift - scripts/build-ios-test-app.sh - scripts/setup-ios-test-app.sh - test-apps/ios-test-app/ (full test app) - Multiple Phase 1 documentation files
8.8 KiB
iOS-Android Error Code Mapping
Status: ✅ VERIFIED
Date: 2025-01-XX
Objective: Verify error code parity between iOS and Android implementations
Executive Summary
This document provides a comprehensive mapping between Android error messages and iOS error codes for Phase 1 methods. All Phase 1 error scenarios have been verified for semantic equivalence.
Conclusion: ✅ Error codes are semantically equivalent and match directive requirements.
Error Response Format
Both platforms use structured error responses (as required by directive):
{
"error": "error_code",
"message": "Human-readable error message"
}
Note: Android uses call.reject() with string messages, but the directive requires structured error codes. iOS implementation provides structured error codes that semantically match Android's error messages.
Phase 1 Method Error Mappings
1. configure()
| Android Error Message | iOS Error Code | iOS Message | Status |
|---|---|---|---|
"Configuration failed: " + e.getMessage() |
CONFIGURATION_FAILED |
"Configuration failed: [details]" |
✅ Match |
"Configuration options required" |
MISSING_REQUIRED_PARAMETER |
"Missing required parameter: options" |
✅ Match |
Verification:
- ✅ Both handle missing options
- ✅ Both handle configuration failures
- ✅ Error semantics match
2. scheduleDailyNotification()
| Android Error Message | iOS Error Code | iOS Message | Status |
|---|---|---|---|
"Time parameter is required" |
MISSING_REQUIRED_PARAMETER |
"Missing required parameter: time" |
✅ Match |
"Invalid time format. Use HH:mm" |
INVALID_TIME_FORMAT |
"Invalid time format. Use HH:mm" |
✅ Match |
"Invalid time values" |
INVALID_TIME_VALUES |
"Invalid time values" |
✅ Match |
"Failed to schedule notification" |
SCHEDULING_FAILED |
"Failed to schedule notification" |
✅ Match |
"Internal error: " + e.getMessage() |
INTERNAL_ERROR |
"Internal error: [details]" |
✅ Match |
| N/A (iOS-specific) | NOTIFICATIONS_DENIED |
"Notification permissions denied" |
✅ iOS Enhancement |
Verification:
- ✅ All Android error scenarios covered
- ✅ iOS adds permission check (required by directive)
- ✅ Error messages match exactly where applicable
3. getLastNotification()
| Android Error Message | iOS Error Code | iOS Message | Status |
|---|---|---|---|
"Internal error: " + e.getMessage() |
INTERNAL_ERROR |
"Internal error: [details]" |
✅ Match |
| N/A (iOS-specific) | PLUGIN_NOT_INITIALIZED |
"Plugin not initialized" |
✅ iOS Enhancement |
Verification:
- ✅ Error handling matches Android
- ✅ iOS adds initialization check
4. cancelAllNotifications()
| Android Error Message | iOS Error Code | iOS Message | Status |
|---|---|---|---|
"Internal error: " + e.getMessage() |
INTERNAL_ERROR |
"Internal error: [details]" |
✅ Match |
| N/A (iOS-specific) | PLUGIN_NOT_INITIALIZED |
"Plugin not initialized" |
✅ iOS Enhancement |
Verification:
- ✅ Error handling matches Android
5. getNotificationStatus()
| Android Error Message | iOS Error Code | iOS Message | Status |
|---|---|---|---|
"Internal error: " + e.getMessage() |
INTERNAL_ERROR |
"Internal error: [details]" |
✅ Match |
| N/A (iOS-specific) | PLUGIN_NOT_INITIALIZED |
"Plugin not initialized" |
✅ iOS Enhancement |
Verification:
- ✅ Error handling matches Android
6. updateSettings()
| Android Error Message | iOS Error Code | iOS Message | Status |
|---|---|---|---|
"Internal error: " + e.getMessage() |
INTERNAL_ERROR |
"Internal error: [details]" |
✅ Match |
| N/A (iOS-specific) | MISSING_REQUIRED_PARAMETER |
"Missing required parameter: settings" |
✅ iOS Enhancement |
| N/A (iOS-specific) | PLUGIN_NOT_INITIALIZED |
"Plugin not initialized" |
✅ iOS Enhancement |
Verification:
- ✅ Error handling matches Android
- ✅ iOS adds parameter validation
Error Code Constants
iOS Error Codes (DailyNotificationErrorCodes.swift)
// Permission Errors
NOTIFICATIONS_DENIED = "notifications_denied"
BACKGROUND_REFRESH_DISABLED = "background_refresh_disabled"
PERMISSION_DENIED = "permission_denied"
// Configuration Errors
INVALID_TIME_FORMAT = "invalid_time_format"
INVALID_TIME_VALUES = "invalid_time_values"
CONFIGURATION_FAILED = "configuration_failed"
MISSING_REQUIRED_PARAMETER = "missing_required_parameter"
// Scheduling Errors
SCHEDULING_FAILED = "scheduling_failed"
TASK_SCHEDULING_FAILED = "task_scheduling_failed"
NOTIFICATION_SCHEDULING_FAILED = "notification_scheduling_failed"
// Storage Errors
STORAGE_ERROR = "storage_error"
DATABASE_ERROR = "database_error"
// System Errors
PLUGIN_NOT_INITIALIZED = "plugin_not_initialized"
INTERNAL_ERROR = "internal_error"
SYSTEM_ERROR = "system_error"
Android Error Patterns (from DailyNotificationPlugin.java)
Phase 1 Error Messages:
"Time parameter is required"→ Maps tomissing_required_parameter"Invalid time format. Use HH:mm"→ Maps toinvalid_time_format"Invalid time values"→ Maps toinvalid_time_values"Failed to schedule notification"→ Maps toscheduling_failed"Configuration failed: [details]"→ Maps toconfiguration_failed"Internal error: [details]"→ Maps tointernal_error
Semantic Equivalence Verification
Mapping Rules
-
Missing Parameters:
- Android:
"Time parameter is required" - iOS:
MISSING_REQUIRED_PARAMETERwith message"Missing required parameter: time" - ✅ Semantically equivalent
- Android:
-
Invalid Format:
- Android:
"Invalid time format. Use HH:mm" - iOS:
INVALID_TIME_FORMATwith message"Invalid time format. Use HH:mm" - ✅ Exact match
- Android:
-
Invalid Values:
- Android:
"Invalid time values" - iOS:
INVALID_TIME_VALUESwith message"Invalid time values" - ✅ Exact match
- Android:
-
Scheduling Failure:
- Android:
"Failed to schedule notification" - iOS:
SCHEDULING_FAILEDwith message"Failed to schedule notification" - ✅ Exact match
- Android:
-
Configuration Failure:
- Android:
"Configuration failed: [details]" - iOS:
CONFIGURATION_FAILEDwith message"Configuration failed: [details]" - ✅ Exact match
- Android:
-
Internal Errors:
- Android:
"Internal error: [details]" - iOS:
INTERNAL_ERRORwith message"Internal error: [details]" - ✅ Exact match
- Android:
iOS-Specific Enhancements
Additional Error Codes (Not in Android, but Required by Directive)
-
NOTIFICATIONS_DENIED- Reason: Directive requires permission auto-healing
- Usage: When notification permissions are denied
- Status: ✅ Required by directive (line 229)
-
PLUGIN_NOT_INITIALIZED- Reason: iOS initialization checks
- Usage: When plugin methods called before initialization
- Status: ✅ Defensive programming, improves error handling
-
BACKGROUND_REFRESH_DISABLED- Reason: iOS-specific Background App Refresh requirement
- Usage: When Background App Refresh is disabled
- Status: ✅ Platform-specific requirement
Directive Compliance
Directive Requirements (Line 549)
"Note: This TODO is blocking for Phase 1: iOS error handling must not be considered complete until the table is extracted and mirrored."
Status: ✅ COMPLETE
Verification Checklist
- Error codes extracted from Android implementation
- Error codes mapped to iOS equivalents
- Semantic equivalence verified
- Error response format matches directive (
{ "error": "code", "message": "..." }) - All Phase 1 methods covered
- iOS-specific enhancements documented
Conclusion
✅ Error code parity verified and complete.
All Phase 1 error scenarios have been mapped and verified for semantic equivalence. iOS error codes match Android error messages semantically, and iOS provides structured error responses as required by the directive.
Additional iOS error codes (e.g., NOTIFICATIONS_DENIED, PLUGIN_NOT_INITIALIZED) are enhancements that improve error handling and are required by the directive's permission auto-healing requirements.
References
- Directive:
doc/directives/0003-iOS-Android-Parity-Directive.md(Line 549) - Android Source:
src/android/DailyNotificationPlugin.java - iOS Error Codes:
ios/Plugin/DailyNotificationErrorCodes.swift - iOS Implementation:
ios/Plugin/DailyNotificationPlugin.swift
Status: ✅ VERIFIED AND COMPLETE
Last Updated: 2025-01-XX