mirror of
https://github.com/home-assistant/iOS.git
synced 2026-06-16 23:33:36 -05:00
<!-- Thank you for submitting a Pull Request and helping to improve Home Assistant. Please complete the following sections to help the processing and review of your changes. Please do not delete anything from this template. --> ## Summary <!-- Provide a brief summary of the changes you have made and most importantly what they aim to achieve --> For some reason Realm database migration was not being called event though scheme version was already bumped to 28, apparently this was caused by watch complication that was accessing realm passing specific object types Test process: - Checkout commitc257fa21f6- Run App in iPhone and watch (with some Actions created) - Checkout commit2c8470e5fe- Run App in iPhone and watch > - this was crashing in watch and now it is running the migration block. ## Screenshots <!-- If this is a user-facing change not in the frontend, please include screenshots in light and dark mode. --> ## Link to pull request in Documentation repository <!-- Pull requests that add, change or remove functionality must have a corresponding pull request in the Companion App Documentation repository (https://github.com/home-assistant/companion.home-assistant). Please add the number of this pull request after the "#" --> Documentation: home-assistant/companion.home-assistant# ## Any other notes <!-- If there is any other information of note, like if this Pull Request is part of a bigger change, please include it here. -->
139 lines
4.8 KiB
Swift
139 lines
4.8 KiB
Swift
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 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 if complication.identifier == AssistDefaultComplication.defaultComplicationId {
|
|
template = AssistDefaultComplication.createAssistTemplate(for: complication.family)
|
|
} else {
|
|
Current.Log.info {
|
|
"no configured template for \(complication.identifier), providing placeholder"
|
|
}
|
|
|
|
template = ComplicationGroupMember(family: complication.family)
|
|
.fallbackTemplate(for: complication.identifier)
|
|
}
|
|
|
|
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 {
|
|
"Providing template for \(complication.identifier) family \(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
|
|
|
|
func getComplicationDescriptors(handler: @escaping ([CLKComplicationDescriptor]) -> Void) {
|
|
let configured = Current.realm().objects(WatchComplication.self)
|
|
.map(\.complicationDescriptor)
|
|
|
|
let placeholders = ComplicationGroupMember.allCases
|
|
.map(\.placeholderComplicationDescriptor)
|
|
|
|
let assistDefaultComplicationDescriptor = [AssistDefaultComplication.descriptor]
|
|
|
|
handler(configured + placeholders + assistDefaultComplicationDescriptor)
|
|
}
|
|
}
|
|
|
|
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"
|
|
}
|
|
}
|
|
}
|