993 lines
35 KiB
Swift
993 lines
35 KiB
Swift
import Foundation
|
|
import ObjectMapper
|
|
import RealmSwift
|
|
import UIColor_Hex_Swift
|
|
import UIKit
|
|
#if os(watchOS)
|
|
import ClockKit
|
|
#endif
|
|
|
|
public class WatchComplication: Object, ImmutableMappable {
|
|
@objc public dynamic var identifier: String = UUID().uuidString
|
|
@objc public dynamic var serverIdentifier: String?
|
|
|
|
@objc private dynamic var rawFamily: String = ""
|
|
public var Family: ComplicationGroupMember {
|
|
get {
|
|
// Current.Log.verbose("GET Family for str '\(rawFamily)'")
|
|
if let f = ComplicationGroupMember(rawValue: rawFamily) {
|
|
return f
|
|
}
|
|
return ComplicationGroupMember.modularSmall
|
|
}
|
|
set {
|
|
rawFamily = newValue.rawValue
|
|
}
|
|
}
|
|
|
|
@objc private dynamic var rawTemplate: String = ""
|
|
public var Template: ComplicationTemplate {
|
|
get {
|
|
// Current.Log.verbose("GET Template for str '\(rawTemplate)'")
|
|
if let t = ComplicationTemplate(rawValue: rawTemplate) {
|
|
return t
|
|
}
|
|
return Family.templates.first!
|
|
}
|
|
set {
|
|
rawTemplate = newValue.rawValue
|
|
}
|
|
}
|
|
|
|
@objc public dynamic var Data: [String: Any] {
|
|
get {
|
|
guard let dictionaryData = complicationData else {
|
|
return [String: Any]()
|
|
}
|
|
do {
|
|
let dict = try JSONSerialization.jsonObject(with: dictionaryData) as? [String: Any]
|
|
return dict!
|
|
} catch {
|
|
return [String: Any]()
|
|
}
|
|
}
|
|
|
|
set {
|
|
do {
|
|
let data = try JSONSerialization.data(withJSONObject: newValue)
|
|
complicationData = data
|
|
} catch {
|
|
complicationData = nil
|
|
}
|
|
}
|
|
}
|
|
|
|
@objc fileprivate dynamic var complicationData: Data?
|
|
@objc public dynamic var CreatedAt = Date()
|
|
|
|
@objc public dynamic var name: String?
|
|
public var displayName: String {
|
|
name ?? Template.style
|
|
}
|
|
|
|
@objc public dynamic var IsPublic: Bool = true
|
|
|
|
override public static func primaryKey() -> String? {
|
|
"identifier"
|
|
}
|
|
|
|
override public static func ignoredProperties() -> [String] {
|
|
["Family", "Template"]
|
|
}
|
|
|
|
override public required init() {
|
|
super.init()
|
|
}
|
|
|
|
public required init(map: ObjectMapper.Map) throws {
|
|
// this is used for watch<->app syncing
|
|
self.CreatedAt = try map.value("CreatedAt", using: DateTransform())
|
|
super.init()
|
|
self.Template = try map.value("Template")
|
|
self.Data = try map.value("Data")
|
|
self.Family = try map.value("Family")
|
|
self.identifier = try map.value("identifier")
|
|
self.name = try map.value("name")
|
|
self.IsPublic = try map.value("IsPublic")
|
|
self.serverIdentifier = try map.value("serverIdentifier")
|
|
}
|
|
|
|
public func mapping(map: ObjectMapper.Map) {
|
|
Template >>> map["Template"]
|
|
Data >>> map["Data"]
|
|
CreatedAt >>> (map["CreatedAt"], DateTransform())
|
|
Family >>> map["Family"]
|
|
identifier >>> map["identifier"]
|
|
name >>> map["name"]
|
|
IsPublic >>> map["IsPublic"]
|
|
serverIdentifier >>> map["serverIdentifier"]
|
|
}
|
|
|
|
enum RenderedValueType: Hashable {
|
|
case textArea(String)
|
|
case gauge
|
|
case ring
|
|
|
|
init?(stringValue: String) {
|
|
let values = stringValue.components(separatedBy: ",")
|
|
|
|
guard values.count >= 1 else {
|
|
return nil
|
|
}
|
|
|
|
switch values[0] {
|
|
case "textArea" where values.count >= 2:
|
|
self = .textArea(values[1])
|
|
case "gauge":
|
|
self = .gauge
|
|
case "ring":
|
|
self = .ring
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
var stringValue: String {
|
|
switch self {
|
|
case let .textArea(value): return "textArea,\(value)"
|
|
case .gauge: return "gauge"
|
|
case .ring: return "ring"
|
|
}
|
|
}
|
|
}
|
|
|
|
func renderedValues() -> [RenderedValueType: Any] {
|
|
(Data["rendered"] as? [String: Any] ?? [:])
|
|
.compactMapKeys(RenderedValueType.init(stringValue:))
|
|
}
|
|
|
|
func updateRawRendered(from response: [String: Any]) {
|
|
Data["rendered"] = response
|
|
}
|
|
|
|
func rawRendered() -> [String: String] {
|
|
var renders = [RenderedValueType: String]()
|
|
|
|
if let textAreas = Data["textAreas"] as? [String: [String: Any]], textAreas.isEmpty == false {
|
|
let toAdd = textAreas.compactMapValues { $0["text"] as? String }
|
|
.filter { $1.containsJinjaTemplate }
|
|
.mapKeys { RenderedValueType.textArea($0) }
|
|
renders.merge(toAdd, uniquingKeysWith: { a, _ in a })
|
|
}
|
|
|
|
if let gaugeDict = Data["gauge"] as? [String: String],
|
|
let gauge = gaugeDict["gauge"], gauge.containsJinjaTemplate {
|
|
renders[.gauge] = gauge
|
|
}
|
|
|
|
if let ringDict = Data["ring"] as? [String: String],
|
|
let ringValue = ringDict["ring_value"], ringValue.containsJinjaTemplate {
|
|
renders[.ring] = ringValue
|
|
}
|
|
|
|
return renders.mapKeys { $0.stringValue }
|
|
}
|
|
|
|
public static func percentileNumber(from value: Any) -> Float? {
|
|
switch value {
|
|
case let value as String:
|
|
// a bit more forgiving than Float(_:)
|
|
let formatter = NumberFormatter()
|
|
formatter.numberStyle = .decimal
|
|
|
|
for locale in [
|
|
// in HA prior to 0.117 (which returns floats), the return type of a float is a string in templates
|
|
// but it's a non-locale-aware string, so we need to parse `0.33` even if the locale expects `0,33`
|
|
Locale(identifier: "en_US_POSIX"),
|
|
// but since it's free-form text, the user may also have typed `0,33` expecting it to work
|
|
Locale.current,
|
|
] {
|
|
formatter.locale = locale
|
|
if let value = formatter.number(from: value)?.floatValue {
|
|
return value
|
|
}
|
|
}
|
|
|
|
return nil
|
|
case let value as Int:
|
|
return Float(value)
|
|
case let value as Double:
|
|
return Float(value)
|
|
case let value as Float:
|
|
return value
|
|
default:
|
|
Current.Log.info("unsure how to float-ify \(type(of: value)), trying as a string")
|
|
return percentileNumber(from: String(describing: value))
|
|
}
|
|
}
|
|
|
|
#if os(watchOS)
|
|
|
|
public var complicationDescriptor: CLKComplicationDescriptor {
|
|
CLKComplicationDescriptor(
|
|
identifier: identifier,
|
|
displayName: displayName,
|
|
supportedFamilies: [
|
|
Family.family,
|
|
]
|
|
)
|
|
}
|
|
|
|
public var textDataProviders: [String: CLKTextProvider] {
|
|
var providers = [String: CLKTextProvider]()
|
|
|
|
if let textAreas = Data["textAreas"] as? [String: [String: Any]] {
|
|
let rendered = renderedValues()
|
|
for (key, textArea) in textAreas {
|
|
let renderedText = rendered[.textArea(key)].flatMap(String.init(describing:))
|
|
|
|
guard let text = renderedText ?? textArea["text"] as? String else {
|
|
Current.Log.warning("TextArea \(key) doesn't have any text!")
|
|
continue
|
|
}
|
|
guard let color = textArea["color"] as? String else {
|
|
Current.Log.warning("TextArea \(key) doesn't have a text color!")
|
|
continue
|
|
}
|
|
providers[key] = with(CLKSimpleTextProvider(text: text)) {
|
|
$0.tintColor = UIColor(color)
|
|
}
|
|
}
|
|
}
|
|
|
|
return providers
|
|
}
|
|
|
|
public var iconProvider: CLKImageProvider? {
|
|
if let iconDict = Data["icon"] as? [String: String], let iconName = iconDict["icon"],
|
|
let iconColor = iconDict["icon_color"], let iconSize = Template.imageSize {
|
|
let iconColor = UIColor(iconColor)
|
|
let icon = MaterialDesignIcons(named: iconName)
|
|
let image = icon.image(ofSize: iconSize, color: iconColor)
|
|
let provider = CLKImageProvider(onePieceImage: image)
|
|
provider.tintColor = iconColor
|
|
return provider
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
public var fullColorImageProvider: CLKFullColorImageProvider? {
|
|
if let iconDict = Data["icon"] as? [String: String], let iconName = iconDict["icon"],
|
|
let iconColor = iconDict["icon_color"], let iconSize = Template.imageSize {
|
|
let icon = MaterialDesignIcons(named: iconName)
|
|
let image = icon.image(ofSize: iconSize, color: UIColor(iconColor))
|
|
return CLKFullColorImageProvider(fullColorImage: image)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
public var gaugeProvider: CLKSimpleGaugeProvider? {
|
|
guard let info = Data["gauge"] as? [String: String] else {
|
|
return nil
|
|
}
|
|
|
|
let fraction: Float
|
|
|
|
if let renderedFraction = renderedValues()[.gauge], let value = Self.percentileNumber(from: renderedFraction) {
|
|
fraction = value
|
|
} else if let stringFraction = info["gauge"], let value = Self.percentileNumber(from: stringFraction) {
|
|
fraction = value
|
|
} else {
|
|
fraction = 0
|
|
}
|
|
|
|
let color: UIColor
|
|
|
|
if let string = info["gauge_color"] {
|
|
color = UIColor(string)
|
|
} else {
|
|
color = .red
|
|
}
|
|
|
|
let style: CLKGaugeProviderStyle
|
|
|
|
if info["gauge_style"]?.lowercased() == "fill" {
|
|
style = .fill
|
|
} else {
|
|
style = .ring
|
|
}
|
|
|
|
return CLKSimpleGaugeProvider(
|
|
style: style,
|
|
gaugeColor: color,
|
|
fillFraction: fraction
|
|
)
|
|
}
|
|
|
|
public typealias RingData = (fraction: Float, style: CLKComplicationRingStyle, color: UIColor)
|
|
public var ringData: RingData {
|
|
guard let info = Data["ring"] as? [String: String] else {
|
|
return (fraction: 0, style: .closed, color: .red)
|
|
}
|
|
|
|
let fraction: Float
|
|
|
|
if let renderedFraction = renderedValues()[.ring], let value = Self.percentileNumber(from: renderedFraction) {
|
|
fraction = value
|
|
} else if let stringFraction = info["ring_value"], let value = Self.percentileNumber(from: stringFraction) {
|
|
fraction = value
|
|
} else {
|
|
fraction = 0
|
|
}
|
|
|
|
let color: UIColor
|
|
|
|
if let string = info["ring_color"] {
|
|
color = UIColor(string)
|
|
} else {
|
|
color = .red
|
|
}
|
|
|
|
let style: CLKComplicationRingStyle
|
|
|
|
if info["ring_type"]?.lowercased() == "open" {
|
|
style = .open
|
|
} else {
|
|
style = .closed
|
|
}
|
|
|
|
return (fraction: fraction, style: style, color: color)
|
|
}
|
|
|
|
public var column2Alignment: CLKComplicationColumnAlignment {
|
|
let alignment: CLKComplicationColumnAlignment
|
|
|
|
if let info = Data["column2alignment"] as? [String: String], let value = info["column2alignment"] {
|
|
alignment = value.lowercased() == "leading" ? .leading : .trailing
|
|
} else {
|
|
alignment = .leading
|
|
}
|
|
|
|
return alignment
|
|
}
|
|
|
|
// swiftlint:disable:next cyclomatic_complexity
|
|
public func CLKComplicationTemplate(family: CLKComplicationFamily) -> CLKComplicationTemplate? {
|
|
if Template.groupMember != ComplicationGroupMember(family: family) {
|
|
Current.Log.warning("Would have returned template (\(Template)) outside expected family (\(family)")
|
|
return nil
|
|
}
|
|
switch Template {
|
|
case .CircularSmallRingImage:
|
|
let template = CLKComplicationTemplateCircularSmallRingImage()
|
|
if let iconProvider {
|
|
template.imageProvider = iconProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
let ringData = ringData
|
|
template.fillFraction = ringData.fraction
|
|
template.ringStyle = ringData.style
|
|
template.tintColor = ringData.color
|
|
return template
|
|
case .CircularSmallSimpleImage:
|
|
let template = CLKComplicationTemplateCircularSmallSimpleImage()
|
|
if let iconProvider {
|
|
template.imageProvider = iconProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .CircularSmallStackImage:
|
|
let template = CLKComplicationTemplateCircularSmallStackImage()
|
|
if let iconProvider {
|
|
template.line1ImageProvider = iconProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Line2"] {
|
|
template.line2TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .CircularSmallRingText:
|
|
let template = CLKComplicationTemplateCircularSmallRingText()
|
|
if let textProvider = textDataProviders["InsideRing"] {
|
|
template.textProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
let ringData = ringData
|
|
template.fillFraction = ringData.fraction
|
|
template.ringStyle = ringData.style
|
|
template.tintColor = ringData.color
|
|
return template
|
|
case .CircularSmallSimpleText:
|
|
let template = CLKComplicationTemplateCircularSmallSimpleText()
|
|
if let textProvider = textDataProviders["Center"] {
|
|
template.textProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .CircularSmallStackText:
|
|
let template = CLKComplicationTemplateCircularSmallStackText()
|
|
if let textProvider = textDataProviders["Line1"] {
|
|
template.line1TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Line2"] {
|
|
template.line2TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .ExtraLargeRingImage:
|
|
let template = CLKComplicationTemplateExtraLargeRingImage()
|
|
if let iconProvider {
|
|
template.imageProvider = iconProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
let ringData = ringData
|
|
template.fillFraction = ringData.fraction
|
|
template.ringStyle = ringData.style
|
|
template.tintColor = ringData.color
|
|
return template
|
|
case .ExtraLargeSimpleImage:
|
|
let template = CLKComplicationTemplateExtraLargeSimpleImage()
|
|
if let iconProvider {
|
|
template.imageProvider = iconProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .ExtraLargeStackImage:
|
|
let template = CLKComplicationTemplateExtraLargeStackImage()
|
|
if let iconProvider {
|
|
template.line1ImageProvider = iconProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Line2"] {
|
|
template.line2TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .ExtraLargeColumnsText:
|
|
let template = CLKComplicationTemplateExtraLargeColumnsText()
|
|
if let textProvider = textDataProviders["Row1Column1"] {
|
|
template.row1Column1TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Row1Column2"] {
|
|
template.row1Column2TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Row2Column1"] {
|
|
template.row2Column1TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Row2Column2"] {
|
|
template.row2Column2TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
template.column2Alignment = column2Alignment
|
|
return template
|
|
case .ExtraLargeRingText:
|
|
let template = CLKComplicationTemplateExtraLargeRingText()
|
|
if let textProvider = textDataProviders["InsideRing"] {
|
|
template.textProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
let ringData = ringData
|
|
template.fillFraction = ringData.fraction
|
|
template.ringStyle = ringData.style
|
|
template.tintColor = ringData.color
|
|
return template
|
|
case .ExtraLargeSimpleText:
|
|
let template = CLKComplicationTemplateExtraLargeSimpleText()
|
|
if let textProvider = textDataProviders["Center"] {
|
|
template.textProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .ExtraLargeStackText:
|
|
let template = CLKComplicationTemplateExtraLargeStackText()
|
|
if let textProvider = textDataProviders["Line1"] {
|
|
template.line1TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Line2"] {
|
|
template.line2TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .ModularSmallRingImage:
|
|
let template = CLKComplicationTemplateModularSmallRingImage()
|
|
if let iconProvider {
|
|
template.imageProvider = iconProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
let ringData = ringData
|
|
template.fillFraction = ringData.fraction
|
|
template.ringStyle = ringData.style
|
|
template.tintColor = ringData.color
|
|
return template
|
|
case .ModularSmallSimpleImage:
|
|
let template = CLKComplicationTemplateModularSmallSimpleImage()
|
|
if let iconProvider {
|
|
template.imageProvider = iconProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .ModularSmallStackImage:
|
|
let template = CLKComplicationTemplateModularSmallStackImage()
|
|
if let iconProvider {
|
|
template.line1ImageProvider = iconProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Line2"] {
|
|
template.line2TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .ModularSmallColumnsText:
|
|
let template = CLKComplicationTemplateModularSmallColumnsText()
|
|
if let textProvider = textDataProviders["Row1Column1"] {
|
|
template.row1Column1TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Row1Column2"] {
|
|
template.row1Column2TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Row2Column1"] {
|
|
template.row2Column1TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Row2Column2"] {
|
|
template.row2Column2TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
template.column2Alignment = column2Alignment
|
|
return template
|
|
case .ModularSmallRingText:
|
|
let template = CLKComplicationTemplateModularSmallRingText()
|
|
if let textProvider = textDataProviders["InsideRing"] {
|
|
template.textProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
let ringData = ringData
|
|
template.fillFraction = ringData.fraction
|
|
template.ringStyle = ringData.style
|
|
template.tintColor = ringData.color
|
|
return template
|
|
case .ModularSmallSimpleText:
|
|
let template = CLKComplicationTemplateModularSmallSimpleText()
|
|
if let textProvider = textDataProviders["Center"] {
|
|
template.textProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .ModularSmallStackText:
|
|
let template = CLKComplicationTemplateModularSmallStackText()
|
|
if let textProvider = textDataProviders["Line1"] {
|
|
template.line1TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Line2"] {
|
|
template.line2TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .ModularLargeStandardBody:
|
|
let template = CLKComplicationTemplateModularLargeStandardBody()
|
|
if let textProvider = textDataProviders["Header"] {
|
|
template.headerTextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Body1"] {
|
|
template.body1TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Body2"] {
|
|
template.body2TextProvider = textProvider
|
|
} else {
|
|
// optional, allowed to be nil and makes body1 wrap
|
|
}
|
|
return template
|
|
case .ModularLargeTallBody:
|
|
let template = CLKComplicationTemplateModularLargeTallBody()
|
|
if let textProvider = textDataProviders["Header"] {
|
|
template.headerTextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Center"] {
|
|
template.bodyTextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .ModularLargeColumns:
|
|
let template = CLKComplicationTemplateModularLargeColumns()
|
|
if let textProvider = textDataProviders["Row1Column1"] {
|
|
template.row1Column1TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Row1Column2"] {
|
|
template.row1Column2TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Row2Column1"] {
|
|
template.row2Column1TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Row2Column2"] {
|
|
template.row2Column2TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
template.column2Alignment = column2Alignment
|
|
return template
|
|
case .ModularLargeTable:
|
|
let template = CLKComplicationTemplateModularLargeTable()
|
|
if let textProvider = textDataProviders["Header"] {
|
|
template.headerTextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Row1Column1"] {
|
|
template.row1Column1TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Row1Column2"] {
|
|
template.row1Column2TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Row2Column1"] {
|
|
template.row2Column1TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Row2Column2"] {
|
|
template.row2Column2TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
template.column2Alignment = column2Alignment
|
|
return template
|
|
case .UtilitarianSmallFlat:
|
|
let template = CLKComplicationTemplateUtilitarianSmallFlat()
|
|
if let iconProvider {
|
|
template.imageProvider = iconProvider
|
|
} else {
|
|
// optional
|
|
}
|
|
if let textProvider = textDataProviders["Center"] {
|
|
template.textProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .UtilitarianSmallRingImage:
|
|
let template = CLKComplicationTemplateUtilitarianSmallRingImage()
|
|
if let iconProvider {
|
|
template.imageProvider = iconProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
let ringData = ringData
|
|
template.fillFraction = ringData.fraction
|
|
template.ringStyle = ringData.style
|
|
template.tintColor = ringData.color
|
|
return template
|
|
case .UtilitarianSmallRingText:
|
|
let template = CLKComplicationTemplateUtilitarianSmallRingText()
|
|
if let textProvider = textDataProviders["InsideRing"] {
|
|
template.textProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
let ringData = ringData
|
|
template.fillFraction = ringData.fraction
|
|
template.ringStyle = ringData.style
|
|
template.tintColor = ringData.color
|
|
return template
|
|
case .UtilitarianSmallSquare:
|
|
let template = CLKComplicationTemplateUtilitarianSmallSquare()
|
|
if let iconProvider {
|
|
template.imageProvider = iconProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .UtilitarianLargeFlat:
|
|
let template = CLKComplicationTemplateUtilitarianLargeFlat()
|
|
if let textProvider = textDataProviders["Center"] {
|
|
template.textProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let iconProvider {
|
|
template.imageProvider = iconProvider
|
|
} else {
|
|
// optional
|
|
}
|
|
return template
|
|
case .GraphicCornerCircularImage:
|
|
let template = CLKComplicationTemplateGraphicCornerCircularImage()
|
|
if let iconProvider = fullColorImageProvider {
|
|
template.imageProvider = iconProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .GraphicCornerGaugeImage:
|
|
let template = CLKComplicationTemplateGraphicCornerGaugeImage()
|
|
if let iconProvider = fullColorImageProvider {
|
|
template.imageProvider = iconProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let gaugeProvider {
|
|
template.gaugeProvider = gaugeProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Leading"] {
|
|
template.leadingTextProvider = textProvider
|
|
} else {
|
|
// optional
|
|
}
|
|
if let textProvider = textDataProviders["Trailing"] {
|
|
template.trailingTextProvider = textProvider
|
|
} else {
|
|
// optional
|
|
}
|
|
return template
|
|
case .GraphicCornerGaugeText:
|
|
let template = CLKComplicationTemplateGraphicCornerGaugeText()
|
|
if let gaugeProvider {
|
|
template.gaugeProvider = gaugeProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Outer"] {
|
|
template.outerTextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Leading"] {
|
|
template.leadingTextProvider = textProvider
|
|
} else {
|
|
// optional
|
|
}
|
|
if let textProvider = textDataProviders["Trailing"] {
|
|
template.trailingTextProvider = textProvider
|
|
} else {
|
|
// optional
|
|
}
|
|
return template
|
|
case .GraphicCornerStackText:
|
|
let template = CLKComplicationTemplateGraphicCornerStackText()
|
|
if let textProvider = textDataProviders["Outer"] {
|
|
template.outerTextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Inner"] {
|
|
template.innerTextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .GraphicCornerTextImage:
|
|
let template = CLKComplicationTemplateGraphicCornerTextImage()
|
|
if let iconProvider = fullColorImageProvider {
|
|
template.imageProvider = iconProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Center"] {
|
|
template.textProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .GraphicCircularImage:
|
|
let template = CLKComplicationTemplateGraphicCircularImage()
|
|
if let iconProvider = fullColorImageProvider {
|
|
template.imageProvider = iconProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .GraphicCircularClosedGaugeImage:
|
|
let template = CLKComplicationTemplateGraphicCircularClosedGaugeImage()
|
|
if let iconProvider = fullColorImageProvider {
|
|
template.imageProvider = iconProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let gaugeProvider {
|
|
template.gaugeProvider = gaugeProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .GraphicCircularOpenGaugeImage:
|
|
let template = CLKComplicationTemplateGraphicCircularOpenGaugeImage()
|
|
if let iconProvider = fullColorImageProvider {
|
|
template.bottomImageProvider = iconProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let gaugeProvider {
|
|
template.gaugeProvider = gaugeProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Center"] {
|
|
template.centerTextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .GraphicCircularClosedGaugeText:
|
|
let template = CLKComplicationTemplateGraphicCircularClosedGaugeText()
|
|
if let gaugeProvider {
|
|
template.gaugeProvider = gaugeProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Center"] {
|
|
template.centerTextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .GraphicCircularOpenGaugeSimpleText:
|
|
let template = CLKComplicationTemplateGraphicCircularOpenGaugeSimpleText()
|
|
if let gaugeProvider {
|
|
template.gaugeProvider = gaugeProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Center"] {
|
|
template.centerTextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Bottom"] {
|
|
template.bottomTextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .GraphicCircularOpenGaugeRangeText:
|
|
let template = CLKComplicationTemplateGraphicCircularOpenGaugeRangeText()
|
|
if let gaugeProvider {
|
|
template.gaugeProvider = gaugeProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Center"] {
|
|
template.centerTextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Leading"] {
|
|
template.leadingTextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Trailing"] {
|
|
template.trailingTextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .GraphicBezelCircularText:
|
|
let template = CLKComplicationTemplateGraphicBezelCircularText()
|
|
if let iconProvider = fullColorImageProvider {
|
|
template.circularTemplate = with(CLKComplicationTemplateGraphicCircularImage()) {
|
|
$0.imageProvider = iconProvider
|
|
}
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Center"] {
|
|
template.textProvider = textProvider
|
|
} else {
|
|
// optional
|
|
}
|
|
return template
|
|
case .GraphicRectangularStandardBody:
|
|
let template = CLKComplicationTemplateGraphicRectangularStandardBody()
|
|
if let textProvider = textDataProviders["Header"] {
|
|
template.headerTextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Body1"] {
|
|
template.body1TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Body2"] {
|
|
template.body2TextProvider = textProvider
|
|
} else {
|
|
// optional
|
|
}
|
|
return template
|
|
case .GraphicRectangularTextGauge:
|
|
let template = CLKComplicationTemplateGraphicRectangularTextGauge()
|
|
if let gaugeProvider {
|
|
template.gaugeProvider = gaugeProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Header"] {
|
|
template.headerTextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Body1"] {
|
|
template.body1TextProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
case .GraphicRectangularLargeImage:
|
|
let template = CLKComplicationTemplateGraphicRectangularLargeImage()
|
|
if let iconProvider = fullColorImageProvider {
|
|
template.imageProvider = iconProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
if let textProvider = textDataProviders["Header"] {
|
|
template.textProvider = textProvider
|
|
} else {
|
|
return nil
|
|
}
|
|
return template
|
|
}
|
|
}
|
|
|
|
#endif
|
|
}
|