Skip to content

Commit d7965a9

Browse files
authored
Merge branch 'loopandlearn:main' into Main
2 parents f3e173f + e12342f commit d7965a9

10 files changed

Lines changed: 144 additions & 219 deletions

File tree

.github/workflows/build_LoopFollow.yml

Lines changed: 101 additions & 188 deletions
Large diffs are not rendered by default.

.github/workflows/validate_secrets.yml

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on: [workflow_call, workflow_dispatch]
55
jobs:
66
validate-access-token:
77
name: Access
8-
runs-on: macos-15
8+
runs-on: ubuntu-latest
99
env:
1010
GH_PAT: ${{ secrets.GH_PAT }}
1111
GH_TOKEN: ${{ secrets.GH_PAT }}
@@ -71,13 +71,6 @@ jobs:
7171
exit 2
7272
fi
7373
74-
validate-match-secrets:
75-
name: Match-Secrets
76-
needs: validate-access-token
77-
runs-on: macos-15
78-
env:
79-
GH_TOKEN: ${{ secrets.GH_PAT }}
80-
steps:
8174
- name: Validate Match-Secrets
8275
run: |
8376
# Validate Match-Secrets
@@ -111,7 +104,7 @@ jobs:
111104
112105
validate-fastlane-secrets:
113106
name: Fastlane
114-
needs: [validate-access-token, validate-match-secrets]
107+
needs: [validate-access-token]
115108
runs-on: macos-15
116109
env:
117110
GH_PAT: ${{ secrets.GH_PAT }}

Config.xcconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
unique_id = ${DEVELOPMENT_TEAM}
77

88
//Version (DEFAULT)
9-
LOOP_FOLLOW_MARKETING_VERSION = 4.1.0
9+
LOOP_FOLLOW_MARKETING_VERSION = 4.2.0

LoopFollow/Alarm/AlarmCondition/MissedReadingCondition.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,17 @@ struct MissedReadingCondition: AlarmCondition {
1717
// Skip if we have *no* readings
1818
guard let last = data.bgReadings.last else { return false }
1919

20+
guard let lastChecked = Storage.shared.lastBGChecked.value else {
21+
// Never checked, so don't alarm.
22+
return false
23+
}
24+
25+
let checkedAgeSeconds = now.timeIntervalSince(lastChecked)
26+
if checkedAgeSeconds > 360 { // 6 minutes
27+
// The check itself is stale, so the data is unreliable. Don't alarm.
28+
return false
29+
}
30+
2031
let secondsSinceLast = now.timeIntervalSince(last.date)
2132
return secondsSinceLast >= thresholdMinutes * 60
2233
}

LoopFollow/BackgroundRefresh/BT/BluetoothDevice.swift

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,11 +223,23 @@ class BluetoothDevice: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate
223223

224224
func centralManager(_: CBCentralManager, didDisconnectPeripheral _: CBPeripheral, error _: Error?) {
225225
timeStampLastStatusUpdate = Date()
226-
227226
bluetoothDeviceDelegate?.didDisconnectFrom(bluetoothDevice: self)
227+
cancelConnectionTimer()
228+
229+
guard let ownPeripheral = peripheral else { return }
228230

229-
if let ownPeripheral = peripheral {
230-
centralManager?.connect(ownPeripheral, options: nil)
231+
DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in
232+
guard let self = self,
233+
let manager = self.centralManager,
234+
manager.state == .poweredOn else { return }
235+
236+
switch ownPeripheral.state {
237+
case .connected, .connecting:
238+
// Already (re)connecting; do nothing
239+
break
240+
default:
241+
manager.connect(ownPeripheral, options: nil)
242+
}
231243
}
232244
}
233245

LoopFollow/Controllers/Nightscout/BGData.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ extension MainViewController {
4646
func webLoadNSBGData(dexData: [ShareGlucoseData] = []) {
4747
// This kicks it out in the instance where dexcom fails but they aren't using NS &&
4848
if !IsNightscoutEnabled() {
49+
Storage.shared.lastBGChecked.value = Date()
4950
return
5051
}
5152

@@ -109,6 +110,8 @@ extension MainViewController {
109110
// if we have Dex data, use it
110111
if !dexData.isEmpty {
111112
self.ProcessDexBGData(data: dexData, sourceName: "Dexcom")
113+
} else {
114+
Storage.shared.lastBGChecked.value = Date()
112115
}
113116
return
114117
}
@@ -121,6 +124,7 @@ extension MainViewController {
121124

122125
guard !data.isEmpty else {
123126
LogManager.shared.log(category: .nightscout, message: "No bg data received. Skipping processing.", limitIdentifier: "No bg data received. Skipping processing.")
127+
Storage.shared.lastBGChecked.value = Date()
124128
return
125129
}
126130

@@ -221,7 +225,10 @@ extension MainViewController {
221225
TaskScheduler.shared.rescheduleTask(id: .minAgoUpdate, to: Date())
222226

223227
let entries = self.bgData
224-
if entries.count < 2 { return } // Protect index out of bounds
228+
if entries.count < 2 { // Protect index out of bounds
229+
Storage.shared.lastBGChecked.value = Date()
230+
return
231+
}
225232

226233
self.updateBGGraph()
227234
self.updateStats()
@@ -264,6 +271,7 @@ extension MainViewController {
264271
stale: Observable.shared.bgStale.value
265272
)
266273
}
274+
Storage.shared.lastBGChecked.value = Date()
267275
}
268276
}
269277
}

LoopFollow/Controllers/Nightscout/DeviceStatus.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@ import UIKit
77

88
extension MainViewController {
99
func webLoadNSDeviceStatus() {
10-
Storage.shared.lastLoopingChecked.value = Date()
11-
1210
let parameters = ["count": "1"]
1311
NightscoutUtils.executeDynamicRequest(eventType: .deviceStatus, parameters: parameters) { result in
1412
switch result {
1513
case let .success(json):
1614
if let jsonDeviceStatus = json as? [[String: AnyObject]] {
1715
DispatchQueue.main.async {
1816
self.updateDeviceStatusDisplay(jsonDeviceStatus: jsonDeviceStatus)
17+
Storage.shared.lastLoopingChecked.value = Date()
1918
}
2019
} else {
2120
self.handleDeviceStatusError()
@@ -29,6 +28,7 @@ extension MainViewController {
2928
private func handleDeviceStatusError() {
3029
LogManager.shared.log(category: .deviceStatus, message: "Device status fetch failed!", limitIdentifier: "Device status fetch failed!")
3130
DispatchQueue.main.async {
31+
Storage.shared.lastLoopingChecked.value = Date()
3232
TaskScheduler.shared.rescheduleTask(id: .deviceStatus, to: Date().addingTimeInterval(10))
3333
self.evaluateNotLooping()
3434
}

LoopFollow/Remote/Settings/RemoteSettingsViewModel.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,15 @@ class RemoteSettingsViewModel: ObservableObject {
6262

6363
// Determine if a comparison is needed and perform it.
6464
switch remoteType {
65-
case .loopAPNS, .trc:
66-
// For both Loop and TRC, the target Team ID is in the same storage location.
65+
case .trc:
6766
// If the target ID is empty, there's nothing to compare.
6867
guard !targetTeamId.isEmpty else {
6968
return false
7069
}
7170
// Return true if the IDs are different.
7271
return loopFollowTeamID != targetTeamId
7372

74-
case .none, .nightscout:
73+
case .loopAPNS, .none, .nightscout:
7574
// For other remote types, this check is not applicable.
7675
return false
7776
}

LoopFollow/Storage/Storage.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ class Storage {
160160
var persistentNotificationLastBGTime = StorageValue<Date>(key: "persistentNotificationLastBGTime", defaultValue: .distantPast)
161161

162162
var lastLoopingChecked = StorageValue<Date?>(key: "lastLoopingChecked", defaultValue: nil)
163+
var lastBGChecked = StorageValue<Date?>(key: "lastBGChecked", defaultValue: nil)
163164

164165
var alarmsPosition = StorageValue<TabPosition>(key: "alarmsPosition", defaultValue: .position2)
165166
var remotePosition = StorageValue<TabPosition>(key: "remotePosition", defaultValue: .more)

fastlane/Fastfile

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,6 @@ platform :ios do
5959
]
6060
)
6161

62-
previous_build_number = latest_testflight_build_number(
63-
app_identifier: "com.#{TEAMID}.LoopFollow",
64-
api_key: api_key,
65-
)
66-
67-
current_build_number = previous_build_number + 1
68-
69-
increment_build_number(
70-
xcodeproj: "#{GITHUB_WORKSPACE}/LoopFollow.xcodeproj",
71-
build_number: current_build_number
72-
)
73-
7462
mapping = Actions.lane_context[
7563
SharedValues::MATCH_PROVISIONING_PROFILE_MAPPING
7664
]

0 commit comments

Comments
 (0)