From deea4551f01f404d4edfb108dcfbc0d49111e760 Mon Sep 17 00:00:00 2001 From: apabari Date: Mon, 15 Oct 2018 13:09:12 -0400 Subject: [PATCH 1/6] Apple Watch Series 4 Complications Enhancements for Apple Watch Series 4 --> .graphicCorner (Outer Text: Glucose and Trend, Inner Text: time) --> .graphicCircular (Full Ring with Current Glucose in Center, Trend Arrow Below) --- CLKComplicationTemplate.swift | 133 +++++++++++++++++++++++++++++ ComplicationController.swift | 154 ++++++++++++++++++++++++++++++++++ Info.plist | 56 +++++++++++++ 3 files changed, 343 insertions(+) create mode 100644 CLKComplicationTemplate.swift create mode 100644 ComplicationController.swift create mode 100644 Info.plist diff --git a/CLKComplicationTemplate.swift b/CLKComplicationTemplate.swift new file mode 100644 index 0000000000..758a643f2d --- /dev/null +++ b/CLKComplicationTemplate.swift @@ -0,0 +1,133 @@ +// +// CLKComplicationTemplate.swift +// Naterade +// +// Created by Nathan Racklyeft on 11/26/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import ClockKit +import HealthKit +import LoopKit +import Foundation + + +extension CLKComplicationTemplate { + + static func templateForFamily(_ family: CLKComplicationFamily, from context: WatchContext) -> CLKComplicationTemplate? { + guard let glucose = context.glucose, let unit = context.preferredGlucoseUnit else { + return nil + } + + return templateForFamily(family, glucose: glucose, unit: unit, date: context.glucoseDate, trend: context.glucoseTrend, eventualGlucose: context.eventualGlucose) + } + + static func templateForFamily(_ family: CLKComplicationFamily, glucose: HKQuantity, unit: HKUnit, date: Date?, trend: GlucoseTrend?, eventualGlucose: HKQuantity?) -> CLKComplicationTemplate? { + + let formatter = NumberFormatter.glucoseFormatter(for: unit) + + guard let glucoseString = formatter.string(from: glucose.doubleValue(for: unit)), + let date = date else + { + return nil + } + + let glucoseAndTrend = "\(glucoseString)\(trend?.symbol ?? " ")" + var accessibilityStrings = [glucoseString] + + if let trend = trend { + accessibilityStrings.append(trend.localizedDescription) + } + + let glucoseAndTrendText = CLKSimpleTextProvider(text: glucoseAndTrend, shortText: glucoseString, accessibilityLabel: accessibilityStrings.joined(separator: ", ")) + let timeText = CLKRelativeDateTextProvider(date: date, style: .natural, units: .minute) + + let timeFormatter = DateFormatter() + timeFormatter.dateStyle = .none + timeFormatter.timeStyle = .short + + + switch family { + case .graphicCorner: + // *************************************** + // ** Apple Watch Series 4 Complication ** + // *************************************** + // Corner Text + // Outer Text: Current Glucose and Trend + // Inner Text: timeText + + if #available(watchOSApplicationExtension 5.0, *) { + let cornerTemplate = CLKComplicationTemplateGraphicCornerStackText() + cornerTemplate.outerTextProvider = glucoseAndTrendText + cornerTemplate.outerTextProvider.tintColor = .green + cornerTemplate.innerTextProvider = timeText + return cornerTemplate + } else { + // Fallback on earlier versions + return nil + } + case .graphicCircular: + // *************************************** + // ** Apple Watch Series 4 Complication ** + // *************************************** + // Circular Gauge + // Full Ring + // Current Glucose in Center, Trend Arrow Below + // * future enhancement - update gauge colors to reflect loop status, or time in range for the day + if #available(watchOSApplicationExtension 5.0, *) { + let circularTemplate = CLKComplicationTemplateGraphicCircularOpenGaugeSimpleText() + circularTemplate.gaugeProvider = CLKSimpleGaugeProvider(style: .fill, gaugeColor: .green, fillFraction: 1) + circularTemplate.centerTextProvider = CLKSimpleTextProvider(text: glucoseString) + circularTemplate.bottomTextProvider = CLKSimpleTextProvider(text: (trend?.symbol ?? " ")) + return circularTemplate + } else { + // Fallback on earlier versions + return nil + } + case .graphicRectangular, .graphicBezel: + return nil + case .modularSmall: + let template = CLKComplicationTemplateModularSmallStackText() + template.line1TextProvider = glucoseAndTrendText + template.line2TextProvider = timeText + return template + case .modularLarge: + let template = CLKComplicationTemplateModularLargeTallBody() + template.bodyTextProvider = glucoseAndTrendText + template.headerTextProvider = timeText + return template + case .circularSmall: + let template = CLKComplicationTemplateCircularSmallSimpleText() + template.textProvider = CLKSimpleTextProvider(text: glucoseString) + return template + case .extraLarge: + let template = CLKComplicationTemplateExtraLargeStackText() + template.line1TextProvider = glucoseAndTrendText + template.line2TextProvider = timeText + return template + case .utilitarianSmall, .utilitarianSmallFlat: + let template = CLKComplicationTemplateUtilitarianSmallFlat() + template.textProvider = CLKSimpleTextProvider(text: glucoseString) + + return template + case .utilitarianLarge: + var eventualGlucoseText = "" + if let eventualGlucose = eventualGlucose, + let eventualGlucoseString = formatter.string(from: eventualGlucose.doubleValue(for: unit)) + { + eventualGlucoseText = eventualGlucoseString + } + + let template = CLKComplicationTemplateUtilitarianLargeFlat() + let format = NSLocalizedString("UtilitarianLargeFlat", tableName: "ckcomplication", comment: "Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time)") + + template.textProvider = CLKSimpleTextProvider(text: String(format: format, arguments: [ + glucoseAndTrend, + eventualGlucoseText, + timeFormatter.string(from: date) + ] + )) + return template + } + } +} diff --git a/ComplicationController.swift b/ComplicationController.swift new file mode 100644 index 0000000000..d632954571 --- /dev/null +++ b/ComplicationController.swift @@ -0,0 +1,154 @@ +// +// ComplicationController.swift +// WatchApp Extension +// +// Created by Nathan Racklyeft on 8/29/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +import ClockKit +import WatchKit + + +final class ComplicationController: NSObject, CLKComplicationDataSource { + + // MARK: - Timeline Configuration + + func getSupportedTimeTravelDirections(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimeTravelDirections) -> Void) { + handler([.backward]) + } + + func getTimelineStartDate(for complication: CLKComplication, withHandler handler: @escaping (Date?) -> Void) { + if let date = ExtensionDelegate.shared().lastContext?.glucoseDate { + handler(date) + } else { + handler(nil) + } + } + + func getTimelineEndDate(for complication: CLKComplication, withHandler handler: @escaping (Date?) -> Void) { + if let date = ExtensionDelegate.shared().lastContext?.glucoseDate { + handler(date) + } else { + handler(nil) + } + } + + func getPrivacyBehavior(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationPrivacyBehavior) -> Void) { + handler(.hideOnLockScreen) + } + + // MARK: - Timeline Population + + private lazy var formatter = NumberFormatter() + + func getCurrentTimelineEntry(for complication: CLKComplication, withHandler handler: (@escaping (CLKComplicationTimelineEntry?) -> Void)) { + let entry: CLKComplicationTimelineEntry? + + if let context = ExtensionDelegate.shared().lastContext, + let glucoseDate = context.glucoseDate, + glucoseDate.timeIntervalSinceNow.minutes >= -15, + let template = CLKComplicationTemplate.templateForFamily(complication.family, from: context) + { + template.tintColor = UIColor.tintColor + entry = CLKComplicationTimelineEntry(date: glucoseDate, complicationTemplate: template) + } else { + entry = nil + } + + handler(entry) + } + + func getTimelineEntries(for complication: CLKComplication, before date: Date, limit: Int, withHandler handler: (@escaping ([CLKComplicationTimelineEntry]?) -> Void)) { + // Call the handler with the timeline entries prior to the given date + handler(nil) + } + + func getTimelineEntries(for complication: CLKComplication, after date: Date, limit: Int, withHandler handler: (@escaping ([CLKComplicationTimelineEntry]?) -> Void)) { + // Call the handler with the timeline entries after to the given date + let entries: [CLKComplicationTimelineEntry]? + + if let context = ExtensionDelegate.shared().lastContext, + let glucoseDate = context.glucoseDate, + glucoseDate.timeIntervalSince(date) > 0, + let template = CLKComplicationTemplate.templateForFamily(complication.family, from: context) + { + template.tintColor = UIColor.tintColor + entries = [CLKComplicationTimelineEntry(date: glucoseDate, complicationTemplate: template)] + } else { + entries = nil + } + + handler(entries) + } + + // MARK: - Placeholder Templates + + func getLocalizableSampleTemplate(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTemplate?) -> Void) { + + let template: CLKComplicationTemplate? + + let glucoseText = CLKSimpleTextProvider.localizableTextProvider(withStringsFileTextKey: "120↘︎", shortTextKey: "120") + let timeText = CLKRelativeDateTextProvider(date: Date(), style: .natural, units: .minute) + + switch complication.family { + + case .graphicCorner: + if #available(watchOSApplicationExtension 5.0, *) { + let cornerTemplate = CLKComplicationTemplateGraphicCornerStackText() + cornerTemplate.outerTextProvider = glucoseText + cornerTemplate.innerTextProvider = timeText + cornerTemplate.outerTextProvider.tintColor = .green + template = cornerTemplate + } else { + // Fallback on earlier versions + template = nil + } + case .graphicCircular: + if #available(watchOSApplicationExtension 5.0, *) { + let circularTemplate = CLKComplicationTemplateGraphicCircularOpenGaugeSimpleText() + circularTemplate.gaugeProvider = CLKSimpleGaugeProvider(style: .fill, gaugeColor: .green, fillFraction: 1) + circularTemplate.centerTextProvider = CLKSimpleTextProvider(text: "120") + circularTemplate.bottomTextProvider = CLKSimpleTextProvider(text: "↘︎") + template = circularTemplate + } else { + // Fallback on earlier versions + template = nil + } + case .graphicRectangular, .graphicBezel: + template = nil + case .modularSmall: + let modularSmall = CLKComplicationTemplateModularSmallStackText() + modularSmall.line1TextProvider = glucoseText + modularSmall.line2TextProvider = timeText + template = modularSmall + case .modularLarge: + let modularSmall = CLKComplicationTemplateModularLargeTallBody() + modularSmall.bodyTextProvider = glucoseText + modularSmall.headerTextProvider = timeText + template = modularSmall + case .circularSmall: + let circularSmall = CLKComplicationTemplateCircularSmallSimpleText() + circularSmall.textProvider = glucoseText + template = circularSmall + case .extraLarge: + let extraLarge = CLKComplicationTemplateExtraLargeStackText() + extraLarge.line1TextProvider = glucoseText + extraLarge.line2TextProvider = timeText + template = extraLarge + case .utilitarianSmall, .utilitarianSmallFlat: + let utilitarianSmallFlat = CLKComplicationTemplateUtilitarianSmallFlat() + utilitarianSmallFlat.textProvider = glucoseText + template = utilitarianSmallFlat + case .utilitarianLarge: + let utilitarianLarge = CLKComplicationTemplateUtilitarianLargeFlat() + let eventualGlucoseText = CLKSimpleTextProvider.localizableTextProvider(withStringsFileTextKey: "75") + utilitarianLarge.textProvider = CLKSimpleTextProvider.localizableTextProvider(withStringsFileFormatKey: "UtilitarianLargeFlat", textProviders: [glucoseText, eventualGlucoseText, CLKTimeTextProvider(date: Date())]) + template = utilitarianLarge + } + + template?.tintColor = UIColor.tintColor + handler(template) + + } +} diff --git a/Info.plist b/Info.plist new file mode 100644 index 0000000000..d9ff34f6f8 --- /dev/null +++ b/Info.plist @@ -0,0 +1,56 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + WatchApp Extension + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + XPC! + CFBundleShortVersionString + 1.9.3 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + CLKComplicationPrincipalClass + $(PRODUCT_MODULE_NAME).ComplicationController + CLKComplicationSupportedFamilies + + CLKComplicationFamilyCircularSmall + CLKComplicationFamilyExtraLarge + CLKComplicationFamilyGraphicBezel + CLKComplicationFamilyGraphicCircular + CLKComplicationFamilyGraphicCorner + CLKComplicationFamilyGraphicRectangular + CLKComplicationFamilyModularLarge + CLKComplicationFamilyModularSmall + CLKComplicationFamilyUtilitarianLarge + CLKComplicationFamilyUtilitarianSmall + CLKComplicationFamilyUtilitarianSmallFlat + + NSExtension + + NSExtensionAttributes + + WKAppBundleIdentifier + $(MAIN_APP_BUNDLE_IDENTIFIER).LoopWatch + + NSExtensionPointIdentifier + com.apple.watchkit + + RemoteInterfacePrincipalClass + $(PRODUCT_MODULE_NAME).StatusInterfaceController + WKExtensionDelegateClassName + $(PRODUCT_MODULE_NAME).ExtensionDelegate + + From e2c3104a4ad08a1c56cde5cdea6cadd4241f3aab Mon Sep 17 00:00:00 2001 From: apabari Date: Mon, 15 Oct 2018 13:12:59 -0400 Subject: [PATCH 2/6] Delete ComplicationController.swift --- ComplicationController.swift | 154 ----------------------------------- 1 file changed, 154 deletions(-) delete mode 100644 ComplicationController.swift diff --git a/ComplicationController.swift b/ComplicationController.swift deleted file mode 100644 index d632954571..0000000000 --- a/ComplicationController.swift +++ /dev/null @@ -1,154 +0,0 @@ -// -// ComplicationController.swift -// WatchApp Extension -// -// Created by Nathan Racklyeft on 8/29/15. -// Copyright © 2015 Nathan Racklyeft. All rights reserved. -// - -import ClockKit -import WatchKit - - -final class ComplicationController: NSObject, CLKComplicationDataSource { - - // MARK: - Timeline Configuration - - func getSupportedTimeTravelDirections(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimeTravelDirections) -> Void) { - handler([.backward]) - } - - func getTimelineStartDate(for complication: CLKComplication, withHandler handler: @escaping (Date?) -> Void) { - if let date = ExtensionDelegate.shared().lastContext?.glucoseDate { - handler(date) - } else { - handler(nil) - } - } - - func getTimelineEndDate(for complication: CLKComplication, withHandler handler: @escaping (Date?) -> Void) { - if let date = ExtensionDelegate.shared().lastContext?.glucoseDate { - handler(date) - } else { - handler(nil) - } - } - - func getPrivacyBehavior(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationPrivacyBehavior) -> Void) { - handler(.hideOnLockScreen) - } - - // MARK: - Timeline Population - - private lazy var formatter = NumberFormatter() - - func getCurrentTimelineEntry(for complication: CLKComplication, withHandler handler: (@escaping (CLKComplicationTimelineEntry?) -> Void)) { - let entry: CLKComplicationTimelineEntry? - - if let context = ExtensionDelegate.shared().lastContext, - let glucoseDate = context.glucoseDate, - glucoseDate.timeIntervalSinceNow.minutes >= -15, - let template = CLKComplicationTemplate.templateForFamily(complication.family, from: context) - { - template.tintColor = UIColor.tintColor - entry = CLKComplicationTimelineEntry(date: glucoseDate, complicationTemplate: template) - } else { - entry = nil - } - - handler(entry) - } - - func getTimelineEntries(for complication: CLKComplication, before date: Date, limit: Int, withHandler handler: (@escaping ([CLKComplicationTimelineEntry]?) -> Void)) { - // Call the handler with the timeline entries prior to the given date - handler(nil) - } - - func getTimelineEntries(for complication: CLKComplication, after date: Date, limit: Int, withHandler handler: (@escaping ([CLKComplicationTimelineEntry]?) -> Void)) { - // Call the handler with the timeline entries after to the given date - let entries: [CLKComplicationTimelineEntry]? - - if let context = ExtensionDelegate.shared().lastContext, - let glucoseDate = context.glucoseDate, - glucoseDate.timeIntervalSince(date) > 0, - let template = CLKComplicationTemplate.templateForFamily(complication.family, from: context) - { - template.tintColor = UIColor.tintColor - entries = [CLKComplicationTimelineEntry(date: glucoseDate, complicationTemplate: template)] - } else { - entries = nil - } - - handler(entries) - } - - // MARK: - Placeholder Templates - - func getLocalizableSampleTemplate(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTemplate?) -> Void) { - - let template: CLKComplicationTemplate? - - let glucoseText = CLKSimpleTextProvider.localizableTextProvider(withStringsFileTextKey: "120↘︎", shortTextKey: "120") - let timeText = CLKRelativeDateTextProvider(date: Date(), style: .natural, units: .minute) - - switch complication.family { - - case .graphicCorner: - if #available(watchOSApplicationExtension 5.0, *) { - let cornerTemplate = CLKComplicationTemplateGraphicCornerStackText() - cornerTemplate.outerTextProvider = glucoseText - cornerTemplate.innerTextProvider = timeText - cornerTemplate.outerTextProvider.tintColor = .green - template = cornerTemplate - } else { - // Fallback on earlier versions - template = nil - } - case .graphicCircular: - if #available(watchOSApplicationExtension 5.0, *) { - let circularTemplate = CLKComplicationTemplateGraphicCircularOpenGaugeSimpleText() - circularTemplate.gaugeProvider = CLKSimpleGaugeProvider(style: .fill, gaugeColor: .green, fillFraction: 1) - circularTemplate.centerTextProvider = CLKSimpleTextProvider(text: "120") - circularTemplate.bottomTextProvider = CLKSimpleTextProvider(text: "↘︎") - template = circularTemplate - } else { - // Fallback on earlier versions - template = nil - } - case .graphicRectangular, .graphicBezel: - template = nil - case .modularSmall: - let modularSmall = CLKComplicationTemplateModularSmallStackText() - modularSmall.line1TextProvider = glucoseText - modularSmall.line2TextProvider = timeText - template = modularSmall - case .modularLarge: - let modularSmall = CLKComplicationTemplateModularLargeTallBody() - modularSmall.bodyTextProvider = glucoseText - modularSmall.headerTextProvider = timeText - template = modularSmall - case .circularSmall: - let circularSmall = CLKComplicationTemplateCircularSmallSimpleText() - circularSmall.textProvider = glucoseText - template = circularSmall - case .extraLarge: - let extraLarge = CLKComplicationTemplateExtraLargeStackText() - extraLarge.line1TextProvider = glucoseText - extraLarge.line2TextProvider = timeText - template = extraLarge - case .utilitarianSmall, .utilitarianSmallFlat: - let utilitarianSmallFlat = CLKComplicationTemplateUtilitarianSmallFlat() - utilitarianSmallFlat.textProvider = glucoseText - template = utilitarianSmallFlat - case .utilitarianLarge: - let utilitarianLarge = CLKComplicationTemplateUtilitarianLargeFlat() - let eventualGlucoseText = CLKSimpleTextProvider.localizableTextProvider(withStringsFileTextKey: "75") - utilitarianLarge.textProvider = CLKSimpleTextProvider.localizableTextProvider(withStringsFileFormatKey: "UtilitarianLargeFlat", textProviders: [glucoseText, eventualGlucoseText, CLKTimeTextProvider(date: Date())]) - template = utilitarianLarge - } - - template?.tintColor = UIColor.tintColor - handler(template) - - } -} From a3dd64aa2b323eea5bebbe1458211bd4270af230 Mon Sep 17 00:00:00 2001 From: apabari Date: Mon, 15 Oct 2018 13:13:13 -0400 Subject: [PATCH 3/6] Delete Info.plist --- Info.plist | 56 ------------------------------------------------------ 1 file changed, 56 deletions(-) delete mode 100644 Info.plist diff --git a/Info.plist b/Info.plist deleted file mode 100644 index d9ff34f6f8..0000000000 --- a/Info.plist +++ /dev/null @@ -1,56 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - WatchApp Extension - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - XPC! - CFBundleShortVersionString - 1.9.3 - CFBundleSignature - ???? - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - CLKComplicationPrincipalClass - $(PRODUCT_MODULE_NAME).ComplicationController - CLKComplicationSupportedFamilies - - CLKComplicationFamilyCircularSmall - CLKComplicationFamilyExtraLarge - CLKComplicationFamilyGraphicBezel - CLKComplicationFamilyGraphicCircular - CLKComplicationFamilyGraphicCorner - CLKComplicationFamilyGraphicRectangular - CLKComplicationFamilyModularLarge - CLKComplicationFamilyModularSmall - CLKComplicationFamilyUtilitarianLarge - CLKComplicationFamilyUtilitarianSmall - CLKComplicationFamilyUtilitarianSmallFlat - - NSExtension - - NSExtensionAttributes - - WKAppBundleIdentifier - $(MAIN_APP_BUNDLE_IDENTIFIER).LoopWatch - - NSExtensionPointIdentifier - com.apple.watchkit - - RemoteInterfacePrincipalClass - $(PRODUCT_MODULE_NAME).StatusInterfaceController - WKExtensionDelegateClassName - $(PRODUCT_MODULE_NAME).ExtensionDelegate - - From d678c5f5a3d3c6e3f74e6d932b61d43a0d7729d7 Mon Sep 17 00:00:00 2001 From: apabari Date: Mon, 15 Oct 2018 13:13:24 -0400 Subject: [PATCH 4/6] Delete CLKComplicationTemplate.swift --- CLKComplicationTemplate.swift | 133 ---------------------------------- 1 file changed, 133 deletions(-) delete mode 100644 CLKComplicationTemplate.swift diff --git a/CLKComplicationTemplate.swift b/CLKComplicationTemplate.swift deleted file mode 100644 index 758a643f2d..0000000000 --- a/CLKComplicationTemplate.swift +++ /dev/null @@ -1,133 +0,0 @@ -// -// CLKComplicationTemplate.swift -// Naterade -// -// Created by Nathan Racklyeft on 11/26/15. -// Copyright © 2015 Nathan Racklyeft. All rights reserved. -// - -import ClockKit -import HealthKit -import LoopKit -import Foundation - - -extension CLKComplicationTemplate { - - static func templateForFamily(_ family: CLKComplicationFamily, from context: WatchContext) -> CLKComplicationTemplate? { - guard let glucose = context.glucose, let unit = context.preferredGlucoseUnit else { - return nil - } - - return templateForFamily(family, glucose: glucose, unit: unit, date: context.glucoseDate, trend: context.glucoseTrend, eventualGlucose: context.eventualGlucose) - } - - static func templateForFamily(_ family: CLKComplicationFamily, glucose: HKQuantity, unit: HKUnit, date: Date?, trend: GlucoseTrend?, eventualGlucose: HKQuantity?) -> CLKComplicationTemplate? { - - let formatter = NumberFormatter.glucoseFormatter(for: unit) - - guard let glucoseString = formatter.string(from: glucose.doubleValue(for: unit)), - let date = date else - { - return nil - } - - let glucoseAndTrend = "\(glucoseString)\(trend?.symbol ?? " ")" - var accessibilityStrings = [glucoseString] - - if let trend = trend { - accessibilityStrings.append(trend.localizedDescription) - } - - let glucoseAndTrendText = CLKSimpleTextProvider(text: glucoseAndTrend, shortText: glucoseString, accessibilityLabel: accessibilityStrings.joined(separator: ", ")) - let timeText = CLKRelativeDateTextProvider(date: date, style: .natural, units: .minute) - - let timeFormatter = DateFormatter() - timeFormatter.dateStyle = .none - timeFormatter.timeStyle = .short - - - switch family { - case .graphicCorner: - // *************************************** - // ** Apple Watch Series 4 Complication ** - // *************************************** - // Corner Text - // Outer Text: Current Glucose and Trend - // Inner Text: timeText - - if #available(watchOSApplicationExtension 5.0, *) { - let cornerTemplate = CLKComplicationTemplateGraphicCornerStackText() - cornerTemplate.outerTextProvider = glucoseAndTrendText - cornerTemplate.outerTextProvider.tintColor = .green - cornerTemplate.innerTextProvider = timeText - return cornerTemplate - } else { - // Fallback on earlier versions - return nil - } - case .graphicCircular: - // *************************************** - // ** Apple Watch Series 4 Complication ** - // *************************************** - // Circular Gauge - // Full Ring - // Current Glucose in Center, Trend Arrow Below - // * future enhancement - update gauge colors to reflect loop status, or time in range for the day - if #available(watchOSApplicationExtension 5.0, *) { - let circularTemplate = CLKComplicationTemplateGraphicCircularOpenGaugeSimpleText() - circularTemplate.gaugeProvider = CLKSimpleGaugeProvider(style: .fill, gaugeColor: .green, fillFraction: 1) - circularTemplate.centerTextProvider = CLKSimpleTextProvider(text: glucoseString) - circularTemplate.bottomTextProvider = CLKSimpleTextProvider(text: (trend?.symbol ?? " ")) - return circularTemplate - } else { - // Fallback on earlier versions - return nil - } - case .graphicRectangular, .graphicBezel: - return nil - case .modularSmall: - let template = CLKComplicationTemplateModularSmallStackText() - template.line1TextProvider = glucoseAndTrendText - template.line2TextProvider = timeText - return template - case .modularLarge: - let template = CLKComplicationTemplateModularLargeTallBody() - template.bodyTextProvider = glucoseAndTrendText - template.headerTextProvider = timeText - return template - case .circularSmall: - let template = CLKComplicationTemplateCircularSmallSimpleText() - template.textProvider = CLKSimpleTextProvider(text: glucoseString) - return template - case .extraLarge: - let template = CLKComplicationTemplateExtraLargeStackText() - template.line1TextProvider = glucoseAndTrendText - template.line2TextProvider = timeText - return template - case .utilitarianSmall, .utilitarianSmallFlat: - let template = CLKComplicationTemplateUtilitarianSmallFlat() - template.textProvider = CLKSimpleTextProvider(text: glucoseString) - - return template - case .utilitarianLarge: - var eventualGlucoseText = "" - if let eventualGlucose = eventualGlucose, - let eventualGlucoseString = formatter.string(from: eventualGlucose.doubleValue(for: unit)) - { - eventualGlucoseText = eventualGlucoseString - } - - let template = CLKComplicationTemplateUtilitarianLargeFlat() - let format = NSLocalizedString("UtilitarianLargeFlat", tableName: "ckcomplication", comment: "Utilitarian large flat format string (1: Glucose & Trend symbol) (2: Eventual Glucose) (3: Time)") - - template.textProvider = CLKSimpleTextProvider(text: String(format: format, arguments: [ - glucoseAndTrend, - eventualGlucoseText, - timeFormatter.string(from: date) - ] - )) - return template - } - } -} From 693f9f3576c7ecd853f0cfbf111d6470023963b0 Mon Sep 17 00:00:00 2001 From: apabari Date: Mon, 15 Oct 2018 13:16:00 -0400 Subject: [PATCH 5/6] Support for Apple Watch Complications --> .graphicCircular complication (full ring, glucose in middle, trend below) --> .graphicCorner complication (outer text: glucose and trend, inner text: time) --- .../Extensions/CLKComplicationTemplate.swift | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/WatchApp Extension/Extensions/CLKComplicationTemplate.swift b/WatchApp Extension/Extensions/CLKComplicationTemplate.swift index 1a3e54331f..758a643f2d 100644 --- a/WatchApp Extension/Extensions/CLKComplicationTemplate.swift +++ b/WatchApp Extension/Extensions/CLKComplicationTemplate.swift @@ -46,8 +46,45 @@ extension CLKComplicationTemplate { timeFormatter.dateStyle = .none timeFormatter.timeStyle = .short + switch family { - case .graphicCorner, .graphicCircular, .graphicRectangular, .graphicBezel: + case .graphicCorner: + // *************************************** + // ** Apple Watch Series 4 Complication ** + // *************************************** + // Corner Text + // Outer Text: Current Glucose and Trend + // Inner Text: timeText + + if #available(watchOSApplicationExtension 5.0, *) { + let cornerTemplate = CLKComplicationTemplateGraphicCornerStackText() + cornerTemplate.outerTextProvider = glucoseAndTrendText + cornerTemplate.outerTextProvider.tintColor = .green + cornerTemplate.innerTextProvider = timeText + return cornerTemplate + } else { + // Fallback on earlier versions + return nil + } + case .graphicCircular: + // *************************************** + // ** Apple Watch Series 4 Complication ** + // *************************************** + // Circular Gauge + // Full Ring + // Current Glucose in Center, Trend Arrow Below + // * future enhancement - update gauge colors to reflect loop status, or time in range for the day + if #available(watchOSApplicationExtension 5.0, *) { + let circularTemplate = CLKComplicationTemplateGraphicCircularOpenGaugeSimpleText() + circularTemplate.gaugeProvider = CLKSimpleGaugeProvider(style: .fill, gaugeColor: .green, fillFraction: 1) + circularTemplate.centerTextProvider = CLKSimpleTextProvider(text: glucoseString) + circularTemplate.bottomTextProvider = CLKSimpleTextProvider(text: (trend?.symbol ?? " ")) + return circularTemplate + } else { + // Fallback on earlier versions + return nil + } + case .graphicRectangular, .graphicBezel: return nil case .modularSmall: let template = CLKComplicationTemplateModularSmallStackText() From 6a6d45c16d0d334cbce5eb4d401af5134a17a005 Mon Sep 17 00:00:00 2001 From: apabari Date: Mon, 15 Oct 2018 13:18:03 -0400 Subject: [PATCH 6/6] Support for Apple Watch Series 4 Complications --> .graphicCircular complication (full ring, glucose in middle, trend below) --> .graphicCorner complication (outer text: glucose and trend, inner text: time) --- .../ComplicationController.swift | 26 ++++++++++++++++++- WatchApp Extension/Info.plist | 10 ++++--- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/WatchApp Extension/ComplicationController.swift b/WatchApp Extension/ComplicationController.swift index 4b149cabb1..d632954571 100644 --- a/WatchApp Extension/ComplicationController.swift +++ b/WatchApp Extension/ComplicationController.swift @@ -92,7 +92,30 @@ final class ComplicationController: NSObject, CLKComplicationDataSource { let timeText = CLKRelativeDateTextProvider(date: Date(), style: .natural, units: .minute) switch complication.family { - case .graphicCorner, .graphicCircular, .graphicRectangular, .graphicBezel: + + case .graphicCorner: + if #available(watchOSApplicationExtension 5.0, *) { + let cornerTemplate = CLKComplicationTemplateGraphicCornerStackText() + cornerTemplate.outerTextProvider = glucoseText + cornerTemplate.innerTextProvider = timeText + cornerTemplate.outerTextProvider.tintColor = .green + template = cornerTemplate + } else { + // Fallback on earlier versions + template = nil + } + case .graphicCircular: + if #available(watchOSApplicationExtension 5.0, *) { + let circularTemplate = CLKComplicationTemplateGraphicCircularOpenGaugeSimpleText() + circularTemplate.gaugeProvider = CLKSimpleGaugeProvider(style: .fill, gaugeColor: .green, fillFraction: 1) + circularTemplate.centerTextProvider = CLKSimpleTextProvider(text: "120") + circularTemplate.bottomTextProvider = CLKSimpleTextProvider(text: "↘︎") + template = circularTemplate + } else { + // Fallback on earlier versions + template = nil + } + case .graphicRectangular, .graphicBezel: template = nil case .modularSmall: let modularSmall = CLKComplicationTemplateModularSmallStackText() @@ -126,5 +149,6 @@ final class ComplicationController: NSObject, CLKComplicationDataSource { template?.tintColor = UIColor.tintColor handler(template) + } } diff --git a/WatchApp Extension/Info.plist b/WatchApp Extension/Info.plist index 72ad48bfe9..d9ff34f6f8 100644 --- a/WatchApp Extension/Info.plist +++ b/WatchApp Extension/Info.plist @@ -26,13 +26,17 @@ $(PRODUCT_MODULE_NAME).ComplicationController CLKComplicationSupportedFamilies - CLKComplicationFamilyModularSmall CLKComplicationFamilyCircularSmall CLKComplicationFamilyExtraLarge - CLKComplicationFamilyUtilitarianSmallFlat - CLKComplicationFamilyUtilitarianLarge + CLKComplicationFamilyGraphicBezel + CLKComplicationFamilyGraphicCircular + CLKComplicationFamilyGraphicCorner + CLKComplicationFamilyGraphicRectangular CLKComplicationFamilyModularLarge + CLKComplicationFamilyModularSmall + CLKComplicationFamilyUtilitarianLarge CLKComplicationFamilyUtilitarianSmall + CLKComplicationFamilyUtilitarianSmallFlat NSExtension