Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Live Activities #35

Closed
wants to merge 42 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
c8b5cc3
live activity
10nas Nov 28, 2023
5fdc18f
Fastfile changes to support Live Activity (#396)
sethgagnon Nov 29, 2023
9b87635
Live activity fixes (#397)
10nas Dec 1, 2023
8b762cf
add glucose graph in dynamic island....WiP
polscm32 Dec 1, 2023
5be9d74
fix x axis for glucose graph in dynamic island
polscm32 Dec 1, 2023
a9b2096
change order of glucose graph items in lock screen
polscm32 Dec 2, 2023
f63f447
style lockscreen widget
polscm32 Dec 2, 2023
7c03637
add glucose bobble to lockscreen
polscm32 Dec 2, 2023
62c9f7c
fix padding
polscm32 Dec 2, 2023
d358ad3
improve lockscreen widget
polscm32 Dec 2, 2023
265251d
increase chart height
polscm32 Dec 2, 2023
b5ff233
fix padding in lockscreenwidget
polscm32 Dec 3, 2023
424febc
fix type error after merge
MikePlante1 Mar 10, 2024
3ccf434
various UI fixes
polscm32 Dec 9, 2023
3ac2c96
small fixes
polscm32 Dec 10, 2023
658ca58
use core data
polscm32 Dec 2, 2023
59af5be
fix conversion in mmol/L for y axis labels in live activity charts
polscm32 Dec 14, 2023
a1c1160
Bolus from watch (#326)
Jon-b-m Nov 11, 2023
a591e65
Revert "Bolus from watch (#326)"
MikePlante1 Mar 12, 2024
502411d
Live Activity Graph
polscm32 Dec 28, 2023
98fcad4
Various updates
polscm32 Dec 30, 2023
0d8af38
Revert "Various updates"
MikePlante1 Mar 12, 2024
570dd3a
add setting for live activity to display complex or simple view
polscm32 Dec 31, 2023
fddf723
readd enum
polscm32 Dec 31, 2023
b06ae0a
Fix merge conflicts when moving lockscreen setting to notifications menu
MikePlante1 Mar 12, 2024
b5859b5
fix x axis labels in live activity charts when near midnight
polscm32 Jan 6, 2024
c15ca1a
pull in live activity fixes from @nas10 and solve merge conflicts
polscm32 Jan 7, 2024
6e5766b
Revert "Fix merge conflicts when moving lockscreen setting to notific…
MikePlante1 Mar 12, 2024
62af6b1
Re-add lockscreen widget setting to StatsConfig menu, and reorganize it
MikePlante1 Mar 12, 2024
d37a7f1
use tresholds for high/low glucose from UI settings
polscm32 Mar 14, 2024
e061ea8
Merge branch 'dev' into liveActivities
MikePlante1 Mar 30, 2024
6da8d91
Revert "Re-add lockscreen widget setting to StatsConfig menu, and reo…
MikePlante1 Mar 30, 2024
4e2ea2b
Revert "Revert "Fix merge conflicts when moving lockscreen setting to…
MikePlante1 Mar 30, 2024
c4f7652
Add Lock Screen Widget setting to Notifications module
MikePlante1 Mar 31, 2024
1aa37e6
Use standard trend arrow for detailed lock screen widget
MikePlante1 Mar 31, 2024
916decc
Merge remote-tracking branch 'origin/dev' into liveActivities
Sjoerd-Bo3 Apr 3, 2024
ec1de8f
Merge branch 'dev' into liveActivities
MikePlante1 Apr 8, 2024
1f87aca
Update bundleID for LA in Fastfile
MikePlante1 Apr 8, 2024
5e7d8b0
Increase bottom padding of updatedLabel in LA
MikePlante1 Apr 8, 2024
dd80180
Fix padding of bgAndTrend label in LA
MikePlante1 Apr 8, 2024
0a161a1
Fix budleID in fastlane for LA
MikePlante1 Apr 9, 2024
189ecbf
Update Fastfile: fix for LiveActivity
bjornoleh Apr 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/create_certs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ jobs:
runs-on: macos-13
steps:
# Uncomment to manually select Xcode version if needed
#- name: Select Xcode version
# run: "sudo xcode-select --switch /Applications/Xcode_14.1.app/Contents/Developer"
- name: Select Xcode version
run: "sudo xcode-select --switch /Applications/Xcode_15.0.1.app/Contents/Developer"

# Checks-out the repo
- name: Checkout Repo
Expand Down
1 change: 1 addition & 0 deletions Core_Data.xcdatamodeld/Core_Data.xcdatamodel/contents
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
</entity>
<entity name="Readings" representedClassName="Readings" syncable="YES" codeGenerationType="class">
<attribute name="date" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="direction" optional="YES" attributeType="String"/>
<attribute name="glucose" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="id" optional="YES" attributeType="String"/>
</entity>
Expand Down
202 changes: 201 additions & 1 deletion FreeAPS.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

88 changes: 21 additions & 67 deletions FreeAPS.xcworkspace/xcshareddata/swiftpm/Package.resolved
Original file line number Diff line number Diff line change
@@ -1,70 +1,24 @@
{
"object": {
"pins": [
{
"package": "CryptoSwift",
"repositoryURL": "https://github.com/krzyzanowskim/CryptoSwift",
"state": {
"branch": null,
"revision": "19b3c3ceed117c5cc883517c4e658548315ba70b",
"version": "1.6.0"
}
},
{
"package": "swift-algorithms",
"repositoryURL": "https://github.com/apple/swift-algorithms",
"state": {
"branch": null,
"revision": "2327673b0e9c7e90e6b1826376526ec3627210e4",
"version": "0.2.1"
}
},
{
"package": "swift-numerics",
"repositoryURL": "https://github.com/apple/swift-numerics",
"state": {
"branch": null,
"revision": "6583ac70c326c3ee080c1d42d9ca3361dca816cd",
"version": "0.1.0"
}
},
{
"package": "SwiftCharts",
"repositoryURL": "https://github.com/ivanschuetz/SwiftCharts.git",
"state": {
"branch": "master",
"revision": "c354c1945bb35a1f01b665b22474f6db28cba4a2",
"version": null
}
},
{
"package": "SwiftDate",
"repositoryURL": "https://github.com/malcommac/SwiftDate",
"state": {
"branch": null,
"revision": "6190d0cefff3013e77ed567e6b074f324e5c5bf5",
"version": "6.3.1"
}
},
{
"package": "SwiftMessages",
"repositoryURL": "https://github.com/SwiftKickMobile/SwiftMessages",
"state": {
"branch": null,
"revision": "b29dd21090b708aa0ae9ecbaf6e2d0487028dc3f",
"version": "9.0.6"
}
},
{
"package": "Swinject",
"repositoryURL": "https://github.com/Swinject/Swinject",
"state": {
"branch": null,
"revision": "8bc503e60965298984fb58cf47b71c541449fe2a",
"version": "2.8.3"
}
"originHash" : "3bbb1091cfb3f1b8b58a093a985268a65a760f0d86e2d024e00ccab5721c0b89",
"pins" : [
{
"identity" : "cryptoswift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/krzyzanowskim/CryptoSwift",
"state" : {
"revision" : "19b3c3ceed117c5cc883517c4e658548315ba70b",
"version" : "1.6.0"
}
]
},
"version": 1
},
{
"identity" : "swiftcharts",
"kind" : "remoteSourceControl",
"location" : "https://github.com/ivanschuetz/SwiftCharts",
"state" : {
"branch" : "master",
"revision" : "c354c1945bb35a1f01b665b22474f6db28cba4a2"
}
}
],
"version" : 3
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@
"oneDimensionalGraph" : false,
"rulerMarks" : false,
"maxCarbs": 1000,
"displayFatAndProteinOnWatch": false
"displayFatAndProteinOnWatch": false,
"lockScreenView": "simple"
}
34 changes: 34 additions & 0 deletions FreeAPS/Sources/APS/Storage/CoreDataStorage.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import CoreData
import Foundation
import SwiftDate
import Swinject

final class CoreDataStorage {
let coredataContext = CoreDataStack.shared.persistentContainer.viewContext // newBackgroundContext()

func fetchGlucose(interval: NSDate) -> [Readings] {
var fetchGlucose = [Readings]()
coredataContext.performAndWait {
let requestReadings = Readings.fetchRequest() as NSFetchRequest<Readings>
let sort = NSSortDescriptor(key: "date", ascending: false)
requestReadings.sortDescriptors = [sort]
requestReadings.predicate = NSPredicate(
format: "glucose > 0 AND date > %@", interval
)
try? fetchGlucose = self.coredataContext.fetch(requestReadings)
}
return fetchGlucose
}

func fetchLatestOverride() -> [Override] {
var overrideArray = [Override]()
coredataContext.performAndWait {
let requestOverrides = Override.fetchRequest() as NSFetchRequest<Override>
let sortOverride = NSSortDescriptor(key: "date", ascending: false)
requestOverrides.sortDescriptors = [sortOverride]
requestOverrides.fetchLimit = 1
try? overrideArray = self.coredataContext.fetch(requestOverrides)
}
return overrideArray
}
}
3 changes: 3 additions & 0 deletions FreeAPS/Sources/APS/Storage/GlucoseStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,13 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
var bg_ = 0
var bgDate = Date()
var id = ""
var direction = ""

if glucose.isNotEmpty {
bg_ = glucose[0].glucose ?? 0
bgDate = glucose[0].dateString
id = glucose[0].id
direction = glucose[0].direction?.symbol ?? "↔︎"
}

if bg_ != 0 {
Expand All @@ -74,6 +76,7 @@ final class BaseGlucoseStorage: GlucoseStorage, Injectable {
dataForForStats.date = bgDate
dataForForStats.glucose = Int16(bg_)
dataForForStats.id = id
dataForForStats.direction = direction
try? self.coredataContext.save()
}
}
Expand Down
4 changes: 4 additions & 0 deletions FreeAPS/Sources/Application/FreeAPSApp.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import ActivityKit
import CoreData
import Foundation
import SwiftUI
Expand Down Expand Up @@ -45,6 +46,9 @@ import Swinject
_ = resolver.resolve(WatchManager.self)!
_ = resolver.resolve(HealthKitManager.self)!
_ = resolver.resolve(BluetoothStateManager.self)!
if #available(iOS 16.2, *) {
_ = resolver.resolve(LiveActivityBridge.self)!
}
}

init() {
Expand Down
6 changes: 6 additions & 0 deletions FreeAPS/Sources/Assemblies/ServiceAssembly.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,11 @@ final class ServiceAssembly: Assembly {
container.register(UserNotificationsManager.self) { r in BaseUserNotificationsManager(resolver: r) }
container.register(WatchManager.self) { r in BaseWatchManager(resolver: r) }
container.register(GarminManager.self) { r in BaseGarminManager(resolver: r) }

if #available(iOS 16.2, *) {
container.register(LiveActivityBridge.self) { r in
LiveActivityBridge(resolver: r)
}
}
}
}
1 change: 1 addition & 0 deletions FreeAPS/Sources/Models/DateFilter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import Foundation

struct DateFilter {
var twoHours = Date().addingTimeInterval(-2.hours.timeInterval) as NSDate
var today = Calendar.current.startOfDay(for: Date()) as NSDate
var day = Date().addingTimeInterval(-24.hours.timeInterval) as NSDate
var week = Date().addingTimeInterval(-7.days.timeInterval) as NSDate
Expand Down
9 changes: 9 additions & 0 deletions FreeAPS/Sources/Models/FreeAPSSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ struct FreeAPSSettings: JSON, Equatable {
var maxCarbs: Decimal = 1000
var displayFatAndProteinOnWatch: Bool = false
var onlyAutotuneBasals: Bool = false
var useLiveActivity: Bool = false
var lockScreenView: LockScreenView = .simple
}

extension FreeAPSSettings: Decodable {
Expand Down Expand Up @@ -224,6 +226,13 @@ extension FreeAPSSettings: Decodable {
settings.onlyAutotuneBasals = onlyAutotuneBasals
}

if let useLiveActivity = try? container.decode(Bool.self, forKey: .useLiveActivity) {
settings.useLiveActivity = useLiveActivity
}
if let lockScreenView = try? container.decode(LockScreenView.self, forKey: .lockScreenView) {
settings.lockScreenView = lockScreenView
}

self = settings
}
}
15 changes: 15 additions & 0 deletions FreeAPS/Sources/Models/LockScreenView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Foundation

enum LockScreenView: String, JSON, CaseIterable, Identifiable, Codable, Hashable {
var id: String { rawValue }
case simple
case detailed
var displayName: String {
switch self {
case .simple:
return NSLocalizedString("Simple", comment: "")
case .detailed:
return NSLocalizedString("Detailed", comment: "")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ extension NotificationsConfig {
@Published var lowGlucose: Decimal = 0
@Published var highGlucose: Decimal = 0
@Published var carbsRequiredThreshold: Decimal = 0
@Published var useLiveActivity = false
@Published var lockScreenView: LockScreenView = .simple
var units: GlucoseUnits = .mmolL

override func subscribe() {
Expand All @@ -20,7 +22,8 @@ extension NotificationsConfig {
subscribeSetting(\.useAlarmSound, on: $useAlarmSound) { useAlarmSound = $0 }
subscribeSetting(\.addSourceInfoToGlucoseNotifications, on: $addSourceInfoToGlucoseNotifications) {
addSourceInfoToGlucoseNotifications = $0 }

subscribeSetting(\.useLiveActivity, on: $useLiveActivity) { useLiveActivity = $0 }
subscribeSetting(\.lockScreenView, on: $lockScreenView) { lockScreenView = $0 }
subscribeSetting(\.lowGlucose, on: $lowGlucose, initial: {
let value = max(min($0, 400), 40)
lowGlucose = units == .mmolL ? value.asMmolL : value
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import ActivityKit
import Combine
import SwiftUI
import Swinject

Expand All @@ -6,6 +8,14 @@ extension NotificationsConfig {
let resolver: Resolver
@StateObject var state = StateModel()

@State private var systemLiveActivitySetting: Bool = {
if #available(iOS 16.1, *) {
ActivityAuthorizationInfo().areActivitiesEnabled
} else {
false
}
}()

private var glucoseFormatter: NumberFormatter {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
Expand All @@ -24,6 +34,71 @@ extension NotificationsConfig {
return formatter
}

@Environment(\.colorScheme) var colorScheme

var color: LinearGradient {
colorScheme == .dark ? LinearGradient(
gradient: Gradient(colors: [
Color("Background_1"),
Color("Background_1"),
Color("Background_2")
// Color("Background_1")
]),
startPoint: .top,
endPoint: .bottom
)
:
LinearGradient(
gradient: Gradient(colors: [Color.gray.opacity(0.1)]),
startPoint: .top,
endPoint: .bottom
)
}

@ViewBuilder private func liveActivitySection() -> some View {
if #available(iOS 16.2, *) {
Section(
header: Text("Live Activity"),
footer: Text(
liveActivityFooterText()
),
content: {
if !systemLiveActivitySetting {
Button("Open Settings App") {
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!)
}
} else {
Toggle("Show Live Activity", isOn: $state.useLiveActivity)
}
Picker(
selection: $state.lockScreenView,
label: Text("Lock screen widget")
) {
ForEach(LockScreenView.allCases) { selection in
Text(selection.displayName).tag(selection)
}
}
}
)
.onReceive(resolver.resolve(LiveActivityBridge.self)!.$systemEnabled, perform: {
self.systemLiveActivitySetting = $0
})
}
}

private func liveActivityFooterText() -> String {
var footer =
"Live activity displays blood glucose live on the lock screen and on the dynamic island (if available)"

if !systemLiveActivitySetting {
footer =
"Live activities are turned OFF in system settings. To enable live activities, go to Settings app -> iAPS -> Turn live Activities ON.\n\n" +
footer
}

return footer
}

var body: some View {
Form {
Section(header: Text("Glucose")) {
Expand Down Expand Up @@ -55,10 +130,12 @@ extension NotificationsConfig {
Text("g").foregroundColor(.secondary)
}
}
}
.onAppear(perform: configureView)
.navigationBarTitle("Notifications")
.navigationBarTitleDisplayMode(.automatic)

liveActivitySection()
}.scrollContentBackground(.hidden).background(color)
.onAppear(perform: configureView)
.navigationBarTitle("Notifications")
.navigationBarTitleDisplayMode(.automatic)
}
}
}
Loading