Swiftのローカル通知の更新は「更新」ではなく「置き換え」が正しい
Swiftのローカル通知の更新でハマったのでメモしておきます。結論はタイトルのとおりです。
ローカル通知の更新がうまくいかない
以下のようなローカル通知を登録したあと、通知の時間やメッセージ内容を変更したいときがありました。
let content = UNMutableNotificationContent()
content.title = "title"
content.body = "body"
content.sound = UNNotificationSound.default()
// 毎日8:30に通知する
var date = DateComponents()
date.hour = 8
date.minute = 30
let trigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: true)
let request = UNNotificationRequest(identifier: "xxx", content: content, trigger: trigger)
let center = UNUserNotificationCenter.current()
center.add(request) { (error : Error?) in
if let theError = error {
// Handle any errors
}
}
以下は更新後に通知されない例です。更新対象が通知時間とメッセージ内容だけだったので、content.body
とtrigger
の内容を設定して登録内容を更新しています。
let content = UNMutableNotificationContent()
content.body = "BODY" // 更新対象
// 毎日9:00に通知する
var date = DateComponents()
date.hour = 9 // 更新対象
date.minute = 0 // 更新対象
let trigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: true)
let request = UNNotificationRequest(identifier: "xxx", content: content, trigger: trigger)
let center = UNUserNotificationCenter.current()
center.add(request) { (error : Error?) in
if let theError = error {
// Handle any errors
}
}
ローカル通知の更新は「更新」ではなく「置き換え」が正しい
なぜ更新後に通知されないんだろうと思い、改めて公式ドキュメントを確認すると答えが書いてありました。要は、通知の更新 = 登録されている通知(identifierが同じ通知)との置き換えである、ということです。
The system uses the identifier parameter to determine how to handle the request:
- If you provide a unique identifier, the system creates a new notification.
- If the identifier matches a previously delivered notification, the system alerts the user again, replaces the old notification with the new one, and places the new notification at the top of the list.
- If the identifier matches a pending request, the new request replaces the pending request.
init(identifier:content:trigger:) | Apple Developer Documentation
上記のコードだと、更新対象外のcontent.title
やcontent.sound
を設定しなかったことで、それぞれが空で登録され、通知されなかったということです。これを踏まえ、通知内容を正しく更新するコードは以下のとおりです。
let content = UNMutableNotificationContent()
content.title = "title" // 更新対象外の値も設定する
content.body = "BODY" // 更新対象
content.sound = UNNotificationSound.default() // 更新対象外の値も設定する
// 毎日9:00に通知する
var date = DateComponents()
date.hour = 9 // 更新対象
date.minute = 0 // 更新対象
let trigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: true)
let request = UNNotificationRequest(identifier: "xxx", content: content, trigger: trigger)
let center = UNUserNotificationCenter.current()
center.add(request) { (error : Error?) in
if let theError = error {
// Handle any errors
}
}
参考リンク
- UNMutableNotificationContent | Apple Developer Documentation
- init(identifier:content:trigger:) | Apple Developer Documentation
Author And Source
この問題について(Swiftのローカル通知の更新は「更新」ではなく「置き換え」が正しい), 我々は、より多くの情報をここで見つけました https://zenn.dev/donchan922/articles/4a4531b0ac5fb7著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Collection and Share based on the CC protocol