OSDN Git Service

AppDelegateからウインドウに関する部分を分離した
[kcd/KCD.git] / KCD / PeriodicNotifier.swift
1 //
2 //  PeriodicNotifier.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2017/01/03.
6 //  Copyright © 2017年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10
11 extension Notification.Name {
12     static let Periodic = Notification.Name("com.masakih.KCD.Notification.Periodic")
13 }
14
15 fileprivate extension Selector {
16     static let notifyIfNeeded = #selector(PeriodicNotifier.notifyIfNeeded(_:))
17 }
18
19 class PeriodicNotifier: NSObject {
20     private let hour: Int
21     private let minutes: Int
22     
23     init(hour: Int, minutes: Int) {
24         self.hour = hour
25         self.minutes = minutes
26         super.init()
27         
28         let nc = NotificationCenter.default
29         nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil, using: notify)
30         nc.addObserver(forName: .NSSystemClockDidChange, object: nil, queue: nil, using: notify)
31         nc.addObserver(forName: .NSWorkspaceDidWake, object: nil, queue: nil, using: notify)
32         
33         notifyIfNeeded(nil)
34     }
35     deinit {
36         NotificationCenter.default.removeObserver(self)
37     }
38     
39     private func notify(_ notification: Notification) {
40         notifyIfNeeded(nil)
41     }
42     
43     @objc fileprivate func notifyIfNeeded(_ timer: Timer?) {
44         let now = Date(timeIntervalSinceNow: 0.0)
45         let unit: Set<Calendar.Component> = [.era, .year, .month, .day]
46         var currentDay = Calendar.current.dateComponents(unit, from: now)
47         currentDay.hour = hour
48         currentDay.minute = minutes
49         if let notifyDate = Calendar.current.date(from: currentDay),
50             now.compare(notifyDate) == .orderedDescending {
51             currentDay.day? += 1
52             NotificationCenter.default.post(name: .Periodic, object: self)
53         }
54         if let v = timer?.isValid, v {
55             timer?.invalidate()
56         }
57         guard let nextNotifyDate = Calendar.current.date(from: currentDay)
58             else { fatalError("Can not create time of notify") }
59         let nextNotifyTime = nextNotifyDate.timeIntervalSinceNow + 0.1
60         Timer.scheduledTimer(timeInterval: nextNotifyTime,
61                              target: self,
62                              selector: .notifyIfNeeded,
63                              userInfo: nil,
64                              repeats: false)
65     }
66 }