Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
37 changes: 37 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# OS X
.DS_Store

# Xcode
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
profile
*.moved-aside
DerivedData
*.hmap
*.ipa
project.xcworkspace

# Bundler
.bundle

Carthage
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
#
# Note: if you ignore the Pods directory, make sure to uncomment
# `pod install` in .travis.yml
#

Pods/
Carthage/
.gitmodules
7 changes: 7 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
language: objective-c
osx_image: xcode10


script:
# Build Travis project and run tests
- xcodebuild -project ShareClient.xcodeproj -scheme ShareClient build -destination name="iPhone SE" test
1 change: 1 addition & 0 deletions Cartfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
github "LoopKit/LoopKit" ~> 2.0
1 change: 1 addition & 0 deletions Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
github "LoopKit/LoopKit" "v2.2.1"
21 changes: 21 additions & 0 deletions Common/LocalizedString.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// LocalizedString.swift
// LoopKit
//
// Created by Retina15 on 8/6/18.
// Copyright © 2018 LoopKit Authors. All rights reserved.
//

import Foundation

internal class FrameworkBundle {
static let main = Bundle(for: FrameworkBundle.self)
}

func LocalizedString(_ key: String, tableName: String? = nil, value: String? = nil, comment: String) -> String {
if let value = value {
return NSLocalizedString(key, tableName: tableName, bundle: FrameworkBundle.main, value: value, comment: comment)
} else {
return NSLocalizedString(key, tableName: tableName, bundle: FrameworkBundle.main, comment: comment)
}
}
463 changes: 457 additions & 6 deletions ShareClient.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0900"
LastUpgradeVersion = "0940"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand All @@ -26,7 +26,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
Expand Down Expand Up @@ -56,7 +55,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0940"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "43A8EC81210E664300A81379"
BuildableName = "ShareClientUI.framework"
BlueprintName = "ShareClientUI"
ReferencedContainer = "container:ShareClient.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "43A8EC81210E664300A81379"
BuildableName = "ShareClientUI.framework"
BlueprintName = "ShareClientUI"
ReferencedContainer = "container:ShareClient.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "43A8EC81210E664300A81379"
BuildableName = "ShareClientUI.framework"
BlueprintName = "ShareClientUI"
ReferencedContainer = "container:ShareClient.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
Binary file added ShareClient/Base.lproj/Localizable.strings
Binary file not shown.
16 changes: 16 additions & 0 deletions ShareClient/HKUnit.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// HKUnit.swift
// xDripG5
//
// Created by Nate Racklyeft on 8/6/16.
// Copyright © 2016 Nathan Racklyeft. All rights reserved.
//

import HealthKit


extension HKUnit {
static let milligramsPerDeciliter: HKUnit = {
return HKUnit.gramUnit(with: .milli).unitDivided(by: HKUnit.literUnit(with: .deci))
}()
}
2 changes: 1 addition & 1 deletion ShareClient/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.4.1</string>
<string>1.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down
2 changes: 1 addition & 1 deletion ShareClient/ShareClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ public class ShareClient {
private func parseDate(_ wt: String) throws -> Date {
// wt looks like "/Date(1462404576000)/"
let re = try NSRegularExpression(pattern: "\\((.*)\\)")
if let match = re.firstMatch(in: wt, range: NSMakeRange(0, wt.characters.count)) {
if let match = re.firstMatch(in: wt, range: NSMakeRange(0, wt.count)) {
#if swift(>=4)
let matchRange = match.range(at: 1)
#else
Expand Down
101 changes: 101 additions & 0 deletions ShareClient/ShareClientManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
//
// ShareClientManager.swift
// Loop
//
// Copyright © 2018 LoopKit Authors. All rights reserved.
//

import LoopKit
import HealthKit


public class ShareClientManager: CGMManager {
public static var managerIdentifier = "DexShareClient"

public init() {
shareService = ShareService(keychainManager: keychain)
}

required convenience public init?(rawState: CGMManager.RawStateValue) {
self.init()
}

public var rawState: CGMManager.RawStateValue {
return [:]
}

private let keychain = KeychainManager()

public var shareService: ShareService {
didSet {
try! keychain.setDexcomShareUsername(shareService.username, password: shareService.password, url: shareService.url)
}
}

public static let localizedTitle = LocalizedString("Dexcom Share", comment: "Title for the CGMManager option")

public let appURL: URL? = nil

weak public var cgmManagerDelegate: CGMManagerDelegate?

public let providesBLEHeartbeat = false

public let shouldSyncToRemoteService = false

public var sensorState: SensorDisplayable? {
return latestBackfill
}

public let managedDataInterval: TimeInterval? = nil

public private(set) var latestBackfill: ShareGlucose?

public func fetchNewDataIfNeeded(_ completion: @escaping (CGMResult) -> Void) {
guard let shareClient = shareService.client else {
completion(.noData)
return
}

// If our last glucose was less than 4.5 minutes ago, don't fetch.
if let latestGlucose = latestBackfill, latestGlucose.startDate.timeIntervalSinceNow > -TimeInterval(minutes: 4.5) {
completion(.noData)
return
}

shareClient.fetchLast(6) { (error, glucose) in
if let error = error {
completion(.error(error))
return
}
guard let glucose = glucose else {
completion(.noData)
return
}

// Ignore glucose values that are up to a minute newer than our previous value, to account for possible time shifting in Share data
let startDate = self.cgmManagerDelegate?.startDateToFilterNewData(for: self)?.addingTimeInterval(TimeInterval(minutes: 1))
let newGlucose = glucose.filterDateRange(startDate, nil)
let newSamples = newGlucose.filter({ $0.isStateValid }).map {
return NewGlucoseSample(date: $0.startDate, quantity: $0.quantity, isDisplayOnly: false, syncIdentifier: "\(Int($0.startDate.timeIntervalSince1970))", device: self.device)
}

self.latestBackfill = newGlucose.first

if newSamples.count > 0 {
completion(.newData(newSamples))
} else {
completion(.noData)
}
}
}

public var device: HKDevice? = nil

public var debugDescription: String {
return [
"## ShareClientManager",
"latestBackfill: \(String(describing: latestBackfill))",
""
].joined(separator: "\n")
}
}
47 changes: 47 additions & 0 deletions ShareClient/ShareGlucose+GlucoseKit.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// ShareGlucose+GlucoseKit.swift
// Naterade
//
// Created by Nathan Racklyeft on 5/8/16.
// Copyright © 2016 Nathan Racklyeft. All rights reserved.
//

import Foundation
import HealthKit
import LoopKit


extension ShareGlucose: GlucoseValue {
public var startDate: Date {
return timestamp
}

public var quantity: HKQuantity {
return HKQuantity(unit: .milligramsPerDeciliter, doubleValue: Double(glucose))
}
}


extension ShareGlucose: SensorDisplayable {
public var isStateValid: Bool {
return glucose >= 39
}

public var trendType: GlucoseTrend? {
return GlucoseTrend(rawValue: Int(trend))
}

public var isLocal: Bool {
return false
}
}

extension SensorDisplayable {
public var stateDescription: String {
if isStateValid {
return LocalizedString("OK", comment: "Sensor state description for the valid state")
} else {
return LocalizedString("Needs Attention", comment: "Sensor state description for the non-valid state")
}
}
}
Loading