見出し画像

【Swift5】UNCalendarNotificationTriggerで指定日時にローカル通知を飛ばす方法

通知の許可を取得する

import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

   func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
       // Override point for customization after application launch.
       // 通知許可の取得
       UNUserNotificationCenter.current().requestAuthorization(
       options: [.alert, .sound, .badge]){
           (granted, _) in
           if granted{
               UNUserNotificationCenter.current().delegate = self
           }
       }
       
       return true
   }

通知を登録する

func addNotification(alertModel : AlermModel)  {
       let content = UNMutableNotificationContent()
       content.title = "AndroidLikeAlerm"
       content.body = "22:30"
       content.sound = UNNotificationSound.default
                
       let notificationCenter = UNUserNotificationCenter.current()
        
       var dateComponentsDay = DateComponents()
       dateComponentsDay.hour = alertModel.alermTime
       dateComponentsDay.minute = alertModel.alermMinute
        
       let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponentsDay, repeats: false)
        
       let request = UNNotificationRequest(identifier: alertModel.alermId, content: content, trigger: trigger)
        
       notificationCenter.add(request) { (error) in
           if error != nil {
               print(error.debugDescription)
           }
       }
       // 登録されている通知確認
       UNUserNotificationCenter.current().getPendingNotificationRequests {
           print("Pending requests :", $0)
       }
   }

dateComponentsDay.hour,dateComponentsDay.minuteにはInt型をセットしてあげてください。基本的にはラベルなどで時刻表示する際は00埋めをすると思うのでString型で管理する方がベターと思いますが、この時だけInt型に変換してあげてください。

ローカル通知を削除する

   func deleteNotification(alertModel : AlermModel) {
       UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [alertModel.alermId])
       
       // 登録されている通知確認
       UNUserNotificationCenter.current().getPendingNotificationRequests {
           print("DELETE:Pending requests :", $0)
       }
   }

AlertModelについて

//
//  AlermModel.swift
//  AndroidLikeAlerm
//
//  Created by tanukidevelop on 2021/06/27.
//

import Foundation


class AlermModel: NSObject, NSCoding {
   var alermId = ""
   var isOn = false
   var alermTime: Int? = nil
   var alermMinute: Int? = nil
   var isRepert: Bool = false
   var isSunday = false
   var isMonday = false
   var isTuesday = false
   var isWednesday = false
   var isThursday = false
   var isFriday = false
   var isSaturday = false
   var alermLabel = ""
   
   init(alermTime: Int?, alermMinute: Int?, isRepert: Bool, isSunday: Bool, isMonday: Bool,
        isTuesday: Bool, isWednesday: Bool, isThursday: Bool, isFriday: Bool,
        isSaturday: Bool, alermLabel: String) {
       self.alermId = UUID().uuidString
       self.isOn = true
       self.alermTime = alermTime!
       self.alermMinute = alermMinute!
       self.isRepert = isRepert
       self.isSunday = isSunday
       self.isMonday = isMonday
       self.isTuesday = isTuesday
       self.isWednesday = isWednesday
       self.isThursday = isThursday
       self.isFriday = isFriday
       self.isSaturday = isSaturday
       self.alermLabel = alermLabel
   }

   // NSKeyedArchiverに呼び出されるシリアライズ処理(NSCodingで定義されている)
   func encode(with aCoder: NSCoder) {
       aCoder.encode(self.alermId, forKey: "alermId")
       aCoder.encode(self.isOn, forKey: "isOn")
       aCoder.encode(self.alermTime, forKey: "alermTime")
       aCoder.encode(self.alermMinute, forKey: "alermMinute")
       aCoder.encode(self.isSunday, forKey: "isSunday")
       aCoder.encode(self.isMonday, forKey: "isMonday")
       aCoder.encode(self.isTuesday, forKey: "isTuesday")
       aCoder.encode(self.isWednesday, forKey: "isWednesday")
       aCoder.encode(self.isThursday, forKey: "isThursday")
       aCoder.encode(self.isFriday, forKey: "isFriday")
       aCoder.encode(self.isSaturday, forKey: "isSaturday")
       aCoder.encode(self.alermLabel, forKey: "alermLabel")
   }

   // NSKeyedArchiverに呼び出されるデシリアライズ処理(NSCodingで定義されている)
   required init?(coder aDecoder: NSCoder) {
       alermId = aDecoder.decodeObject(forKey: "alermId") as! String
       isOn = aDecoder.decodeBool(forKey: "isOn")
       alermTime = aDecoder.decodeObject(forKey: "alermTime") as! Int
       alermMinute = aDecoder.decodeObject(forKey: "alermMinute") as! Int
       isSunday = aDecoder.decodeBool(forKey: "isSunday")
       isMonday = aDecoder.decodeBool(forKey: "isMonday")
       isTuesday = aDecoder.decodeBool(forKey: "isTuesday")
       isWednesday = aDecoder.decodeBool(forKey: "isWednesday")
       isThursday = aDecoder.decodeBool(forKey: "isThursday")
       isFriday = aDecoder.decodeBool(forKey: "isFriday")
       isSaturday = aDecoder.decodeBool(forKey: "isSaturday")
       alermLabel = aDecoder.decodeObject(forKey: "alermLabel")  as! String

   }
}

こんな感じで作り込んでいました。

self.alermId = UUID().uuidString

データモデルのIDは自動生成で重複しないように作成して、そのIDをそのまま通知のidentifyにあてはめています。

なので、アラームをオンにする時やオフにする時はそのアラームのデータモデルの通知を追加したり、オフにする時はすべて削除できたりします。

画像1


この記事が気に入ったらサポートをしてみませんか?