Skip to content

Commit f5df3eb

Browse files
committed
Bugfixes and interface improvements
1 parent ad3c3b1 commit f5df3eb

19 files changed

+232
-219
lines changed

InfiniLink.xcodeproj/project.pbxproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -338,13 +338,13 @@
338338
path = InfiniLinkUITests;
339339
sourceTree = "<group>";
340340
};
341-
E02C62102CD05D8E00C4D19B /* Software Update */ = {
341+
E02C62102CD05D8E00C4D19B /* Update */ = {
342342
isa = PBXGroup;
343343
children = (
344344
E0A7C08A2CB1E4CC0042A12D /* SoftwareUpdateView.swift */,
345345
E02C62112CD05DA900C4D19B /* CurrentUpdateView.swift */,
346346
);
347-
path = "Software Update";
347+
path = Update;
348348
sourceTree = "<group>";
349349
};
350350
E03C30B32CC7030A00DD8363 /* Notifications */ = {
@@ -509,7 +509,7 @@
509509
E0A7C0892CB1E4BF0042A12D /* General */ = {
510510
isa = PBXGroup;
511511
children = (
512-
E02C62102CD05D8E00C4D19B /* Software Update */,
512+
E02C62102CD05D8E00C4D19B /* Update */,
513513
E0599A052CB4C75500D64E0B /* Filesystem */,
514514
E05999B62CB2FC6400D64E0B /* About */,
515515
E0A7C0872CB1BBE70042A12D /* GeneralSettingsView.swift */,

InfiniLink/BLE/BLECharacteristicHandler.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,12 @@ struct BLECharacteristicHandler {
7878
BLEWriteManager().setTime(characteristic: characteristic)
7979
case bleManager.cbuuidList.weather:
8080
bleManager.weatherCharacteristic = characteristic
81-
8281
case bleManager.cbuuidList.dfuControlPoint:
8382
bleManager.dfuControlPointCharacteristic = characteristic
8483
peripheral.setNotifyValue(true, for: characteristic)
8584
case bleManager.cbuuidList.dfuPacket:
8685
bleManager.dfuPacketCharacteristic = characteristic
8786
peripheral.setNotifyValue(true, for: characteristic)
88-
8987
case bleManager.cbuuidList.navigationFlags:
9088
bleManager.navigationFlagsCharacteristic = characteristic
9189
case bleManager.cbuuidList.navigationNarrative:

InfiniLink/BLE/BLEManager.swift

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
144144

145145
if let peripheral = peripherals.first, !isConnectedToPinetime {
146146
// FIXME: should we add a check to confirm the watch is already not connected to the system (state != .connected), or let it pair this way?
147-
connect(peripheral: peripheral) {}
147+
connect(peripheral: peripheral)
148148
} else {
149149
scanForNewDevices()
150150
}
@@ -161,20 +161,19 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
161161
func connect(peripheral: CBPeripheral, completion: (() -> Void)? = nil) {
162162
guard isBluetoothOn else { return }
163163

164-
if peripheral.name == "InfiniTime" {
165-
isConnecting = true
166-
peripheralToConnect = peripheral
167-
central.connect(peripheralToConnect, options: nil)
168-
169-
completion?()
170-
}
164+
isConnecting = true
165+
peripheralToConnect = peripheral
166+
central.connect(peripheralToConnect, options: nil)
167+
168+
completion?()
171169
}
172170

173-
func onConnect() {
171+
func onConnect(_ peripheral: CBPeripheral) {
174172
stopScanning()
175173

174+
// downloadManager.clearUpdate()
175+
176176
isConnecting = false
177-
downloadManager.updateAvailable = false
178177
pairedDeviceID = peripheralToConnect.identifier.uuidString
179178
pairedDevice = deviceManager.fetchDevice(with: peripheralToConnect.identifier.uuidString)
180179
hasDisconnectedForUpdate = false
@@ -183,11 +182,14 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
183182
infiniTime?.delegate = self
184183
infiniTime.discoverServices(nil)
185184
isConnectedToPinetime = true
185+
peripheralToConnect = nil // We're done using this, so set it to nil
186186

187187
log("Connected to \(pairedDevice?.name ?? "InfiniTime")", type: .info, caller: "BLEManager", target: .ble)
188188
}
189189

190190
func unpair(device: Device? = nil) {
191+
// We need to disconnect first because BLE updateInfo methods will be called when Core Data doesn't have an object to update
192+
disconnect()
191193
// Delete the device object we have said for this watch
192194
deviceManager.removeDevice(device ?? pairedDevice!)
193195
// FIXME: Better way to do this? We have to give core data some time to update
@@ -204,7 +206,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
204206
pairedDeviceID = nil
205207
// This only disconnects and removes the watch from the recognized device list in the app. If using secure pairing, iOS will still keep the bond
206208
// and we have no way to remove it
207-
disconnect()
208209
startScanning()
209210
}
210211

@@ -233,7 +234,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
233234
// We just switched devices, update the UI
234235
self.pairedDeviceID = device.uuid
235236
self.pairedDevice = deviceManager.fetchDevice()
236-
self.deviceManager.getSettings()
237237

238238
self.disconnect()
239239
self.startScanning()
@@ -276,7 +276,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
276276

277277
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
278278
// The connection was successfully, update state vars and start service discovery
279-
onConnect()
279+
onConnect(peripheral)
280280
}
281281

282282
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {

InfiniLink/BLE/DeviceManager.swift

Lines changed: 68 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,17 @@ import SwiftUI
99
import CoreData
1010
import CoreBluetooth
1111

12+
struct CharacteristicIdentifier {
13+
static let modelNumber = CBUUID(string: "2A24")
14+
static let serial = CBUUID(string: "2A25")
15+
static let firmware = CBUUID(string: "2A26")
16+
static let hardwareRevision = CBUUID(string: "2A27")
17+
static let softwareRevision = CBUUID(string: "2A28")
18+
static let manufacturer = CBUUID(string: "2A29")
19+
static let blefsVersion = CBUUID(string: "adaf0100-4669-6c65-5472-616e73666572")
20+
}
21+
1222
class DeviceManager: ObservableObject {
13-
struct cbuuid {
14-
let modelNumber = CBUUID(string: "2A24")
15-
let serial = CBUUID(string: "2A25")
16-
let firmware = CBUUID(string: "2A26")
17-
let hardwareRevision = CBUUID(string: "2A27")
18-
let softwareRevision = CBUUID(string: "2A28")
19-
let manufacturer = CBUUID(string: "2A29")
20-
let blefsVersion = CBUUID(string: "adaf0100-4669-6c65-5472-616e73666572")
21-
}
22-
let cbuuids = cbuuid()
23-
2423
let persistenceController = PersistenceController.shared
2524
let bleManager = BLEManager.shared
2625

@@ -61,9 +60,9 @@ class DeviceManager: ObservableObject {
6160
@Published var settings = Settings()
6261
@Published var watches = [Device]()
6362

64-
// Get persisted settings, before settings.dat has loaded
65-
func getSettings() {
66-
guard let device = bleManager.pairedDevice else { return }
63+
// Update persisted settings, before settings.dat has loaded
64+
func setSettings(_ device: Device? = nil) {
65+
let device = device ?? fetchDevice()!
6766

6867
DispatchQueue.main.async {
6968
self.settings = Settings(
@@ -88,19 +87,20 @@ class DeviceManager: ObservableObject {
8887
func fetchDevice(with uuid: String? = nil) -> Device? {
8988
guard let id = uuid ?? bleManager.pairedDeviceID else { return nil }
9089

90+
let context = persistenceController.container.viewContext
9191
let fetchRequest: NSFetchRequest<Device> = Device.fetchRequest()
9292
fetchRequest.predicate = NSPredicate(format: "uuid == %@", id)
9393

9494
do {
95-
let existingDevices = try persistenceController.container.viewContext.fetch(fetchRequest)
95+
let existingDevices = try context.fetch(fetchRequest)
9696

9797
// There's already a paired watch
9898
if let existingDevice = existingDevices.first {
99+
setSettings(existingDevice)
99100
return existingDevice
100101
}
101102

102103
// There's not already a paired watch, create a new object to save
103-
let context = persistenceController.container.newBackgroundContext()
104104
let newDevice = Device(context: context)
105105
context.perform {
106106
newDevice.uuid = id
@@ -120,6 +120,8 @@ class DeviceManager: ObservableObject {
120120
}
121121
}
122122

123+
setSettings(newDevice)
124+
123125
return newDevice
124126
} catch {
125127
log("Error fetching or saving device: \(error)", caller: "DeviceManager")
@@ -133,7 +135,7 @@ class DeviceManager: ObservableObject {
133135
let context = persistenceController.container.viewContext
134136

135137
// MARK: - Crash
136-
// Crashes happening when creating watch face objects from the viewContext
138+
// Crashes occasionally happening when creating watch face objects from the viewContext
137139
context.perform {
138140
device.brightLevel = Int16(settings.brightLevel.rawValue)
139141
device.chimesOption = Int16(settings.chimesOption.rawValue)
@@ -164,12 +166,13 @@ class DeviceManager: ObservableObject {
164166
log("Error saving settings: \(error.localizedDescription)", caller: "DeviceManager - updateSettings")
165167
}
166168
}
167-
getSettings()
169+
170+
// We've gotten the settings from the watch, now set our variables
171+
setSettings(device)
168172
}
169173

170-
func updateName(name: String, for device: Device) {
171-
guard let uuid = device.uuid else { return }
172-
guard let device = fetchDevice(with: uuid) else { return }
174+
func updateName(name: String, for id: String) {
175+
guard let device = fetchDevice(with: id) else { return }
173176

174177
device.name = name
175178

@@ -196,49 +199,63 @@ class DeviceManager: ObservableObject {
196199
func fetchAllDevices() {
197200
let fetchRequest: NSFetchRequest<Device> = Device.fetchRequest()
198201

199-
do {
200-
self.watches = try self.persistenceController.container.viewContext.fetch(fetchRequest)
201-
} catch {
202-
log("Error fetching devices: \(error.localizedDescription)", caller: "DeviceManager")
202+
DispatchQueue.main.async {
203+
do {
204+
self.watches = try self.persistenceController.container.viewContext.fetch(fetchRequest)
205+
} catch {
206+
log("Error fetching devices: \(error.localizedDescription)", caller: "DeviceManager")
207+
}
203208
}
204209
}
205210
}
206211

207212
extension DeviceManager {
208213
func updateInfo(characteristic: CBCharacteristic) {
209214
guard let value = characteristic.value else { return }
210-
guard bleManager.pairedDevice != nil else { return }
211-
212-
bleManager.pairedDevice.bleUUID = characteristic.uuid.uuidString
213-
214-
switch characteristic.uuid {
215-
case cbuuids.modelNumber:
216-
bleManager.pairedDevice.modelNumber = String(data: value, encoding: .utf8) ?? ""
217-
case cbuuids.serial:
218-
bleManager.pairedDevice.serial = String(data: value, encoding: .utf8) ?? ""
219-
case cbuuids.firmware:
220-
bleManager.pairedDevice.firmware = String(data: value, encoding: .utf8) ?? ""
221-
case cbuuids.hardwareRevision:
222-
bleManager.pairedDevice.hardwareRevision = String(data: value, encoding: .utf8) ?? ""
223-
case cbuuids.softwareRevision:
224-
bleManager.pairedDevice.softwareRevision = String(data: value, encoding: .utf8) ?? ""
225-
case cbuuids.manufacturer:
226-
bleManager.pairedDevice.manufacturer = String(data: value, encoding: .utf8) ?? ""
227-
case cbuuids.blefsVersion:
228-
let byteArray = [UInt8](value)
229-
if byteArray.count >= 2 {
230-
bleManager.pairedDevice.blefsVersion = "\(Int(byteArray[1]))\(Int(byteArray[0]))"
231-
} else {
232-
bleManager.pairedDevice.blefsVersion = "00" // or some fallback
215+
guard let objectID = bleManager.pairedDevice?.objectID else { return }
216+
217+
let context = persistenceController.container.viewContext
218+
219+
context.perform {
220+
do {
221+
guard let device = try context.existingObject(with: objectID) as? Device else { return }
222+
223+
device.bleUUID = characteristic.uuid.uuidString
224+
225+
switch characteristic.uuid {
226+
case CharacteristicIdentifier.modelNumber:
227+
device.modelNumber = String(data: value, encoding: .utf8) ?? ""
228+
case CharacteristicIdentifier.serial:
229+
device.serial = String(data: value, encoding: .utf8) ?? ""
230+
case CharacteristicIdentifier.firmware:
231+
device.firmware = String(data: value, encoding: .utf8) ?? ""
232+
case CharacteristicIdentifier.hardwareRevision:
233+
device.hardwareRevision = String(data: value, encoding: .utf8) ?? ""
234+
case CharacteristicIdentifier.softwareRevision:
235+
device.softwareRevision = String(data: value, encoding: .utf8) ?? ""
236+
case CharacteristicIdentifier.manufacturer:
237+
device.manufacturer = String(data: value, encoding: .utf8) ?? ""
238+
case CharacteristicIdentifier.blefsVersion:
239+
let byteArray = [UInt8](value)
240+
if byteArray.count >= 2 {
241+
device.blefsVersion = "\(Int(byteArray[1]))\(Int(byteArray[0]))"
242+
} else {
243+
device.blefsVersion = "00"
244+
}
245+
default:
246+
break
247+
}
248+
249+
try context.save()
250+
} catch {
251+
log("Failed to update paired device: \(error)", caller: "DeviceManager", target: .ble)
233252
}
234-
default:
235-
break
236253
}
237254
}
238255

239256
func readInfoCharacteristics(characteristic: CBCharacteristic, peripheral: CBPeripheral) {
240257
switch characteristic.uuid {
241-
case cbuuids.modelNumber, cbuuids.serial, cbuuids.firmware, cbuuids.hardwareRevision, cbuuids.softwareRevision, cbuuids.manufacturer, cbuuids.blefsVersion: peripheral.readValue(for: characteristic)
258+
case CharacteristicIdentifier.modelNumber, CharacteristicIdentifier.serial, CharacteristicIdentifier.firmware, CharacteristicIdentifier.hardwareRevision, CharacteristicIdentifier.softwareRevision, CharacteristicIdentifier.manufacturer, CharacteristicIdentifier.blefsVersion: peripheral.readValue(for: characteristic)
242259
default:
243260
break
244261
}

InfiniLink/ContentView.swift

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,14 @@ import SwiftUI
99
import EventKit
1010

1111
struct ContentView: View {
12-
@ObservedObject var bleManager = BLEManager.shared
13-
@ObservedObject var remindersManager = RemindersManager.shared
14-
@ObservedObject var personalizationController = PersonalizationController.shared
15-
@ObservedObject var notificationManager = NotificationManager.shared
12+
@ObservedObject private var bleManager = BLEManager.shared
1613

17-
@AppStorage("pairedDeviceID") var pairedDeviceID: String?
14+
@AppStorage("pairedDeviceID") private var pairedDeviceID: String?
1815

1916
var body: some View {
2017
Group {
2118
if pairedDeviceID != nil {
2219
DeviceView()
23-
.onChange(of: bleManager.weatherCharacteristic) { _ in
24-
WeatherController.shared.fetchWeatherData()
25-
}
26-
.onChange(of: bleManager.batteryLevel) { bat in
27-
notificationManager.checkToSendLowBatteryNotification()
28-
}
29-
.sheet(isPresented: $personalizationController.showSetupSheet) {
30-
SetUpDetailsView()
31-
}
3220
} else {
3321
WelcomeView()
3422
}

InfiniLink/Core/Components/WatchFaceView.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,11 @@ struct WatchFaceView: View {
1616

1717
let date = Date()
1818

19-
@Binding var watchface: UInt8?
20-
19+
let watchface: UInt8?
2120
let device: Device?
2221

23-
init(watchface: Binding<UInt8?>, device: Device? = nil) {
24-
self._watchface = watchface
22+
init(watchface: UInt8? = nil, device: Device? = nil) {
23+
self.watchface = watchface
2524
self.device = device
2625
}
2726

0 commit comments

Comments
 (0)