forked from home-assistant/iOS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathComplicationController.swift
142 lines (119 loc) · 5.07 KB
/
ComplicationController.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import ClockKit
import RealmSwift
import Shared
class ComplicationController: NSObject, CLKComplicationDataSource {
// Helpful resources
// https://github.com/LoopKit/Loop/issues/816
// https://crunchybagel.com/detecting-which-complication-was-tapped/
private func complicationModel(for complication: CLKComplication) -> WatchComplication? {
// Helper function to get a complication using the correct ID depending on watchOS version
let model: WatchComplication?
if #available(watchOS 7, *), complication.identifier != CLKDefaultComplicationIdentifier {
// existing complications that were configured pre-7 have no identifier set
// so we can only access the value if it's a valid one. otherwise, fall back to old matching behavior.
model = Current.realm().object(ofType: WatchComplication.self, forPrimaryKey: complication.identifier)
} else {
// we migrate pre-existing complications, and when still using watchOS 6 create new ones,
// with the family as the identifier, so we can rely on this code path for older OS and older complications
let matchedFamily = ComplicationGroupMember(family: complication.family)
model = Current.realm().object(ofType: WatchComplication.self, forPrimaryKey: matchedFamily.rawValue)
}
return model
}
private func template(for complication: CLKComplication) -> CLKComplicationTemplate {
MaterialDesignIcons.register()
let template: CLKComplicationTemplate
if let generated = complicationModel(for: complication)?.CLKComplicationTemplate(family: complication.family) {
template = generated
} else {
Current.Log.info {
if #available(watchOS 7, *) {
return "no configured template for \(complication.identifier), providing placeholder"
} else {
return "no configured template for \(complication.family.rawValue), providing placeholder"
}
}
if #available(watchOS 7, *) {
template = ComplicationGroupMember(family: complication.family)
.fallbackTemplate(for: complication.identifier)
} else {
template = ComplicationGroupMember(family: complication.family)
.fallbackTemplate(for: nil)
}
}
return template
}
// MARK: - Timeline Configuration
func getPrivacyBehavior(
for complication: CLKComplication,
withHandler handler: @escaping (CLKComplicationPrivacyBehavior) -> Void
) {
let model = complicationModel(for: complication)
if model?.IsPublic == false {
handler(.hideOnLockScreen)
} else {
handler(.showOnLockScreen)
}
}
// MARK: - Timeline Population
func getCurrentTimelineEntry(
for complication: CLKComplication,
withHandler handler: @escaping (CLKComplicationTimelineEntry?) -> Void
) {
Current.Log.verbose {
if #available(watchOS 7, *) {
return "Providing template for \(complication.identifier) family \(complication.family.description)"
} else {
return "Providing template for \(complication.family.description)"
}
}
let date = Date().encodedForComplication(family: complication.family) ?? Date()
handler(.init(date: date, complicationTemplate: template(for: complication)))
}
// MARK: - Placeholder Templates
func getLocalizableSampleTemplate(
for complication: CLKComplication,
withHandler handler: @escaping (CLKComplicationTemplate?) -> Void
) {
handler(template(for: complication))
}
// MARK: - Complication Descriptors
@available(watchOS 7.0, *)
func getComplicationDescriptors(handler: @escaping ([CLKComplicationDescriptor]) -> Void) {
let configured = Current.realm().objects(WatchComplication.self)
.map(\.complicationDescriptor)
let placeholders = ComplicationGroupMember.allCases
.map(\.placeholderComplicationDescriptor)
handler(configured + placeholders)
}
}
extension CLKComplicationFamily {
var description: String {
switch self {
case .circularSmall:
return "Circular Small"
case .extraLarge:
return "Extra Large"
case .graphicBezel:
return "Graphic Bezel"
case .graphicCircular:
return "Graphic Circular"
case .graphicCorner:
return "Graphic Corner"
case .graphicRectangular:
return "Graphic Rectangular"
case .modularLarge:
return "Modular Large"
case .modularSmall:
return "Modular Small"
case .utilitarianLarge:
return "Utilitarian Large"
case .utilitarianSmall:
return "Utilitarian Small"
case .utilitarianSmallFlat:
return "Utilitarian Small Flat"
default:
return "unknown"
}
}
}