- Update Android manifest, Java imports, and capacitor.plugins.json to use org.timesafari.dailynotification (receivers, intent action, plugin classpath) - Update iOS Info.plist BGTaskSchedulerPermittedIdentifiers to org.timesafari.* - Bump @timesafari/daily-notification-plugin 1.3.3 → 2.0.0 (package-lock, Podfile.lock) - Update docs and test-notification-receiver.sh to reference new package/action names - Lockfile: minor bumps for @expo/cli, @expo/fingerprint, @expo/router-server, babel-preset-expo
107 lines
5.9 KiB
Markdown
107 lines
5.9 KiB
Markdown
# Daily Notification Plugin: Alignment Outline
|
||
|
||
**Purpose:** Checklist of changes/additions needed in this app to align with the test app (`daily-notification-plugin/test-apps/daily-notification-test`) so that:
|
||
|
||
1. **Rollover recovery** (and rollover itself) works.
|
||
2. **Notifications show when the app is in the foreground** (not only background/closed).
|
||
3. **Plugin loads at app launch** so recovery runs after reboot without the user opening notification UI.
|
||
|
||
**Reference:** Test app at
|
||
`/Users/aardimus/Sites/trentlarson/daily-notification-plugin_test/daily-notification-plugin/test-apps/daily-notification-test`
|
||
|
||
---
|
||
|
||
## 1. iOS AppDelegate
|
||
|
||
**File:** `ios/App/App/AppDelegate.swift`
|
||
|
||
### 1.1 Add imports
|
||
|
||
- [ ] `import UserNotifications`
|
||
- [ ] Import the Daily Notification plugin framework (Swift module name: **TimesafariDailyNotificationPlugin** per this app’s Podfile; test app uses **DailyNotificationPlugin**)
|
||
|
||
### 1.2 Conform to `UNUserNotificationCenterDelegate`
|
||
|
||
- [ ] Add `, UNUserNotificationCenterDelegate` to the class declaration:
|
||
`class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate`
|
||
|
||
### 1.3 Force-load plugin at launch
|
||
|
||
- [ ] In `application(_:didFinishLaunchingWithOptions:)`, **before** other setup, add logic to force-load the plugin class (e.g. `_ = DailyNotificationPlugin.self` or the class exposed by the TimesafariDailyNotificationPlugin pod) so that the plugin’s `load()` (and thus `performRecovery()`) runs at app launch, not only when JS first calls the plugin.
|
||
|
||
### 1.4 Set notification center delegate
|
||
|
||
- [ ] In `didFinishLaunchingWithOptions`, set:
|
||
`UNUserNotificationCenter.current().delegate = self`
|
||
- [ ] In `applicationDidBecomeActive`, **re-set** the same delegate (in case Capacitor or another component clears it).
|
||
|
||
### 1.5 Implement `userNotificationCenter(_:willPresent:withCompletionHandler:)`
|
||
|
||
- [ ] When a notification is delivered (including in foreground), read `notification_id` and `scheduled_time` from `notification.request.content.userInfo`.
|
||
- [ ] Post rollover event:
|
||
`NotificationCenter.default.post(name: NSNotification.Name("DailyNotificationDelivered"), object: nil, userInfo: ["notification_id": id, "scheduled_time": scheduledTime])`
|
||
- [ ] Call completion handler with presentation options so the notification is shown in foreground, e.g.
|
||
`completionHandler([.banner, .sound, .badge])` (use `.alert` on iOS 13 if needed).
|
||
|
||
### 1.6 Implement `userNotificationCenter(_:didReceive:withCompletionHandler:)`
|
||
|
||
- [ ] Handle notification tap/interaction; call `completionHandler()` when done.
|
||
|
||
---
|
||
|
||
## 2. Android Manifest
|
||
|
||
**File:** `android/app/src/main/AndroidManifest.xml`
|
||
|
||
### 2.1 Fix receiver placement
|
||
|
||
- [ ] Move the two `<receiver>` elements (**DailyNotificationReceiver** and **BootReceiver**) **inside** the `<application>` block (e.g. after `<activity>...</activity>` and before `<provider>...</provider>`).
|
||
- [ ] Remove the stray second `</application>` so there is a single `<application>...</application>` containing activity, receivers, and provider.
|
||
|
||
### 2.2 (Optional) Add NotifyReceiver
|
||
|
||
- [ ] If the plugin’s Android integration expects **NotifyReceiver** for alarm-based delivery, add a `<receiver>` for `org.timesafari.dailynotification.NotifyReceiver` inside `<application>` (see test app manifest for exact declaration).
|
||
|
||
### 2.3 (Optional) BootReceiver options
|
||
|
||
- [ ] Consider aligning with test app: add `android:directBootAware="true"`, `android:exported="true"`, and intent-filter actions `LOCKED_BOOT_COMPLETED`, `MY_PACKAGE_REPLACED`, `PACKAGE_REPLACED` if you need the same boot/update behavior.
|
||
|
||
---
|
||
|
||
## 3. Capacitor / JS startup (optional but recommended)
|
||
|
||
**File:** `src/main.capacitor.ts` (or the main entry used for native builds)
|
||
|
||
### 3.1 Load plugin at startup
|
||
|
||
- [ ] Add a top-level import or an early call that touches the Daily Notification plugin so the JS side loads it at app startup (e.g. `import "@timesafari/daily-notification-plugin"` or a small init that calls `getRebootRecoveryStatus()` or `configure()`).
|
||
This ensures the plugin is loaded as soon as the app runs; together with the iOS force-load in AppDelegate, recovery runs at launch.
|
||
|
||
---
|
||
|
||
## 4. Plugin configuration (optional)
|
||
|
||
- [ ] If you use the native fetcher or need plugin config (db path, storage, etc.), call `DailyNotification.configure()` and/or `configureNativeFetcher()` when appropriate (e.g. after login or when notification UI is first used), similar to the test app’s `configureNativeFetcher()` in HomeView.
|
||
|
||
---
|
||
|
||
## 5. Summary table
|
||
|
||
| Area | Change / addition |
|
||
|-------------------------|------------------------------------------------------------------------------------|
|
||
| **iOS AppDelegate** | Conform to `UNUserNotificationCenterDelegate`; set delegate; force-load plugin; implement `willPresent` (post `DailyNotificationDelivered` + show in foreground) and `didReceive`. |
|
||
| **Android manifest** | Move DailyNotificationReceiver and BootReceiver inside `<application>`; remove duplicate `</application>`; optionally add NotifyReceiver and BootReceiver options. |
|
||
| **main.capacitor.ts** | Optionally import or call plugin at startup so it (and recovery) load at launch. |
|
||
| **Plugin config** | Optionally call `configure()` / `configureNativeFetcher()` where appropriate. |
|
||
|
||
---
|
||
|
||
## 6. Verification
|
||
|
||
After making the changes:
|
||
|
||
- [ ] **iOS:** Build and run; trigger a daily notification and confirm it appears when the app is in the foreground.
|
||
- [ ] **iOS:** Confirm rollover (next day’s schedule) still occurs after a notification fires (check logs for `DNP-ROLLOVER` / `DailyNotificationDelivered`).
|
||
- [ ] **iOS:** Restart the app (or reboot) and confirm recovery runs without opening the notification settings screen (e.g. logs show plugin load and recovery).
|
||
- [ ] **Android:** Build and run; confirm receivers are registered (no manifest errors) and that notifications and boot recovery behave as expected.
|