【Swift4】UNUserNotificationCenterで通知が出ない。.quarterが邪魔だった。

以前の投稿で5秒後に通知を出すというところまでやった。
【Swift4】【Objective-C】UNUserNotificationCenterで通知の許可をもらう。 | iPhoneアプリ備忘録

しかし、現在時刻を取得して5秒後の時刻に鳴るようにしても通知が来ない。
なのでいろいろ試してみた。

まずは前回の復習から。
AppDelegateでゴニョゴニョしてViewControllerで前回も書いた5秒後に通知のコードを書いて、
未通知を呼び出すコードを書いてみる。

    func fiveMinute()  {
        //ローカル通知の設定
        let content = UNMutableNotificationContent()
        content.title = "Title"
        content.subtitle = "Subtitle" // 新登場!
        content.body = "Body"
        content.sound = UNNotificationSound.default
        
        // 5秒後に発火
        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
        let request = UNNotificationRequest(identifier: "FiveSecond",
                                            content: content,
                                            trigger: trigger)
        
        // ローカル通知予約
        UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
        
        //ノーティフィケーションの確認
        UNUserNotificationCenter.current().getPendingNotificationRequests(completionHandler: {
            (notficiations) in
            for localNotification in notficiations {
                print("ノーティフィケーション",localNotification)
            }
        })
    }

これを走らせるとデバッグエリアに通知の設定が表示されて5秒後に通知が出る。

ノーティフィケーション <UNNotificationRequest: 0x60000290c930; identifier: FiveSecond, content: <UNNotificationContent: 0x60000125aac0; title: Title, subtitle: Subtitle, body: Body, summaryArgument: , summaryArgumentCount: 0, categoryIdentifier: , launchImageName: , threadIdentifier: , attachments: (
), badge: (null), sound: <UNNotificationSound: 0x6000003513e0>,, trigger: <UNTimeIntervalNotificationTrigger: 0x6000027425e0; repeats: NO, timeInterval: 5.000000>>

今度はトリガーをインターバルのUNTimeIntervalNotificationTriggerから
カレンダーのUNCalendarNotificationTriggerで、現在時刻をDate()で取得し5秒後を指定してみる。
コードはこんな感じ。

    func dateNotification() {
        //ローカル通知の設定
        let content = UNMutableNotificationContent()
        content.title = "Title"
        content.subtitle = "Subtitle" // 新登場!
        content.body = "Body"
        content.sound = UNNotificationSound.default
        
        
        var dateComponents = DateComponents()
        dateComponents = Calendar.current.dateComponents(in: TimeZone.current, from:Date() + 5)
        print("でーとこんぽーねんつ",dateComponents)
        
        // 5秒後に発火
        let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
//        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
        let request = UNNotificationRequest(identifier: "FiveSecond",
                                            content: content,
                                            trigger: trigger)
        
        // ローカル通知予約
        UNUserNotificationCenter.current().add(request, withCompletionHandler: { (error) in
                    if let error = error {
                        print("エラー",error)
                    } else{
                        print("エラーじゃない?")
                    }
                })

        //ノーティフィケーションの確認
        UNUserNotificationCenter.current().getPendingNotificationRequests(completionHandler: {
            (notficiations) in
            for localNotification in notficiations {
                print("ノーティフィケーション",localNotification)
            }
        })
    }

これを走らせると、下記の通り。

でーとこんぽーねんつ calendar: gregorian (current) timeZone: Asia/Tokyo (current) era: 1 year: 2019 month: 3 day: 19 hour: 16 minute: 2 second: 5 nanosecond: 610242009 weekday: 3 weekdayOrdinal: 3 quarter: 0 weekOfMonth: 4 weekOfYear: 12 yearForWeekOfYear: 2019 isLeapMonth: false 

dateComponentsの内容だけで、ノーティフィケーションは表示されず通知も出なかった。
特にXcodeでエラーも出てないのにノーティフィケーションに登録されなかったようだ。

let date = Date() から取ってくるのではなく、
dateComponentsを指定すると通るので、dateComponentsの何かが悪さしているっぽいのでいろいろとnilを入れて試してみた。

var dateComponents = DateComponents()
dateComponents = Calendar.current.dateComponents(in: TimeZone.current, from:Date() + 5)
// dateComponents.calendar = nil
// dateComponents.timeZone = nil
// dateComponents.era = nil
// dateComponents.year = nil
// dateComponents.weekday = nil
// dateComponents.yearForWeekOfYear = nil
// dateComponents.weekOfYear = nil
// dateComponents.weekOfMonth = nil
// dateComponents.weekdayOrdinal = nil
dateComponents.quarter = nil
print(“でーとこんぽーねんつ”,dateComponents)

結果、dateComponents.quarter が入ってると駄目なようだ。
これで一日費やした。/(^o^)\

オマケ。
アラームに使うために.quarterと秒数を取った日付の取り方。

        //アラーム用にquarterをとって、秒を0に。
        var dateComponents = DateComponents()
        dateComponents = Calendar.current.dateComponents(in: TimeZone.current, from:Date())
        dateComponents.quarter = nil
        dateComponents.second = 0
        dateComponents.nanosecond = 0
        let date = Calendar.current.date(from: dateComponents)

参考サイト
DateComponentsの各要素について調べてみた – Swiftをはじめよう!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です