问题
I made an app that sends a local notification showing the user a random prime number every day at 9 AM.
The issue is that the shown number is always the same.
The code that creates the Notification Request only gets called once (which I kind of expected, being the Notification a repeating one), how then can I update its content?
I can provide the code that generates the random prime number, but I've tested it and it works, so I don't think that's necessary (please let me know if otherwise).
Here's how I create the Notification Request (this is from AppDelegate):
// AppDelegate.swift
import UIKit
import MessageUI
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
// MARK: Properties
var window: UIWindow?
// Life Cycle
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [
UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
// MARK: Notification
// Create notification object
let center = UNUserNotificationCenter.current()
// Set the delegate of the Notification to be AppDelegate file
center.delegate = self
// Create action allowing user to copy number from notification
let copyAction = UNNotificationAction(identifier: "COPY_ACTION",
title: "Copy",
options: UNNotificationActionOptions(rawValue: 0))
// Create category with a copy action
let myCategory = UNNotificationCategory(identifier: "RANDOM",
actions: [copyAction],
intentIdentifiers: [],
hiddenPreviewsBodyPlaceholder: "",
options: .customDismissAction)
center.setNotificationCategories([myCategory])
let options: UNAuthorizationOptions = [.alert, .sound]
center.requestAuthorization(options: options) { (granted, error) in
if !granted {
print("Something went wrong: \(String(describing: error))")
}
}
center.getNotificationSettings { (settings) in
if settings.authorizationStatus != .authorized {
// Notifications not allowed
}
}
// Access view controller containing function that generates random prime numbers
let tab = window?.rootViewController as? UITabBarController
let randomVC = tab?.viewControllers?[3] as? RandomViewController
let content = UNMutableNotificationContent()
content.title = "Your daily prime is:"
// Set body to random prime, or 1 if returned value is nil
content.body = "\(randomVC?.makeRandomNotification() ?? 1)"
content.categoryIdentifier = "RANDOM"
content.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: "choo.caf"))
var date = DateComponents()
date.hour = 9
date.minute = 00
let trigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: true)
let request = UNNotificationRequest(identifier: "RANDOM", content: content, trigger: trigger)
center.add(request)
return true
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
switch response.actionIdentifier {
case "COPY_ACTION":
UIPasteboard.general.string = response.notification.request.content.body
default:
break
}
completionHandler()
}
func userNotificationCenter(
_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .sound])
}
}
Note: I tested this by changing the trigger from a specific time to simply repeating every 60 seconds. Like so:
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 60, repeats: true)
(Un)related:
- Unable to update local scheduled notification content - not a solution. I'm creating a single repeating request (I tried it and it did not work).
- local notification not repeating - Android, not iOS
- Repeating local notification removes previous pending local notifications - Suggested solution not practical
- Ios repeating local notifications - Different question
- repeating local Notifications automatically? - Android, not iOS
回答1:
The content is fixed once you've created the request. If it wasn't, there would be some method your UNUserNotificationCenterDelegate
could use to do it. The code you've written won't be re-called just because the notification repeats.
You basically have three options:
- Use push notifications instead of local notifications, and put the responsibility for generating new daily content in a server somewhere.
- Schedule many individual notifications with their own prime number content (you can have up to 64 at one time) and rely on the user opening your app at some point over the course of two months so that you can schedule more. Note that this means you'll need code to figure out when you already have them scheduled, how many you should add, etc.
- Create a notification content extension* that will allow you to choose a number when the user sees and interacts with your notification.
I think I'd probably lean towards 3, but I haven't personally played with that API yet. It seems closest to what you're wanting to happen: it's essentially a callback -- albeit an elaborate one -- to allow you to "update" the content.
*Also see: 10-minute intro to them at Little Bites of Cocoa
来源:https://stackoverflow.com/questions/54165040/repeating-local-notification-not-updating-content