This commit is contained in:
Paul Plant 2024-01-28 18:06:16 +01:00
parent e795fcece6
commit fb90a13e83
6 changed files with 269 additions and 163 deletions

View File

@ -25,31 +25,31 @@ enum ConstantsWidget {
}()
// live activity notification widget
static let viewWidthLiveActivityNotificationNormal: CGFloat = 200
static let viewHeightLiveActivityNotificationNormal: CGFloat = 80 // 100 for normal
static let viewWidthLiveActivityNotificationNormal: CGFloat = 180
static let viewHeightLiveActivityNotificationNormal: CGFloat = 90
static let hoursToShowLiveActivityNotificationNormal: Double = 3
static let intervalBetweenXAxisValuesLiveActivityNotificationNormal: Int = 1
static let viewWidthLiveActivityNotificationLarge: CGFloat = 220
static let viewHeightLiveActivityNotificationLarge: CGFloat = 140 // 150 seems to be max size without clipping
static let hoursToShowLiveActivityNotificationLarge: Double = 5
static let viewWidthLiveActivityNotificationLarge: CGFloat = 360
static let viewHeightLiveActivityNotificationLarge: CGFloat = 160 // 150 seems to be max size without clipping
static let hoursToShowLiveActivityNotificationLarge: Double = 6
static let intervalBetweenXAxisValuesLiveActivityNotificationLarge: Int = 1
static let viewBackgroundColorLiveActivityNotification = Color.black
static let lowHighLineColorLiveActivityNotification = Color(white: 0.7)
static let urgentLowHighLineLiveActivityNotification = Color(white: 0.5)
static let lowHighLineColorLiveActivityNotification = Color(white: 0.6)
static let urgentLowHighLineLiveActivityNotification = Color(white: 0.4)
static let xAxisGridLineColorLiveActivityNotification = Color(white: 0.4)
static let glucoseCircleDiameterLiveActivityNotification: Double = 36
static let relativeYAxisLineSizeLiveActivityNotification: Double = 1
static let xAxisLabelOffsetLiveActivityNotification: Double = -10
// dynamic island bottom (expanded)
static let viewWidthDynamicIsland: CGFloat = 320
static let viewWidthDynamicIsland: CGFloat = 330
static let viewHeightDynamicIsland: CGFloat = 70
static let viewBackgroundColorDynamicIsland = Color.black
static let lowHighLineColorDynamicIsland = Color(white: 0.7)
static let urgentLowHighLineColorDynamicIsland = Color(white: 0.5)
static let lowHighLineColorDynamicIsland = Color(white: 0.6)
static let urgentLowHighLineColorDynamicIsland = Color(white: 0.4)
static let xAxisGridLineColorDynamicIsland = Color(white: 0.5)
static let hoursToShowDynamicIsland: Double = 12
static let intervalBetweenXAxisValuesDynamicIsland: Int = 2

View File

@ -77,7 +77,8 @@ struct GlucoseChartView: View {
let intervalBetweenAxisValues: Int = glucoseChartWidgetType.intervalBetweenAxisValues(liveActivityNotificationSizeType: liveActivityNotificationSizeType)
/// first, for each int in mappingArray, we create a Date, starting with the lower hour + 1 hour - we will create 5 in this example, starting with hour 08 (7 + 3600 seconds)
let startDateLower = startDate.toLowerHour()
let startDateLower = Date(timeIntervalSinceReferenceDate:
(startDate.timeIntervalSinceReferenceDate / 3600.0).rounded(.down) * 3600.0)
let xAxisValues: [Date] = stride(from: 1, to: mappingArray.count + 1, by: intervalBetweenAxisValues).map {
startDateLower.addingTimeInterval(Double($0)*3600)
@ -89,7 +90,8 @@ struct GlucoseChartView: View {
var body: some View {
let domain = 40 ... max(bgReadingValues.max() ?? 400, urgentHighLimitInMgDl)
let domain = (min((bgReadingValues.min() ?? 40), urgentLowLimitInMgDl) - 6) ... (max((bgReadingValues.max() ?? 400), urgentHighLimitInMgDl) + 6)
Chart {
if domain.contains(urgentLowLimitInMgDl) {
@ -123,24 +125,47 @@ struct GlucoseChartView: View {
.symbolSize(glucoseChartWidgetType.glucoseCircleDiameter)
.foregroundStyle(bgColor(bgValueInMgDl: bgReadingValues[index]))
}
// add a phantom glucose point five minutes after the end of any BG values just to give more context
PointMark(x: .value("Time", Date().addingTimeInterval(5 * 60)),
y: .value("BG", 100))
.symbol(Circle())
.symbolSize(glucoseChartWidgetType.glucoseCircleDiameter)
.foregroundStyle(.clear)
}
.chartXAxis {
// https://developer.apple.com/documentation/charts/customizing-axes-in-swift-charts
AxisMarks(values: xAxisValues()) {
// AxisMarks(values: xAxisValues()) { value in
//
// if let v = value.as(Date.self) {
// AxisValueLabel {
// Text(v.formatted(.dateTime.hour()))
// .foregroundStyle(Color.white)
// }
// //.offset(x: glucoseChartWidgetType.xAxisLabelOffset)
//
// AxisGridLine()
// .foregroundStyle(glucoseChartWidgetType.xAxisGridLineColor)
// }
// }
AxisMarks(values: .automatic(desiredCount: Int(glucoseChartWidgetType.hoursToShow(liveActivityNotificationSizeType: liveActivityNotificationSizeType)))) {
if let v = $0.as(Date.self) {
AxisValueLabel {
Text(v.formatted(.dateTime.hour()))
.foregroundStyle(Color.white)
}
.offset(x: glucoseChartWidgetType.xAxisLabelOffset)
// AxisValueLabel {
// Text(v.formatted(.dateTime.hour()))
// .foregroundStyle(Color.white)
// }
// .offset(x: glucoseChartWidgetType.xAxisLabelOffset)
AxisGridLine()
.foregroundStyle(glucoseChartWidgetType.xAxisGridLineColor)
}
}
}
//.background(Color.purple)
.chartYAxis(.hidden)
.chartYScale(domain: domain)
.frame(width: glucoseChartWidgetType.viewSize(liveActivityNotificationSizeType: liveActivityNotificationSizeType).width, height: glucoseChartWidgetType.viewSize(liveActivityNotificationSizeType: liveActivityNotificationSizeType).height)
// .padding(.top, 20)
// .padding(.bottom, 20)
}
}

View File

@ -38,8 +38,6 @@ struct XDripWidgetAttributes: ActivityAttributes {
var bgUnitString: String
var bgValueStringInUserChosenUnit: String
//var bgReadings: [BgReading]
init(bgReadingValues: [Double], bgReadingDates: [Date], isMgDl: Bool, slopeOrdinal: Int, deltaChangeInMgDl: Double?, urgentLowLimitInMgDl: Double, lowLimitInMgDl: Double, highLimitInMgDl: Double, urgentHighLimitInMgDl: Double, updatedDate: Date, liveActivityNotificationSizeTypeAsInt: Int) {
// these are the "passed in" stateful values used to initialize
@ -79,17 +77,18 @@ struct XDripWidgetAttributes: ActivityAttributes {
/// Show the bg event title if relevant
/// - Returns: a localized string such as "HIGH" or "LOW" as required
func getBgTitle() -> String? {
@available(iOS 16, *)
func getBgTitle() -> LocalizedStringResource {
if bgValueInMgDl >= urgentHighLimitInMgDl {
return Texts_Widget.urgentHigh
return "\(Texts_Widget.urgentHigh)"
} else if bgValueInMgDl >= highLimitInMgDl {
return Texts_Widget.high
return "\(Texts_Widget.high)"
} else if bgValueInMgDl <= lowLimitInMgDl {
return Texts_Widget.low
return "\(Texts_Widget.low)"
} else if bgValueInMgDl <= urgentLowLimitInMgDl {
return Texts_Widget.urgentLow
return "\(Texts_Widget.urgentLow)"
} else {
return nil
return "TEST"
}
}
@ -148,18 +147,47 @@ struct XDripWidgetAttributes: ActivityAttributes {
}
func deltaChangeFormatted(font: Font) -> some View {
HStack(spacing: 4) {
HStack(alignment: .firstTextBaseline, spacing: 4) {
Text(getDeltaChangeStringInUserChosenUnit())
.font(font).bold()
.foregroundStyle(Color(white: 0.9))
.minimumScaleFactor(0.2)
.lineLimit(1)
Text(bgUnitString)
.font(font)
.foregroundStyle(Color(white: 0.5))
.minimumScaleFactor(0.2)
.lineLimit(1)
}
}
}
// func remindUserToOpenApp(eventStartDate: Date) -> Bool {
// return eventStartDate < Date().addingTimeInterval(-3600 * 0.2) ? true : false
// }
func placeTextAtBottomOfWidget(glucoseChartWidgetType: GlucoseChartWidgetType) -> Bool {
// first see at which index in bgReadingDates the BG value is after one hour
var firstIndexForWidgetType = 0
var index = 0
for _ in bgReadingValues {
if bgReadingDates[index] > Date().addingTimeInterval((-glucoseChartWidgetType.hoursToShow(liveActivityNotificationSizeType: LiveActivityNotificationSizeType(rawValue: liveActivityNotificationSizeTypeAsInt) ?? .normal) * 60 * 60) + 3600) {
firstIndexForWidgetType = index
}
index += 1
}
// then get the bg value of that index in the bgValues array
// if it is higher than the user's high limit, then we can assume that the data will be hidden
// by the text (bg value, trend + delta), so return true to show the text at the bottom of the view
if bgReadingValues[firstIndexForWidgetType] >= highLimitInMgDl {
return true
}
return false
}
}
// when was the live activity event started? We check this on each update cycle and dismiss/recreate it before the 8-hour limit.
var eventStartDate: Date
// no static data is needed
}

View File

@ -13,13 +13,137 @@ import SwiftUI
@available(iOSApplicationExtension 16.2, *)
struct XDripWidgetLiveActivity: Widget {
let glucoseChartWidgetType: GlucoseChartWidgetType = .dynamicIsland
var body: some WidgetConfiguration {
ActivityConfiguration(for: XDripWidgetAttributes.self) { context in
LiveActivityView(state: context.state)
// Lock screen/banner UI goes here
if context.state.liveActivityNotificationSizeTypeAsInt == 0 {
// 0 = normal size chart
HStack(spacing: 20) {
VStack {
Text("\(context.state.bgValueStringInUserChosenUnit)\(context.state.trendArrow())")
.font(.system(size: 50)).bold()
.foregroundStyle(context.state.getBgColor())
.minimumScaleFactor(0.1)
.lineLimit(1)
context.state.deltaChangeFormatted(font: .title2)
.minimumScaleFactor(0.1)
.lineLimit(1)
}
.padding(4)
// ZStack {
GlucoseChartView(bgReadingValues: context.state.bgReadingValues, bgReadingDates: context.state.bgReadingDates, glucoseChartWidgetType: .liveActivityNotification, isMgDl: context.state.isMgDl, urgentLowLimitInMgDl: context.state.urgentLowLimitInMgDl, lowLimitInMgDl: context.state.lowLimitInMgDl, highLimitInMgDl: context.state.highLimitInMgDl, urgentHighLimitInMgDl: context.state.urgentHighLimitInMgDl, liveActivityNotificationSizeType: LiveActivityNotificationSizeType(rawValue: context.state.liveActivityNotificationSizeTypeAsInt) ?? .normal)
//Text(context.attributes.eventStartDate.formatted(date: .omitted, time: .shortened))
/*
if context.state.remindUserToOpenApp(eventStartDate: context.attributes.eventStartDate) {
VStack(alignment: .center) {
Spacer()
Text("Please open xDrip4iOS")
.font(.caption)
.minimumScaleFactor(0.1)
.foregroundStyle(.black)
.multilineTextAlignment(.center)
.lineLimit(1)
.padding(EdgeInsets(top: 4, leading: 8, bottom: 4, trailing: 8))
.background(Color(white: 0.8, opacity: 0.8))
.cornerRadius(15)
Spacer()
}
.padding(8)
}
*/
// }
}
.activityBackgroundTint(.black)
.padding(6)
} else if context.state.liveActivityNotificationSizeTypeAsInt == 1 {
// 1 = minimal widget with no chart
HStack(alignment: .center) {
Text("\(context.state.bgValueStringInUserChosenUnit)\(context.state.trendArrow())")
.font(.largeTitle).bold()
.foregroundStyle(context.state.getBgColor())
.minimumScaleFactor(0.1)
.lineLimit(1)
Spacer()
context.state.deltaChangeFormatted(font: .title)
.minimumScaleFactor(0.1)
.lineLimit(1)
}
.activityBackgroundTint(.black)
.padding(15)
} else {
// 2 = large chart
ZStack {
GlucoseChartView(bgReadingValues: context.state.bgReadingValues, bgReadingDates: context.state.bgReadingDates, glucoseChartWidgetType: .liveActivityNotification, isMgDl: context.state.isMgDl, urgentLowLimitInMgDl: context.state.urgentLowLimitInMgDl, lowLimitInMgDl: context.state.lowLimitInMgDl, highLimitInMgDl: context.state.highLimitInMgDl, urgentHighLimitInMgDl: context.state.urgentHighLimitInMgDl, liveActivityNotificationSizeType: LiveActivityNotificationSizeType(rawValue: context.state.liveActivityNotificationSizeTypeAsInt) ?? .normal)
//Text(context.attributes.eventStartDate.formatted(date: .omitted, time: .shortened))
VStack {
if context.state.placeTextAtBottomOfWidget(glucoseChartWidgetType: .liveActivityNotification) {
Spacer()
}
HStack(alignment: .firstTextBaseline) {
Text("\(context.state.bgValueStringInUserChosenUnit)\(context.state.trendArrow()) ")
.font(.title2).bold()
.foregroundStyle(context.state.getBgColor())
context.state.deltaChangeFormatted(font: .title3)
}
.padding(EdgeInsets(top: 4, leading: 8, bottom: 4, trailing: 8))
.background(Color(white: 0, opacity: 0.7))
.cornerRadius(20)
if !context.state.placeTextAtBottomOfWidget(glucoseChartWidgetType: .liveActivityNotification) {
Spacer()
}
// if let bgTitle = state.getBgTitle() {
// Text(bgTitle)
// .foregroundStyle(state.getBgColor())
// .font(.subheadline).bold()
// .multilineTextAlignment(.center)
// }
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(6)
/*
if context.state.remindUserToOpenApp(eventStartDate: context.attributes.eventStartDate) {
VStack(alignment: .center) {
Spacer()
Text("Live activity ending soon\nPlease open xDrip4iOS")
.font(.footnote).bold()
.foregroundStyle(.black)
.multilineTextAlignment(.center)
.padding(EdgeInsets(top: 6, leading: 10, bottom: 6, trailing: 10))
.background(Color(white: 0.8, opacity: 0.8))
.cornerRadius(15)
Spacer()
}
}
*/
}
.activityBackgroundTint(.black)
}
} dynamicIsland: { context in
@ -28,24 +152,29 @@ struct XDripWidgetLiveActivity: Widget {
.font(.largeTitle).bold()
.foregroundStyle(context.state.getBgColor())
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
.minimumScaleFactor(0.1)
.lineLimit(1)
}
DynamicIslandExpandedRegion(.trailing) {
context.state.deltaChangeFormatted(font: .title2)
context.state.deltaChangeFormatted(font: .title)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
}
DynamicIslandExpandedRegion(.bottom) {
GlucoseChartView(bgReadingValues: context.state.bgReadingValues, bgReadingDates: context.state.bgReadingDates, glucoseChartWidgetType: glucoseChartWidgetType, isMgDl: context.state.isMgDl, urgentLowLimitInMgDl: context.state.urgentLowLimitInMgDl, lowLimitInMgDl: context.state.lowLimitInMgDl, highLimitInMgDl: context.state.highLimitInMgDl, urgentHighLimitInMgDl: context.state.urgentHighLimitInMgDl, liveActivityNotificationSizeType: LiveActivityNotificationSizeType(rawValue: context.state.liveActivityNotificationSizeTypeAsInt) ?? .normal)
GlucoseChartView(bgReadingValues: context.state.bgReadingValues, bgReadingDates: context.state.bgReadingDates, glucoseChartWidgetType: .dynamicIsland, isMgDl: context.state.isMgDl, urgentLowLimitInMgDl: context.state.urgentLowLimitInMgDl, lowLimitInMgDl: context.state.lowLimitInMgDl, highLimitInMgDl: context.state.highLimitInMgDl, urgentHighLimitInMgDl: context.state.urgentHighLimitInMgDl, liveActivityNotificationSizeType: LiveActivityNotificationSizeType(rawValue: context.state.liveActivityNotificationSizeTypeAsInt) ?? .normal)
}
} compactLeading: {
Text("\(context.state.bgValueStringInUserChosenUnit)\(context.state.trendArrow())")
.foregroundStyle(context.state.getBgColor())
.minimumScaleFactor(0.1)
} compactTrailing: {
Text(context.state.getDeltaChangeStringInUserChosenUnit())
.minimumScaleFactor(0.1)
} minimal: {
Text(context.state.bgValueStringInUserChosenUnit)
.foregroundStyle(context.state.getBgColor())
.minimumScaleFactor(0.1)
}
.widgetURL(URL(string: "xdripswift"))
.keylineTint(context.state.getBgColor())
@ -55,85 +184,15 @@ struct XDripWidgetLiveActivity: Widget {
}
@available(iOSApplicationExtension 16.2, *)
struct LiveActivityView: View {
let state: XDripWidgetAttributes.ContentState
let glucoseChartWidgetType: GlucoseChartWidgetType = .liveActivityNotification
var body: some View {
// Lock screen/banner UI goes here
if state.liveActivityNotificationSizeTypeAsInt == 0 {
// 0 = normal size chart
HStack(spacing: 20) {
VStack(spacing: 10) {
Text("\(state.bgValueStringInUserChosenUnit)\(state.trendArrow())")
.font(.largeTitle).bold()
.foregroundStyle(state.getBgColor())
state.deltaChangeFormatted(font: .title2)
}
GlucoseChartView(bgReadingValues: state.bgReadingValues, bgReadingDates: state.bgReadingDates, glucoseChartWidgetType: glucoseChartWidgetType, isMgDl: state.isMgDl, urgentLowLimitInMgDl: state.urgentLowLimitInMgDl, lowLimitInMgDl: state.lowLimitInMgDl, highLimitInMgDl: state.highLimitInMgDl, urgentHighLimitInMgDl: state.urgentHighLimitInMgDl, liveActivityNotificationSizeType: LiveActivityNotificationSizeType(rawValue: state.liveActivityNotificationSizeTypeAsInt) ?? .normal)
}
.activityBackgroundTint(.black)
.padding(10)
} else if state.liveActivityNotificationSizeTypeAsInt == 1 {
// 1 = minimal widget with no chart
HStack {
Text("\(state.bgValueStringInUserChosenUnit)\(state.trendArrow())")
.font(.largeTitle).bold()
.foregroundStyle(state.getBgColor())
Spacer()
if let bgTitle = state.getBgTitle() {
Text(bgTitle)
.foregroundStyle(state.getBgColor())
.font(.title2).bold()
.multilineTextAlignment(.center)
}
Spacer()
state.deltaChangeFormatted(font: .title2)
}
.activityBackgroundTint(.black)
.padding(15)
} else {
// 2 = large widget with no chart
HStack(spacing: 10) {
VStack(spacing: 10) {
Text("\(state.bgValueStringInUserChosenUnit)\(state.trendArrow())")
.font(.title).bold()
.foregroundStyle(state.getBgColor())
state.deltaChangeFormatted(font: .title3)
if let bgTitle = state.getBgTitle() {
Text(bgTitle)
.foregroundStyle(state.getBgColor())
.font(.subheadline).bold()
.multilineTextAlignment(.center)
}
}
GlucoseChartView(bgReadingValues: state.bgReadingValues, bgReadingDates: state.bgReadingDates, glucoseChartWidgetType: glucoseChartWidgetType, isMgDl: state.isMgDl, urgentLowLimitInMgDl: state.urgentLowLimitInMgDl, lowLimitInMgDl: state.lowLimitInMgDl, highLimitInMgDl: state.highLimitInMgDl, urgentHighLimitInMgDl: state.urgentHighLimitInMgDl, liveActivityNotificationSizeType: LiveActivityNotificationSizeType(rawValue: state.liveActivityNotificationSizeTypeAsInt) ?? .normal)
}
.activityBackgroundTint(.black)
.padding(10)
}
}
}
//@available(iOSApplicationExtension 16.2, *)
//struct LiveActivityView: View {
//
// let state: XDripWidgetAttributes.ContentState
// let glucoseChartWidgetType: GlucoseChartWidgetType = .liveActivityNotification
//
// var body: some View {
// }
//}
@available(iOS 16.2, *)
struct XDripWidgetLiveActivity_Previews: PreviewProvider {
@ -143,9 +202,9 @@ struct XDripWidgetLiveActivity_Previews: PreviewProvider {
let endDate = Date()
let startDate = endDate.addingTimeInterval(-3600 * 12)
var currentDate = startDate
var dateArray: [Date] = []
while currentDate < endDate {
dateArray.append(currentDate)
currentDate = currentDate.addingTimeInterval(60 * 5)
@ -162,14 +221,17 @@ struct XDripWidgetLiveActivity_Previews: PreviewProvider {
for index in bgValueArray.indices {
if currentValue < 70 {
increaseValues = true
} else if currentValue > 180 {
increaseValues = false
}
let randomValue = Double(Int.random(in: -10..<10))
let randomValue = Double(Int.random(in: 0..<20))
bgValueArray[index] = currentValue + (increaseValues ? randomValue : -randomValue)
if currentValue < 80 {
increaseValues = true
bgValueArray[index] = currentValue + abs(randomValue)
} else if currentValue > 160 {
increaseValues = false
bgValueArray[index] = currentValue - abs(randomValue)
} else {
bgValueArray[index] = currentValue + (increaseValues ? randomValue : -randomValue)
}
currentValue = bgValueArray[index]
}
@ -178,9 +240,9 @@ struct XDripWidgetLiveActivity_Previews: PreviewProvider {
}
static let attributes = XDripWidgetAttributes(eventStartDate: Date().addingTimeInterval(-1000))
static let attributes = XDripWidgetAttributes() //(eventStartDate: Date().addingTimeInterval(-1000))
static let contentState = XDripWidgetAttributes.ContentState(bgReadingValues: bgValueArray(), bgReadingDates: bgDateArray(), isMgDl: true, slopeOrdinal:5, deltaChangeInMgDl: -2, urgentLowLimitInMgDl: 70, lowLimitInMgDl: 80, highLimitInMgDl: 140, urgentHighLimitInMgDl: 180, updatedDate: Date(), liveActivityNotificationSizeTypeAsInt: 2)
static let contentState = XDripWidgetAttributes.ContentState(bgReadingValues: bgValueArray(), bgReadingDates: bgDateArray(), isMgDl: true, slopeOrdinal:5, deltaChangeInMgDl: -2, urgentLowLimitInMgDl: 70, lowLimitInMgDl: 80, highLimitInMgDl: 140, urgentHighLimitInMgDl: 180, updatedDate: Date(), liveActivityNotificationSizeTypeAsInt: 0)
static var previews: some View {
attributes

View File

@ -9,6 +9,7 @@
import Foundation
import ActivityKit
import OSLog
import SwiftUI
@available(iOS 16.2, *)
public final class LiveActivityManager {
@ -21,7 +22,7 @@ public final class LiveActivityManager {
static let shared = LiveActivityManager()
private init() {
eventAttributes = XDripWidgetAttributes(eventStartDate: Date())
eventAttributes = XDripWidgetAttributes() //eventStartDate: Date())
}
}
@ -32,28 +33,28 @@ extension LiveActivityManager {
/// start or update the live activity based upon whether it currently exists or not
/// - Parameter contentState: the contentState to show
/// - Parameter forceRestart: will force the current live activity to end and a new one will be started
func runActivity(contentState: XDripWidgetAttributes.ContentState, forceRestart: Bool) {
trace("In runActivity", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info)
trace("in runActivity", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info)
// checking whether 'Live activities' is enabled for the app in settings
if ActivityAuthorizationInfo().areActivitiesEnabled {
if eventActivity == nil {
trace(" eventActivity == nil, trying to start new activity", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info)
print("Starting new Live Activity")
trace(" starting new live activity", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info)
startActivity(contentState: contentState)
} else if forceRestart {
print("ending current activity and starting a new one")
trace(" eventActivity != nil, will attempt to end the current activity and start a new one", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info)
print("Restarting Live Activity")
trace(" restarting live activity", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info)
Task {
endActivity()
await endActivity()
startActivity(contentState: contentState)
}
} else {
trace(" eventActivity != nil, trying to update existing activity", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info)
print("Updating Live Activity")
trace(" updating live activity", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info)
Task {
await updateActivity(to: contentState)
@ -70,7 +71,6 @@ extension LiveActivityManager {
let content = ActivityContent(state: contentState, staleDate: nil, relevanceScore: 1.0)
do {
print("Trying to start new live activity")
eventActivity = try Activity.request(
attributes: eventAttributes,
content: content,
@ -80,7 +80,7 @@ extension LiveActivityManager {
print("New live activity started: \(String(describing: eventActivity?.id))")
let idString = "\(String(describing: eventActivity?.id))"
trace("New live activity started: %{public}@", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info, idString)
trace("new live activity started: %{public}@", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info, idString)
} catch {
print(error.localizedDescription)
@ -102,34 +102,26 @@ extension LiveActivityManager {
startActivity(contentState: contentState)
}
return
} else {
// check if the activity is not about to be orphaned by iOS (after 8 hours) and left on the screen with the initial state. If it is then end it.
if eventAttributes.eventStartDate > Date().addingTimeInterval(-3600 * 8) {
await eventActivity?.update(
ActivityContent<XDripWidgetAttributes.ContentState>(
state: contentState,
staleDate: Date().addingTimeInterval(10)
)
)
} else {
trace("Live activity is 8 hours old so will no longer be able to be updated. Ending activity ", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info)
endActivity()
startActivity(contentState: contentState)
}
//let alertConfiguration = AlertConfiguration(title: "BG Alert", body: contentState.getBgTitle(), sound: .default)
let updatedContent = ActivityContent(state: contentState, staleDate: nil)
// if contentState.getBgTitle() != "" {
// print("Triggering Live Activity alert for \(String(describing: contentState.getBgTitle()))")
// trace("triggering live activity alert for: %{public}@", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info, String(describing: contentState.getBgTitle()))
//
// await eventActivity?.update(updatedContent, alertConfiguration: alertConfiguration)
// } else {
// await eventActivity?.update(updatedContent)
// }
await eventActivity?.update(updatedContent)
}
}
/// end the live activity if it is being shown, do nothing if there is no eventyActivity
func endActivity() {
func endActivity() async {
if eventActivity != nil {
Task {
@ -140,9 +132,9 @@ extension LiveActivityManager {
trace("Ending live activity: %{public}@", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info, idString)
await activity.end(nil, dismissalPolicy: .immediate)
eventActivity = nil
}
}
eventActivity = nil
}
}
@ -163,10 +155,11 @@ extension LiveActivityManager {
trace("Ending live activity: %{public}@", log: self.log, category: ConstantsLog.categoryLiveActivityManager, type: .info, idString)
await activity.end(nil, dismissalPolicy: .immediate)
eventActivity = nil
}
semaphore.signal()
}
semaphore.wait()
eventActivity = nil
}
}

View File

@ -3524,8 +3524,6 @@ final class RootViewController: UIViewController, ObservableObject {
// also take advantage to just skip the rest of the function if they have live activities disabled
var showLiveActivity: Bool = true //!(!UserDefaults.standard.isMaster || UserDefaults.standard.liveActivityType == .disabled)
let forceRestart = forceRestart
if let bgReadingsAccessor = bgReadingsAccessor, showLiveActivity {
// get 2 last Readings, with a calculatedValue