NativeScript Angular:如何为非本地存储的课程事件提前15分钟通知用户
Hey there! Let's work through how to implement those 15-minute pre-class reminders in your app, even without initial local storage for your schedule data. Here's a practical, step-by-step approach:
1. First: Persist Your Schedule Locally
To trigger notifications even when the app is closed or restarted, you need to store the loaded course schedule locally. NativeScript offers a few easy options for this:
Option 1: Use ApplicationSettings (Simple Key-Value Storage)
This is great for small to medium-sized schedule data:
import { ApplicationSettings } from "@nativescript/core"; // Define your schedule data structure interface ClassSchedule { id: string; courseName: string; startTime: string; // Store as ISO string to avoid date serialization issues // Add other relevant fields (instructor, location, etc.) } // Save schedule after loading from server saveScheduleToLocal(schedule: ClassSchedule[]) { ApplicationSettings.setString("userClassSchedule", JSON.stringify(schedule)); } // Retrieve saved schedule getSavedSchedule(): ClassSchedule[] { const savedData = ApplicationSettings.getString("userClassSchedule"); return savedData ? JSON.parse(savedData) as ClassSchedule[] : []; }
Option 2: Use SQLite (For Larger/Complex Data)
If your schedule has lots of entries or needs querying, use the @nativescript/sqlite plugin to store data in a local database.
2. Implement Local Notifications
NativeScript's @nativescript/local-notifications plugin handles foreground/background notifications seamlessly.
Step 1: Install the Plugin
npm install @nativescript/local-notifications
Step 2: Schedule Reminders for Each Class
Create a function to calculate the reminder time (15 mins before class starts) and schedule notifications. We'll also handle cleaning up old reminders to avoid duplicates:
import { LocalNotifications } from "@nativescript/local-notifications"; import { isIOS } from "@nativescript/core"; scheduleClassReminders(schedule: ClassSchedule[]) { // Cancel existing reminders first to avoid duplicates LocalNotifications.cancelAll().then(() => { const pendingNotifications = schedule.map(classItem => { const classStartTime = new Date(classItem.startTime); const reminderTime = new Date(classStartTime); reminderTime.setMinutes(reminderTime.getMinutes() - 15); // Skip reminders for classes that already passed if (reminderTime <= new Date()) return null; return { id: parseInt(classItem.id), // Unique ID for each notification title: `Reminder: ${classItem.courseName} Starts Soon!`, body: `Your ${classItem.courseName} class begins in 15 minutes.`, at: reminderTime, sound: isIOS ? "default" : null, // iOS requires explicit sound setting payload: { courseId: classItem.id } // Pass data for when user taps the notification }; }).filter(notification => notification !== null); // Schedule all valid reminders LocalNotifications.schedule(pendingNotifications).then( scheduledIds => console.log(`Scheduled ${scheduledIds.length} class reminders`), error => console.error("Failed to schedule reminders:", error) ); }); }
3. Integrate Into Your Existing Workflow
Wire this logic into your component where you load the schedule:
ngOnInit() { this.loadClassScheduleFromServer().then(fetchedSchedule => { // Save to local storage first this.saveScheduleToLocal(fetchedSchedule); // Schedule reminders this.scheduleClassReminders(fetchedSchedule); }); } // Handle user selecting a new course onCourseSelectionChanged(selectedCourseId: string) { this.loadClassScheduleFromServer(selectedCourseId).then(newSchedule => { this.saveScheduleToLocal(newSchedule); this.scheduleClassReminders(newSchedule); // Replaces old reminders }); }
4. Handle App Restarts
Ensure reminders are re-scheduled when the app launches (in case the device was restarted):
Add this to your root app.component.ts:
ngOnInit() { // Request notification permission first (required on iOS/Android) LocalNotifications.requestPermission().then(granted => { if (granted) { const savedSchedule = this.getSavedSchedule(); if (savedSchedule.length > 0) { this.scheduleClassReminders(savedSchedule); } } else { console.log("Notification permission denied; reminders won't work."); } }); }
Key Notes
- Time Zone Handling: Always store
startTimeas an ISO string (e.g.,new Date().toISOString()) to avoid time zone discrepancies when parsing dates locally. - Notification Permissions: Never skip requesting permission—both iOS and Android block notifications by default until the user approves.
- Duplicate Prevention: Canceling all existing reminders before scheduling new ones ensures you don't get multiple alerts for the same class.
内容的提问来源于stack exchange,提问作者Stel Dare

