Skip to content

Commit 9627d6c

Browse files
committed
Merge branch 'watch-app' into test-merge
2 parents a7d1270 + dd19e64 commit 9627d6c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+955
-523
lines changed

Loop.xcodeproj/project.pbxproj

Lines changed: 93 additions & 45 deletions
Large diffs are not rendered by default.

Loop/Managers/DeviceDataManager.swift

Lines changed: 29 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import LoopKit
1515
import MinimedKit
1616
import RileyLinkKit
1717
import ShareClient
18-
import WatchConnectivity
1918
import xDripG5
2019

2120
enum State<T> {
@@ -24,7 +23,7 @@ enum State<T> {
2423
}
2524

2625

27-
class DeviceDataManager: NSObject, CarbStoreDelegate, TransmitterDelegate, WCSessionDelegate {
26+
class DeviceDataManager: CarbStoreDelegate, TransmitterDelegate {
2827
/// Notification posted by the instance when new glucose data was processed
2928
static let GlucoseUpdatedNotification = "com.loudnate.Naterade.notification.GlucoseUpdated"
3029

@@ -245,32 +244,33 @@ class DeviceDataManager: NSObject, CarbStoreDelegate, TransmitterDelegate, WCSes
245244
assertCurrentPumpData()
246245
}
247246

248-
func transmitter(transmitter: Transmitter, didReadGlucose glucose: GlucoseRxMessage) {
247+
func transmitter(transmitter: Transmitter, didReadGlucose glucoseMessage: GlucoseRxMessage) {
249248
transmitterStartTime = transmitter.startTimeInterval
250249

251-
if glucose != latestGlucoseMessage {
252-
latestGlucoseMessage = glucose
250+
assertCurrentPumpData()
253251

254-
if glucose.glucose >= 20, let startDate = latestGlucoseMessageDate, glucoseStore = glucoseStore {
255-
let quantity = HKQuantity(unit: HKUnit.milligramsPerDeciliterUnit(), doubleValue: Double(glucose.glucose))
252+
guard glucoseMessage != latestGlucoseMessage else {
253+
return
254+
}
256255

257-
let device = HKDevice(name: "xDripG5", manufacturer: "Dexcom", model: "G5 Mobile", hardwareVersion: nil, firmwareVersion: nil, softwareVersion: String(xDripG5VersionNumber), localIdentifier: nil, UDIDeviceIdentifier: "00386270000002")
256+
latestGlucoseMessage = glucoseMessage
258257

259-
glucoseStore.addGlucose(quantity, date: startDate, displayOnly: glucose.glucoseIsDisplayOnly, device: device, resultHandler: { (_, value, error) -> Void in
260-
if let error = error {
261-
self.logger?.addError(error, fromSource: "GlucoseStore")
262-
}
258+
guard let glucose = TransmitterGlucose(glucoseMessage: glucoseMessage, startTime: transmitter.startTimeInterval), glucoseStore = glucoseStore else {
259+
NSNotificationCenter.defaultCenter().postNotificationName(self.dynamicType.GlucoseUpdatedNotification, object: self)
260+
return
261+
}
263262

264-
NSNotificationCenter.defaultCenter().postNotificationName(self.dynamicType.GlucoseUpdatedNotification, object: self)
265-
})
263+
latestGlucoseValue = glucose
266264

267-
updateWatch()
268-
} else {
269-
NSNotificationCenter.defaultCenter().postNotificationName(self.dynamicType.GlucoseUpdatedNotification, object: self)
265+
let device = HKDevice(name: "xDripG5", manufacturer: "Dexcom", model: "G5 Mobile", hardwareVersion: nil, firmwareVersion: nil, softwareVersion: String(xDripG5VersionNumber), localIdentifier: nil, UDIDeviceIdentifier: "00386270000002")
266+
267+
glucoseStore.addGlucose(glucose.quantity, date: glucose.startDate, displayOnly: glucoseMessage.glucoseIsDisplayOnly, device: device, resultHandler: { (_, _, error) -> Void in
268+
if let error = error {
269+
self.logger?.addError(error, fromSource: "GlucoseStore")
270270
}
271-
}
272271

273-
assertCurrentPumpData()
272+
NSNotificationCenter.defaultCenter().postNotificationName(self.dynamicType.GlucoseUpdatedNotification, object: self)
273+
})
274274
}
275275

276276
// MARK: G5 data
@@ -289,19 +289,13 @@ class DeviceDataManager: NSObject, CarbStoreDelegate, TransmitterDelegate, WCSes
289289

290290
var latestGlucoseMessage: GlucoseRxMessage?
291291

292-
var latestGlucoseMessageDate: NSDate? {
293-
guard let glucose = latestGlucoseMessage, startTime = transmitterStartTime else {
294-
return nil
295-
}
296-
297-
return NSDate(timeIntervalSince1970: startTime).dateByAddingTimeInterval(NSTimeInterval(glucose.timestamp))
298-
}
292+
var latestGlucoseValue: GlucoseValue?
299293

300294
/**
301295
Attempts to backfill glucose data from the share servers if the G5 connection hasn't been established.
302296
*/
303297
private func backfillGlucoseFromShareIfNeeded() {
304-
if self.latestGlucoseMessageDate == nil,
298+
if latestGlucoseMessage == nil,
305299
let shareClient = self.shareClient, glucoseStore = self.glucoseStore
306300
{
307301
// Load glucose from Share if our xDripG5 connection hasn't started
@@ -324,6 +318,8 @@ class DeviceDataManager: NSObject, CarbStoreDelegate, TransmitterDelegate, WCSes
324318
self.logger?.addError(error, fromSource: "GlucoseStore")
325319
}
326320

321+
self.latestGlucoseValue = value
322+
327323
NSNotificationCenter.defaultCenter().postNotificationName(self.dynamicType.GlucoseUpdatedNotification, object: self)
328324
}
329325
}
@@ -542,125 +538,10 @@ class DeviceDataManager: NSObject, CarbStoreDelegate, TransmitterDelegate, WCSes
542538

543539
// MARK: - WatchKit
544540

545-
private var watchSession: WCSession? = {
546-
if WCSession.isSupported() {
547-
return WCSession.defaultSession()
548-
} else {
549-
return nil
550-
}
551-
}()
552-
553-
private func updateWatch() {
554-
if let session = watchSession {
555-
switch session.activationState {
556-
case .NotActivated, .Inactive:
557-
session.activateSession()
558-
case .Activated:
559-
sendWatchContext()
560-
}
561-
}
562-
}
563-
564-
private var latestComplicationGlucose: GlucoseRxMessage?
565-
566-
private func sendWatchContext() {
567-
if let session = watchSession where session.paired && session.watchAppInstalled {
568-
let userInfo = WatchContext(pumpStatus: latestPumpStatus, glucose: latestGlucoseMessage, glucoseMessageDate: latestGlucoseMessageDate).rawValue
569-
570-
let complicationShouldUpdate: Bool
571-
572-
if let complicationGlucose = latestComplicationGlucose, glucose = latestGlucoseMessage {
573-
complicationShouldUpdate = Int(glucose.timestamp) - Int(complicationGlucose.timestamp) >= 30 * 60 || abs(Int(glucose.glucose) - Int(complicationGlucose.glucose)) >= 20
574-
} else {
575-
complicationShouldUpdate = true
576-
}
577-
578-
if session.complicationEnabled && complicationShouldUpdate, let glucose = latestGlucoseMessage {
579-
session.transferCurrentComplicationUserInfo(userInfo)
580-
latestComplicationGlucose = glucose
581-
} else {
582-
do {
583-
try session.updateApplicationContext(userInfo)
584-
} catch let error {
585-
self.logger?.addError(error, fromSource: "WCSession")
586-
}
587-
}
588-
}
589-
}
590-
591-
private func addCarbEntryFromWatchMessage(message: [String: AnyObject], completionHandler: ((units: Double?, error: ErrorType?) -> Void)? = nil) {
592-
if let carbStore = carbStore, carbEntry = CarbEntryUserInfo(rawValue: message) {
593-
let newEntry = NewCarbEntry(
594-
quantity: HKQuantity(unit: carbStore.preferredUnit, doubleValue: carbEntry.value),
595-
startDate: carbEntry.startDate,
596-
foodType: nil,
597-
absorptionTime: carbEntry.absorptionTimeType.absorptionTimeFromDefaults(carbStore.defaultAbsorptionTimes)
598-
)
541+
private(set) var watchManager: WatchDataManager!
599542

600-
loopManager.addCarbEntryAndRecommendBolus(newEntry) { (units, error) in
601-
if let error = error {
602-
self.logger?.addError(error, fromSource: error is CarbStore.Error ? "CarbStore" : "Bolus")
603-
} else {
604-
AnalyticsManager.didAddCarbsFromWatch(carbEntry.value)
605-
}
606-
607-
completionHandler?(units: units, error: error)
608-
}
609-
} else {
610-
completionHandler?(units: nil, error: Error.ValueError("Unable to parse CarbEntryUserInfo: \(message)"))
611-
}
612-
}
613-
614-
// MARK: WCSessionDelegate
615-
616-
func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String: AnyObject]) -> Void) {
617-
switch message["name"] as? String {
618-
case CarbEntryUserInfo.name?:
619-
addCarbEntryFromWatchMessage(message) { (units, error) in
620-
replyHandler(BolusSuggestionUserInfo(recommendedBolus: units ?? 0).rawValue)
621-
}
622-
case SetBolusUserInfo.name?:
623-
if let bolus = SetBolusUserInfo(rawValue: message) {
624-
self.loopManager.enactBolus(bolus.value) { (success, error) in
625-
if !success {
626-
NotificationManager.sendBolusFailureNotificationForAmount(bolus.value, atDate: bolus.startDate)
627-
} else {
628-
AnalyticsManager.didSetBolusFromWatch(bolus.value)
629-
}
630-
631-
replyHandler([:])
632-
}
633-
} else {
634-
replyHandler([:])
635-
}
636-
default:
637-
break
638-
}
639-
}
640-
641-
func session(session: WCSession, didReceiveUserInfo userInfo: [String : AnyObject]) {
642-
addCarbEntryFromWatchMessage(userInfo)
643-
}
644-
645-
func session(session: WCSession, activationDidCompleteWithState activationState: WCSessionActivationState, error: NSError?) {
646-
switch activationState {
647-
case .Activated:
648-
if let error = error {
649-
logger?.addError(error, fromSource: "WCSession")
650-
}
651-
case .Inactive, .NotActivated:
652-
break
653-
}
654-
}
655-
656-
func sessionDidBecomeInactive(session: WCSession) {
657-
// Nothing to do here
658-
}
659-
660-
func sessionDidDeactivate(session: WCSession) {
661-
watchSession = WCSession.defaultSession()
662-
watchSession?.delegate = self
663-
watchSession?.activateSession()
543+
@objc private func loopDataDidUpdateNotification(_: NSNotification) {
544+
watchManager.updateWatch()
664545
}
665546

666547
// MARK: - Initialization
@@ -669,7 +550,7 @@ class DeviceDataManager: NSObject, CarbStoreDelegate, TransmitterDelegate, WCSes
669550

670551
private(set) var loopManager: LoopDataManager!
671552

672-
override init() {
553+
init() {
673554
let pumpID = NSUserDefaults.standardUserDefaults().pumpID
674555

675556
doseStore = DoseStore(
@@ -716,8 +597,6 @@ class DeviceDataManager: NSObject, CarbStoreDelegate, TransmitterDelegate, WCSes
716597
shareClient = nil
717598
}
718599

719-
super.init()
720-
721600
rileyLinkManagerObserver = NSNotificationCenter.defaultCenter().addObserverForName(nil, object: rileyLinkManager, queue: nil) { [weak self] (note) -> Void in
722601
self?.receivedRileyLinkManagerNotification(note)
723602
}
@@ -732,9 +611,9 @@ class DeviceDataManager: NSObject, CarbStoreDelegate, TransmitterDelegate, WCSes
732611
}
733612

734613
loopManager = LoopDataManager(deviceDataManager: self)
614+
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(loopDataDidUpdateNotification(_:)), name: LoopDataManager.LoopDataUpdatedNotification, object: loopManager)
735615

736-
watchSession?.delegate = self
737-
watchSession?.activateSession()
616+
watchManager = WatchDataManager(deviceDataManager: self)
738617

739618
carbStore?.delegate = self
740619

@@ -749,22 +628,3 @@ class DeviceDataManager: NSObject, CarbStoreDelegate, TransmitterDelegate, WCSes
749628
}
750629
}
751630

752-
753-
extension WatchContext {
754-
convenience init(pumpStatus: MySentryPumpStatusMessageBody?, glucose: GlucoseRxMessage?, glucoseMessageDate: NSDate?) {
755-
self.init()
756-
757-
if let glucose = glucose, date = glucoseMessageDate where glucose.state > 5 {
758-
glucoseValue = Int(glucose.glucose)
759-
glucoseTrend = Int(glucose.trend)
760-
glucoseDate = date
761-
}
762-
763-
if let status = pumpStatus, date = status.pumpDateComponents.date {
764-
IOB = status.iob
765-
reservoir = status.reservoirRemainingUnits
766-
pumpDate = date
767-
}
768-
}
769-
}
770-

0 commit comments

Comments
 (0)