This commit is contained in:
Paul Plant 2021-10-15 16:47:27 +02:00
parent 58c4f25728
commit a01b504d85
5 changed files with 142 additions and 19 deletions

View File

@ -7,15 +7,18 @@
//
import ClockKit
import WatchKit
class ComplicationController: NSObject, CLKComplicationDataSource {
// MARK: - Complication Configuration
func getComplicationDescriptors(handler: @escaping ([CLKComplicationDescriptor]) -> Void) {
let descriptors = [
CLKComplicationDescriptor(identifier: "complication", displayName: "xdrip", supportedFamilies: CLKComplicationFamily.allCases)
CLKComplicationDescriptor(identifier: "complication", displayName: "xDrip4iOS", supportedFamilies: CLKComplicationFamily.allCases)
// Multiple complication support can be added here with more descriptors
]
@ -40,16 +43,119 @@ class ComplicationController: NSObject, CLKComplicationDataSource {
}
// MARK: - Timeline Population
func getCurrentTimelineEntry(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimelineEntry?) -> Void) {
// Call the handler with the current timeline entry
handler(nil)
if let template = getComplicationTemplate(for: complication, using: Date()) {
let entry = CLKComplicationTimelineEntry(date: Date(), complicationTemplate: template)
handler(entry)
} else {
handler(nil)
}
}
func getCurrentTimelineEntry3(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimelineEntry?) -> Void) {
// let entry: CLKComplicationTimelineEntry
let myDelegate = WKExtension.shared().delegate as! ExtensionDelegate
let valueText = CLKSimpleTextProvider.localizableTextProvider(withStringsFileTextKey: myDelegate.currentBGValueText)
let minsAgoText = CLKSimpleTextProvider.localizableTextProvider(withStringsFileTextKey: myDelegate.minsAgoText)
// let textProvider = CLKTextProvider(format: dataString)
// let template = CLKComplicationTemplateUtilitarianLargeFlat(textProvider: textProvider)
// let template = CLKComplicationTemplateModularSmallStackText.init(line1TextProvider: valueText, line2TextProvider: minsAgoText)
let template = CLKComplicationTemplateCircularSmallSimpleText.init(textProvider: valueText)
//entry = CLKComplicationTimelineEntry(date: Date(), complicationTemplate: template)
handler(CLKComplicationTimelineEntry(date: Date(), complicationTemplate: template))
// switch complication.family {
//
// case .modularSmall:
// let template = CLKComplicationTemplateModularSmallStackText.init(line1TextProvider: valueText, line2TextProvider: minsAgoText)
// entry = CLKComplicationTimelineEntry(date: Date(), complicationTemplate: template)
// case .modularLarge:
// let template = CLKComplicationTemplateModularLargeTallBody.init(headerTextProvider: minsAgoText, bodyTextProvider: valueText)
// entry = CLKComplicationTimelineEntry(date: Date(), complicationTemplate: template)
// case .circularSmall:
// let template = CLKComplicationTemplateCircularSmallSimpleText.init(textProvider: valueText)
// entry = CLKComplicationTimelineEntry(date: Date(), complicationTemplate: template)
// case .extraLarge:
// let template = CLKComplicationTemplateExtraLargeStackText.init(line1TextProvider: valueText, line2TextProvider: minsAgoText)
// entry = CLKComplicationTimelineEntry(date: Date(), complicationTemplate: template)
// case .utilitarianSmall, .utilitarianSmallFlat:
// let template = CLKComplicationTemplateUtilitarianSmallFlat.init(textProvider: valueText)
// entry = CLKComplicationTimelineEntry(date: Date(), complicationTemplate: template)
// case .utilitarianLarge:
// let eventualGlucoseText = CLKSimpleTextProvider.localizableTextProvider(withStringsFileTextKey: "75")
// let template = CLKComplicationTemplateUtilitarianLargeFlat.init(textProvider: CLKSimpleTextProvider.localizableTextProvider(withStringsFileFormatKey: "UtilitarianLargeFlat", textProviders: [valueText, eventualGlucoseText, CLKTimeTextProvider(date: Date())]))
// entry = CLKComplicationTimelineEntry(date: Date(), complicationTemplate: template)
//// case .graphicCorner, .graphicCircular, .graphicBezel, .graphicRectangular, .graphicExtraLarge:
//// entry = CLKComplicationTimelineEntry
////
// // @unknown default:
// // entry = nil
// case .graphicCorner:
// break
// case .graphicBezel:
// break
// case .graphicCircular:
// break
// case .graphicRectangular:
// break
// case .graphicExtraLarge:
// break
// @unknown default:
// break
// }
//
// handler(entry)
}
func getTimelineEntries(for complication: CLKComplication, after date: Date, limit: Int, withHandler handler: @escaping ([CLKComplicationTimelineEntry]?) -> Void) {
// Call the handler with the timeline entries after the given date
handler(nil)
}
func getComplicationTemplate(for complication: CLKComplication, using date: Date) -> CLKComplicationTemplate? {
let myDelegate = WKExtension.shared().delegate as! ExtensionDelegate
let valueText = CLKSimpleTextProvider.localizableTextProvider(withStringsFileTextKey: myDelegate.currentBGValueText.description)
let minsAgoText = CLKSimpleTextProvider.localizableTextProvider(withStringsFileTextKey: myDelegate.minsAgoText)
switch complication.family {
case .modularSmall:
let template = CLKComplicationTemplateModularSmallStackText.init(line1TextProvider: valueText, line2TextProvider: minsAgoText)
return template
case .modularLarge:
let template = CLKComplicationTemplateModularLargeTallBody.init(headerTextProvider: minsAgoText, bodyTextProvider: valueText)
return template
case .circularSmall:
let template = CLKComplicationTemplateCircularSmallSimpleText.init(textProvider: valueText)
return template
case .extraLarge:
let template = CLKComplicationTemplateExtraLargeStackText.init(line1TextProvider: valueText, line2TextProvider: minsAgoText)
return template
case .utilitarianSmall, .utilitarianSmallFlat:
let template = CLKComplicationTemplateUtilitarianSmallFlat.init(textProvider: valueText)
return template
case .utilitarianLarge:
let eventualGlucoseText = CLKSimpleTextProvider.localizableTextProvider(withStringsFileTextKey: "75")
let template = CLKComplicationTemplateUtilitarianLargeFlat.init(textProvider: CLKSimpleTextProvider.localizableTextProvider(withStringsFileFormatKey: "UtilitarianLargeFlat", textProviders: [valueText, eventualGlucoseText, CLKTimeTextProvider(date: Date())]))
return template
case .graphicCorner, .graphicCircular, .graphicBezel, .graphicRectangular, .graphicExtraLarge:
return nil
@unknown default:
return nil
}
}
// MARK: - Sample Templates

View File

@ -10,6 +10,9 @@ import WatchKit
class ExtensionDelegate: NSObject, WKExtensionDelegate {
var currentBGValueText: String = "124↘"
var minsAgoText: String = "3 mins"
func applicationDidFinishLaunching() {
// Perform any final initialization of your application.
}

View File

@ -23,11 +23,11 @@ class InterfaceController: WKInterfaceController {
/// we can attach this action to the value label (or whatever) and use it to force refresh the data if it is needed for some reason. We'll set it to require a 2 second push so it should not be triggered accidentally
@IBAction func longPressToRefresh(_ sender: Any) {
// set all label outlets to deactivated and show a message to the user to acknowledge that a refresh has been requested
minutesAgoLabelOutlet.setText("Refreshing...")
// // set all label outlets to deactivated and show a message to the user to acknowledge that a refresh has been requested
// minutesAgoLabelOutlet.setText("Refreshing...")
minutesAgoLabelOutlet.setTextColor(ConstantsWatchApp.labelColorDeactivated)
deltaLabelOutlet.setText("---")
deltaLabelOutlet.setText("Refreshing...")
deltaLabelOutlet.setTextColor(ConstantsWatchApp.labelColorDeactivated)
valueLabelOutlet.setText("---")
@ -37,21 +37,26 @@ class InterfaceController: WKInterfaceController {
}
// Here is an example of accessing the Float variable
// let accessVar = myDelegate.dataVar1
// let myDict = myDelegate.myDictionary
// MARK: - Properties - other private properties
// WatchConnectivity session needed for messaging with the companion app
private let session = WCSession.default
// declare and initialise app-wide variables
private var currentBGValue: Double = 0
private var currentBGValueText: String = ""
private var currentBGTimestamp: Date = Date()
private var deltaTextLocalized: String = "---"
private var minutesAgoTextLocalized: String = "---"
private var urgentLowMarkValueInUserChosenUnit: Double = 0
private var lowMarkValueInUserChosenUnit: Double = 0
private var highMarkValueInUserChosenUnit: Double = 0
private var urgentHighMarkValueInUserChosenUnit: Double = 0
var currentBGValue: Double = 0
var currentBGValueText: String = ""
var currentBGTimestamp: Date = Date()
var deltaTextLocalized: String = "---"
var minutesAgoTextLocalized: String = "---"
var urgentLowMarkValueInUserChosenUnit: Double = 0
var lowMarkValueInUserChosenUnit: Double = 0
var highMarkValueInUserChosenUnit: Double = 0
var urgentHighMarkValueInUserChosenUnit: Double = 0
// MARK: - overriden functions
@ -70,6 +75,9 @@ class InterfaceController: WKInterfaceController {
// This method is called when watch view controller is about to be visible to user
super.willActivate()
// change some of the UI text so that the user sees that something is happening whilst we request new data
deltaLabelOutlet.setText("Refreshing...")
// pull new BG data from xDrip4iOS
requestBGData()
@ -104,6 +112,10 @@ class InterfaceController: WKInterfaceController {
minutesAgoLabelOutlet.setText(minutesAgoText)
minutesAgoLabelOutlet.setTextColor(ConstantsWatchApp.minsAgoLabelColor)
let myDelegate = WKExtension.shared().delegate as! ExtensionDelegate
myDelegate.minsAgoText = minutesAgoText
// let's see how long the "mins ago" string is. Some localizations produce a really long string (Dutch, Swedish) that isn't easily abbreviated without losing context. In this case, let's just hide the icon to allow the text to fit without issues
iconImageOutlet.setHidden(minutesAgoText.count > 13 ? true : false)
@ -112,6 +124,8 @@ class InterfaceController: WKInterfaceController {
valueLabelOutlet.setText(currentBGValueText.description)
myDelegate.currentBGValueText = currentBGValueText
// make a simple check to ensure that there is no incoherency between the BG and objective values (i.e. some values in mg/dl whilst others are still in mmol/l). This can happen as the message sending from the iOS session is asynchronous. When one value is updated before the others, then it can cause the wrong colour text to be displayed until the next messages arrive 0.5 seconds later and the view is corrected.
let coherencyCheck = (currentBGValue < 30 && urgentLowMarkValueInUserChosenUnit < 10 && lowMarkValueInUserChosenUnit < 10 && highMarkValueInUserChosenUnit < 30 && urgentHighMarkValueInUserChosenUnit < 30) || (currentBGValue > 20 && urgentLowMarkValueInUserChosenUnit > 20 && lowMarkValueInUserChosenUnit > 20 && highMarkValueInUserChosenUnit > 80 && urgentHighMarkValueInUserChosenUnit > 80)

View File

@ -4257,7 +4257,7 @@
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Watch App WatchKit Extension/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = xDrip4iO5;
INFOPLIST_KEY_CLKComplicationPrincipalClass = Watch_App_WatchKit_Extension.ComplicationController;
INFOPLIST_KEY_CLKComplicationPrincipalClass = "$(PRODUCT_MODULE_NAME).ComplicationController";
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2021 Johan Degraeve. All rights reserved.";
INFOPLIST_KEY_WKExtensionDelegateClassName = Watch_App_WatchKit_Extension.ExtensionDelegate;
LD_RUNPATH_SEARCH_PATHS = (
@ -4289,7 +4289,7 @@
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Watch App WatchKit Extension/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = xDrip4iO5;
INFOPLIST_KEY_CLKComplicationPrincipalClass = Watch_App_WatchKit_Extension.ComplicationController;
INFOPLIST_KEY_CLKComplicationPrincipalClass = "$(PRODUCT_MODULE_NAME).ComplicationController";
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2021 Johan Degraeve. All rights reserved.";
INFOPLIST_KEY_WKExtensionDelegateClassName = Watch_App_WatchKit_Extension.ExtensionDelegate;
LD_RUNPATH_SEARCH_PATHS = (

View File

@ -2548,7 +2548,7 @@ final class RootViewController: UIViewController {
let minutesAgo = -Int(lastReading.timeStamp.timeIntervalSinceNow) / 60
let minutesAgoTextLocalized = (minutesAgo == 1 ? Texts_Common.minute:Texts_Common.minutes) + " " + Texts_HomeView.ago
let minutesAgoTextLocalized = (minutesAgo == 1 ? Texts_Common.minute:Texts_Common.minutes) // + " " + Texts_HomeView.ago
let latestReadings = bgReadingsAccessor.get2LatestBgReadings(minimumTimeIntervalInMinutes: 4.0)