OSDN Git Service

コード整形
[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     
13     static let Periodic = Notification.Name("com.masakih.KCD.Notification.Periodic")
14 }
15
16 fileprivate extension Selector {
17     
18     static let notifyIfNeeded = #selector(PeriodicNotifier.notifyIfNeeded(_:))
19 }
20
21 final class PeriodicNotifier: NSObject {
22     
23     private let hour: Int
24     private let minutes: Int
25     
26     init(hour: Int, minutes: Int) {
27         
28         self.hour = hour
29         self.minutes = minutes
30         
31         super.init()
32         
33         let nc = NotificationCenter.default
34         nc.addObserver(forName: .NSSystemTimeZoneDidChange, object: nil, queue: nil, using: notify)
35         nc.addObserver(forName: .NSSystemClockDidChange, object: nil, queue: nil, using: notify)
36         nc.addObserver(forName: .NSWorkspaceDidWake, object: nil, queue: nil, using: notify)
37         
38         notifyIfNeeded(nil)
39     }
40     
41     deinit {
42         
43         NotificationCenter.default.removeObserver(self)
44     }
45     
46     private func notify(_ notification: Notification) {
47         
48         notifyIfNeeded(nil)
49     }
50     
51     @objc fileprivate func notifyIfNeeded(_ timer: Timer?) {
52         
53         let now = Date(timeIntervalSinceNow: 0.0)
54         let unit: Set<Calendar.Component> = [.era, .year, .month, .day]
55         var currentDay = Calendar.current.dateComponents(unit, from: now)
56         currentDay.hour = hour
57         currentDay.minute = minutes
58         
59         if let notifyDate = Calendar.current.date(from: currentDay),
60             now.compare(notifyDate) == .orderedDescending {
61             
62             currentDay.day? += 1
63             NotificationCenter.default.post(name: .Periodic, object: self)
64         }
65         
66         if let v = timer?.isValid, v {
67             
68             timer?.invalidate()
69         }
70         
71         guard let nextNotifyDate = Calendar.current.date(from: currentDay)
72             else { fatalError("Can not create time of notify") }
73         
74         let nextNotifyTime = nextNotifyDate.timeIntervalSinceNow + 0.1
75         Timer.scheduledTimer(timeInterval: nextNotifyTime,
76                              target: self,
77                              selector: .notifyIfNeeded,
78                              userInfo: nil,
79                              repeats: false)
80     }
81 }