From 93acbdab59bd806abb900444ba0f8229c55a9d96 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 25 Jun 2018 23:42:08 -0500 Subject: [PATCH 01/22] Rl statistics (#412) * Add GetStatistics command * Fix session description for enable LEDs * Add UI command for getting RL statistics * Handle command interrupted before attempting to parse response. * Fix tests --- RileyLinkBLEKit/Command.swift | 9 +++++ RileyLinkBLEKit/CommandSession.swift | 33 ++++++++++++++++- .../PeripheralManager+RileyLink.swift | 26 +++++++------ RileyLinkBLEKit/RadioFirmwareVersion.swift | 15 ++++++++ RileyLinkBLEKit/Response.swift | 37 +++++++++++++++++++ RileyLinkKit/PumpMessageSender.swift | 3 ++ RileyLinkKit/PumpOpsSession.swift | 4 ++ .../PumpOpsSynchronousTests.swift | 4 ++ ...sponseViewController+RileyLinkDevice.swift | 23 +++++++++++- .../RileyLinkDeviceTableViewController.swift | 7 ++++ 10 files changed, 148 insertions(+), 13 deletions(-) diff --git a/RileyLinkBLEKit/Command.swift b/RileyLinkBLEKit/Command.swift index 6484176ac..542fcd243 100644 --- a/RileyLinkBLEKit/Command.swift +++ b/RileyLinkBLEKit/Command.swift @@ -23,6 +23,7 @@ enum RileyLinkCommand: UInt8 { case setSWEncoding = 11 case setPreamble = 12 case resetRadioConfig = 13 + case getStatistics = 14 } enum RileyLinkLEDType: UInt8 { @@ -291,3 +292,11 @@ struct ResetRadioConfig: Command { return Data(bytes: [RileyLinkCommand.resetRadioConfig.rawValue]) } } + +struct GetStatistics: Command { + typealias ResponseType = GetStatisticsResponse + + var data: Data { + return Data(bytes: [RileyLinkCommand.getStatistics.rawValue]) + } +} diff --git a/RileyLinkBLEKit/CommandSession.swift b/RileyLinkBLEKit/CommandSession.swift index 1940ab4a1..3686f7e50 100644 --- a/RileyLinkBLEKit/CommandSession.swift +++ b/RileyLinkBLEKit/CommandSession.swift @@ -51,6 +51,27 @@ public enum CC111XRegister: UInt8 { case paTable0 = 0x2e } +public struct RileyLinkStatistics { + public let uptime: TimeInterval + public let radioRxOverflowCount: UInt16 + public let radioRxFifoOverflowCount: UInt16 + public let packetRxCount: UInt16 + public let packetTxCount: UInt16 + public let crcFailureCount: UInt16 + public let spiSyncFailureCount: UInt16 + + public init(uptime: TimeInterval, radioRxOverflowCount: UInt16, radioRxFifoOverflowCount: UInt16, packetRxCount: UInt16, packetTxCount: UInt16, crcFailureCount: UInt16, spiSyncFailureCount: UInt16) { + self.uptime = uptime + self.radioRxOverflowCount = radioRxOverflowCount + self.radioRxFifoOverflowCount = radioRxFifoOverflowCount + self.packetRxCount = packetRxCount + self.packetTxCount = packetTxCount + self.crcFailureCount = crcFailureCount + self.spiSyncFailureCount = spiSyncFailureCount + } + +} + public struct CommandSession { let manager: PeripheralManager let responseType: PeripheralManager.ResponseType @@ -212,5 +233,15 @@ public struct CommandSession { let command = ResetRadioConfig() _ = try writeCommand(command, timeout: 0) } - + + public func getRileyLinkStatistics() throws -> RileyLinkStatistics { + guard firmwareVersion.supportsRileyLinkStatistics else { + throw RileyLinkDeviceError.unsupportedCommand(.getStatistics) + } + + let command = GetStatistics() + let response: GetStatisticsResponse = try writeCommand(command, timeout: 0) + + return response.statistics + } } diff --git a/RileyLinkBLEKit/PeripheralManager+RileyLink.swift b/RileyLinkBLEKit/PeripheralManager+RileyLink.swift index 548f3c20b..eeaff68ec 100644 --- a/RileyLinkBLEKit/PeripheralManager+RileyLink.swift +++ b/RileyLinkBLEKit/PeripheralManager+RileyLink.swift @@ -321,27 +321,31 @@ extension PeripheralManager { } addCondition(.valueUpdate(characteristic: characteristic, matching: { value in - guard let value = value else { + guard let value = value, value.count > 0 else { + log.debug("Empty response from RileyLink. Continuing to listen for command response.") return false } - + log.debug("RL Recv(single): %@", value.hexadecimalString) - guard let response = R(data: value) else { - // We don't recognize the contents. Keep listening. + guard let code = ResponseCode(rawValue: value[0]) else { + let unknownCode = value[0..<1].hexadecimalString + log.debug("Unknown response code from RileyLink: %{public}@. Continuing to listen for command response.", unknownCode) return false } - switch response.code { - case .rxTimeout, .zeroData, .invalidParam, .unknownCommand: - log.debug("RileyLink response: %{public}@", String(describing: response)) - capturedResponse = response - return true + switch code { case .commandInterrupted: // This is expected in cases where an "Idle" GetPacket command is running - log.debug("RileyLink response: %{public}@", String(describing: response)) + log.debug("Idle command interrupted. Continuing to listen for command response.") return false - case .success: + default: + guard let response = R(data: value) else { + log.debug("Unable to parse response.") + // We don't recognize the contents. Keep listening. + return false + } + log.debug("RileyLink response: %{public}@", String(describing: response)) capturedResponse = response return true } diff --git a/RileyLinkBLEKit/RadioFirmwareVersion.swift b/RileyLinkBLEKit/RadioFirmwareVersion.swift index 345b7440a..34e959fae 100644 --- a/RileyLinkBLEKit/RadioFirmwareVersion.swift +++ b/RileyLinkBLEKit/RadioFirmwareVersion.swift @@ -50,6 +50,16 @@ extension RadioFirmwareVersion { return true } + private var atLeastV2_2: Bool { + guard components.count >= 2 else { + return false; + } + let major = components[0] + let minor = components[1] + return major > 2 || (major == 2 && minor >= 2) + } + + var supportsPreambleExtension: Bool { return atLeastV2 } @@ -69,6 +79,11 @@ extension RadioFirmwareVersion { var needsExtraByteForUpdateRegisterCommand: Bool { return !atLeastV2 } + + var supportsRileyLinkStatistics: Bool { + return atLeastV2_2 + } + } diff --git a/RileyLinkBLEKit/Response.swift b/RileyLinkBLEKit/Response.swift index 9ec084448..0d576be95 100644 --- a/RileyLinkBLEKit/Response.swift +++ b/RileyLinkBLEKit/Response.swift @@ -103,6 +103,43 @@ struct GetVersionResponse: Response { } } +struct GetStatisticsResponse: Response { + let code: ResponseCode + + let statistics: RileyLinkStatistics + + init?(data: Data) { + guard data.count > 0, let code = ResponseCode(rawValue: data[data.startIndex]) else { + return nil + } + + self.init(code: code, data: data[data.startIndex.advanced(by: 1)...]) + } + + init?(legacyData data: Data) { + self.init(code: .success, data: data) + } + + private init?(code: ResponseCode, data: Data) { + self.code = code + + guard data.count >= 16 else { + return nil + } + + let uptime = TimeInterval(milliseconds: Double(data[data.startIndex...].toBigEndian(UInt32.self))) + let radioRxOverflowCount = data[data.startIndex.advanced(by: 4)...].toBigEndian(UInt16.self) + let radioRxFifoOverflowCount = data[data.startIndex.advanced(by: 6)...].toBigEndian(UInt16.self) + let packetRxCount = data[data.startIndex.advanced(by: 8)...].toBigEndian(UInt16.self) + let packetTxCount = data[data.startIndex.advanced(by: 10)...].toBigEndian(UInt16.self) + let crcFailureCount = data[data.startIndex.advanced(by: 12)...].toBigEndian(UInt16.self) + let spiSyncFailureCount = data[data.startIndex.advanced(by: 14)...].toBigEndian(UInt16.self) + + self.statistics = RileyLinkStatistics(uptime: uptime, radioRxOverflowCount: radioRxOverflowCount, radioRxFifoOverflowCount: radioRxFifoOverflowCount, packetRxCount: packetRxCount, packetTxCount: packetTxCount, crcFailureCount: crcFailureCount, spiSyncFailureCount: spiSyncFailureCount) + } +} + + struct PacketResponse: Response { let code: ResponseCode let packet: RFPacket? diff --git a/RileyLinkKit/PumpMessageSender.swift b/RileyLinkKit/PumpMessageSender.swift index fa33ed9a2..f40df7f7e 100644 --- a/RileyLinkKit/PumpMessageSender.swift +++ b/RileyLinkKit/PumpMessageSender.swift @@ -45,6 +45,9 @@ protocol PumpMessageSender { /// - Throws: LocalizedError func enableCCLEDs() throws + + /// - Throws: LocalizedError + func getRileyLinkStatistics() throws -> RileyLinkStatistics } extension PumpMessageSender { diff --git a/RileyLinkKit/PumpOpsSession.swift b/RileyLinkKit/PumpOpsSession.swift index 5cdec2bf0..d264c3246 100644 --- a/RileyLinkKit/PumpOpsSession.swift +++ b/RileyLinkKit/PumpOpsSession.swift @@ -618,6 +618,10 @@ extension PumpOpsSession { } } } + + public func getStatistics() throws -> RileyLinkStatistics { + return try session.getRileyLinkStatistics() + } public func discoverCommands(in range: CountableClosedRange, _ updateHandler: (_ messages: [String]) -> Void) { diff --git a/RileyLinkKitTests/PumpOpsSynchronousTests.swift b/RileyLinkKitTests/PumpOpsSynchronousTests.swift index 816fc77c7..9b1e91dd7 100644 --- a/RileyLinkKitTests/PumpOpsSynchronousTests.swift +++ b/RileyLinkKitTests/PumpOpsSynchronousTests.swift @@ -320,6 +320,10 @@ func randomDataString(length:Int) -> String { } class PumpMessageSenderStub: PumpMessageSender { + func getRileyLinkStatistics() throws -> RileyLinkStatistics { + throw PumpOpsError.noResponse(during: "Tests") + } + func sendAndListen(_ data: Data, repeatCount: Int, timeout: TimeInterval, retryCount: Int) throws -> RFPacket? { guard let decoded = MinimedPacket(encodedData: data), let messageType = MessageType(rawValue: decoded.data[4]) diff --git a/RileyLinkKitUI/CommandResponseViewController+RileyLinkDevice.swift b/RileyLinkKitUI/CommandResponseViewController+RileyLinkDevice.swift index 8eade33ae..7ff5900d7 100644 --- a/RileyLinkKitUI/CommandResponseViewController+RileyLinkDevice.swift +++ b/RileyLinkKitUI/CommandResponseViewController+RileyLinkDevice.swift @@ -52,6 +52,27 @@ extension CommandResponseViewController { return NSLocalizedString("Discovering commands…", comment: "Progress message for discovering commands.") } } + + static func getStatistics(ops: PumpOps?, device: RileyLinkDevice) -> T { + return T { (completionHandler) -> String in + ops?.runSession(withName: "Get Statistics", using: device) { (session) in + let response: String + do { + let stats = try session.getStatistics() + response = String(describing: stats) + } catch let error { + response = String(describing: error) + } + + DispatchQueue.main.async { + completionHandler(response) + } + } + + return NSLocalizedString("Get Statistics…", comment: "Progress message for getting statistics.") + } + } + static func dumpHistory(ops: PumpOps?, device: RileyLinkDevice) -> T { return T { (completionHandler) -> String in @@ -210,7 +231,7 @@ extension CommandResponseViewController { static func enableLEDs(ops: PumpOps?, device: RileyLinkDevice) -> T { return T { (completionHandler) -> String in device.enableBLELEDs() - ops?.runSession(withName: "Read pump status", using: device) { (session) in + ops?.runSession(withName: "Enable LEDs", using: device) { (session) in let response: String do { try session.enableCCLEDs() diff --git a/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift b/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift index 38d9e90b1..c6a40d357 100644 --- a/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift +++ b/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift @@ -242,6 +242,7 @@ public class RileyLinkDeviceTableViewController: UITableViewController { case readBasalSchedule case enableLED case discoverCommands + case getStatistics } private func cellForRow(_ row: DeviceRow) -> UITableViewCell? { @@ -374,6 +375,10 @@ public class RileyLinkDeviceTableViewController: UITableViewController { case .discoverCommands: cell.textLabel?.text = NSLocalizedString("Discover Commands", comment: "The title of the command to discover commands") + + case .getStatistics: + cell.textLabel?.text = NSLocalizedString("Get Statistics", comment: "The title of the command to get statistics") + } } @@ -452,6 +457,8 @@ public class RileyLinkDeviceTableViewController: UITableViewController { vc = .enableLEDs(ops: ops, device: device) case .discoverCommands: vc = .discoverCommands(ops: ops, device: device) + case .getStatistics: + vc = .getStatistics(ops: ops, device: device) } if let cell = tableView.cellForRow(at: indexPath) { From b8db9103024714910eec348dacb3cf4d6c4460a5 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 4 Jul 2018 23:50:35 -0500 Subject: [PATCH 02/22] Updates for PumpManager (#413) * Updates for PumpManager * Update LoopKit resolved version * Use Xcode 9.4 for Travis build * Fix test frameworks * Re-add rl statistics command --- .gitignore | 1 + .travis.yml | 2 +- Cartfile | 1 + Cartfile.resolved | 1 + .../CaseCountable.swift | 0 Common/HKUnit.swift | 36 + Common/Locked.swift | 40 + .../Extensions => Common}/NibLoadable.swift | 0 Common/TimeZone.swift | 5 + .../Extensions => Common}/UIColor.swift | 0 ...ntryPumpStatusMessageBody+CGMManager.swift | 63 ++ .../SensorValueGlucoseEvent+CGMManager.swift | 26 + .../ChangeMaxBasalRateMessageBody.swift | 4 +- .../Messages/ChangeMaxBolusMessageBody.swift | 17 +- MinimedKit/{ => Messages}/MessageBody.swift | 0 MinimedKit/{ => Messages}/MessageType.swift | 0 MinimedKit/Messages/MeterMessage.swift | 9 +- .../{ => Messages/Models}/BasalSchedule.swift | 0 MinimedKit/{ => Messages/Models}/CRC16.swift | 0 .../Models}/GlucoseEventType.swift | 0 .../{ => Messages/Models}/GlucosePage.swift | 0 .../{ => Messages/Models}/HistoryPage.swift | 0 .../Models/MySentryAlertType.swift} | 4 +- .../{ => Messages/Models}/PartialDecode.swift | 0 .../{ => Messages/Models}/PumpEventType.swift | 0 .../Models}/TimestampedGlucoseEvent.swift | 0 .../Models}/TimestampedHistoryEvent.swift | 0 .../MySentryAlertClearedMessageBody.swift | 4 +- .../Messages/MySentryAlertMessageBody.swift | 4 +- MinimedKit/{ => Messages}/PacketType.swift | 0 MinimedKit/{ => Messages}/PumpMessage.swift | 0 .../{ => Models}/BatteryChemistryType.swift | 0 MinimedKit/Models/PumpColor.swift | 14 + MinimedKit/{ => Models}/PumpModel.swift | 5 + MinimedKit/{ => Models}/PumpRegion.swift | 0 .../PumpManager}/BasalProfile.swift | 2 - .../PumpManager}/CommandSession.swift | 0 MinimedKit/PumpManager/DoseStore.swift | 101 ++ .../PumpManager/EnliteSensorDisplayable.swift | 37 + .../HistoryPage+PumpOpsSession.swift | 4 +- .../PumpManager/InsulinDataSource.swift | 24 + .../PumpManager/MinimedPumpManager.swift | 696 ++++++++++++++ .../PumpManager/MinimedPumpManagerError.swift | 28 + .../PumpManager/MinimedPumpManagerState.swift | 140 +++ .../PumpMessage+PumpOpsSession.swift | 2 - .../PumpManager}/PumpMessageSender.swift | 1 - .../PumpManager}/PumpOps.swift | 2 +- .../PumpManager}/PumpOpsError.swift | 1 - .../PumpManager/PumpOpsSession+LoopKit.swift | 39 + .../PumpManager}/PumpSettings.swift | 2 - .../PumpManager}/PumpState.swift | 1 - MinimedKit/PumpManager/RileyLinkDevice.swift | 25 + MinimedKit/{ => Radio}/CRC8.swift | 0 .../{ => Radio}/FourByteSixByteEncoding.swift | 0 MinimedKit/{ => Radio}/MinimedPacket.swift | 0 .../ChangeMaxBolusMessageBodyTests.swift | 25 +- ...mpOpsSynchronousBuildFromFramesTests.swift | 4 +- .../PumpOpsSynchronousTests.swift | 0 .../Base.lproj/MinimedPumpManager.storyboard | 585 ++++++++++++ .../CommandResponseViewController.swift | 43 +- MinimedKitUI/Info.plist | 24 + MinimedKitUI/MinimedKitUI.h | 19 + .../5xx Blue.imageset/5xx Blue.pdf | Bin 0 -> 4577 bytes .../5xx Blue.imageset/Contents.json | 12 + .../5xx Clear.imageset/5xx Clear.pdf | Bin 0 -> 5266 bytes .../5xx Clear.imageset/Contents.json | 12 + .../5xx Outline.imageset/5xx Outline.pdf | Bin 0 -> 4941 bytes .../5xx Outline.imageset/Contents.json | 16 + .../5xx Purple.imageset/5xx Purple.pdf | Bin 0 -> 4580 bytes .../5xx Purple.imageset/Contents.json | 12 + .../5xx Small Blue.pdf | Bin 0 -> 4513 bytes .../5xx Small Blue.imageset/Contents.json | 12 + .../5xx Small Clear.pdf | Bin 0 -> 5177 bytes .../5xx Small Clear.imageset/Contents.json | 12 + .../5xx Small Outline.pdf | Bin 0 -> 4808 bytes .../5xx Small Outline.imageset/Contents.json | 16 + .../5xx Small Purple.pdf | Bin 0 -> 4511 bytes .../5xx Small Purple.imageset/Contents.json | 12 + .../5xx Small Smoke.pdf | Bin 0 -> 4514 bytes .../5xx Small Smoke.imageset/Contents.json | 12 + .../5xx Smoke.imageset/5xx Smoke.pdf | Bin 0 -> 4578 bytes .../5xx Smoke.imageset/Contents.json | 12 + .../7xx Blue.imageset/7xx Blue.pdf | Bin 0 -> 4559 bytes .../7xx Blue.imageset/Contents.json | 12 + .../7xx Clear.imageset/7xx Clear.pdf | Bin 0 -> 5167 bytes .../7xx Clear.imageset/Contents.json | 12 + .../7xx Outline.imageset/7xx Outline.pdf | Bin 0 -> 4920 bytes .../7xx Outline.imageset/Contents.json | 16 + .../7xx Purple.imageset/7xx Purple.pdf | Bin 0 -> 4555 bytes .../7xx Purple.imageset/Contents.json | 12 + .../7xx Small Blue.pdf | Bin 0 -> 4496 bytes .../7xx Small Blue.imageset/Contents.json | 12 + .../7xx Small Clear.pdf | Bin 0 -> 5090 bytes .../7xx Small Clear.imageset/Contents.json | 12 + .../7xx Small Outline.pdf | Bin 0 -> 4788 bytes .../7xx Small Outline.imageset/Contents.json | 16 + .../7xx Small Purple.pdf | Bin 0 -> 4494 bytes .../7xx Small Purple.imageset/Contents.json | 12 + .../7xx Small Smoke.pdf | Bin 0 -> 4495 bytes .../7xx Small Smoke.imageset/Contents.json | 12 + .../7xx Smoke.imageset/7xx Smoke.pdf | Bin 0 -> 4551 bytes .../7xx Smoke.imageset/Contents.json | 12 + .../MinimedKitUI.xcassets/Contents.json | 6 + .../Pump ID Diagram.imageset/Contents.json | 12 + .../Pump ID Diagram.pdf | Bin 0 -> 36344 bytes .../Contents.json | 20 + .../Pump Screen Text.colorset/Contents.json | 20 + MinimedKitUI/MinimedPumpManager+UI.swift | 102 +++ .../MinimedPumpSettingsViewController.swift | 281 ++++++ MinimedKitUI/PumpModel.swift | 62 ++ .../PumpOps.swift | 2 +- .../RadioSelectionTableViewController.swift | 37 + ...LinkMinimedDeviceTableViewController.swift | 536 +++++++++++ .../MinimedPumpClockSetupViewController.swift | 17 + .../MinimedPumpIDSetupViewController.swift | 439 +++++++++ ...inimedPumpManagerSetupViewController.swift | 115 +++ ...MinimedPumpSentrySetupViewController.swift | 175 ++++ ...nimedPumpSettingsSetupViewController.swift | 177 ++++ ...nimedPumpSetupCompleteViewController.swift | 37 + RileyLink.xcodeproj/project.pbxproj | 859 +++++++++++++++--- .../xcschemes/MinimedKitUI.xcscheme | 80 ++ RileyLink/DeviceDataManager.swift | 3 +- RileyLink/Extensions/UserDefaults.swift | 2 +- .../RileyLinkListTableViewController.swift | 3 +- .../SettingsTableViewController.swift | 1 + RileyLinkKit/PumpOpsSession.swift | 18 +- .../{Extensions => }/RileyLinkDevice.swift | 11 +- RileyLinkKit/RileyLinkDeviceManager.swift | 16 + RileyLinkKit/RileyLinkPumpManager.swift | 127 +++ RileyLinkKit/RileyLinkPumpManagerState.swift | 44 + RileyLinkKitUI/CBPeripheralState.swift | 2 +- RileyLinkKitUI/RileyLinkDevice.swift | 18 - .../RileyLinkDeviceTableViewController.swift | 199 +--- .../RileyLinkDevicesHeaderView.swift | 37 + .../RileyLinkDevicesTableViewDataSource.swift | 209 +++++ .../RileyLinkKitUI.xcassets/Contents.json | 6 + .../RileyLink Tint.colorset/Contents.json | 20 + .../RileyLink.imageset/Contents.json | 15 + .../RileyLink.imageset/RileyLink.pdf | Bin 0 -> 36519 bytes .../RileyLinkManagerSetupViewController.swift | 40 + .../RileyLinkSettingsViewController.swift | 64 ++ .../RileyLinkSetupTableViewController.swift | 150 +++ RileyLinkKitUI/SetupImageTableViewCell.swift | 14 + RileyLinkKitUI/SetupImageTableViewCell.xib | 39 + RileyLinkKitUI/TextFieldTableViewCell.swift | 24 - RileyLinkKitUI/TextFieldTableViewCell.xib | 40 - .../TextFieldTableViewController.swift | 101 -- 147 files changed, 5930 insertions(+), 547 deletions(-) create mode 100644 Cartfile create mode 100644 Cartfile.resolved rename {RileyLinkKitUI => Common}/CaseCountable.swift (100%) create mode 100644 Common/HKUnit.swift create mode 100644 Common/Locked.swift rename {RileyLink/Extensions => Common}/NibLoadable.swift (100%) rename {RileyLink/Extensions => Common}/UIColor.swift (100%) create mode 100644 MinimedKit/CGMManager/MySentryPumpStatusMessageBody+CGMManager.swift create mode 100644 MinimedKit/CGMManager/SensorValueGlucoseEvent+CGMManager.swift rename MinimedKit/{ => Messages}/MessageBody.swift (100%) rename MinimedKit/{ => Messages}/MessageType.swift (100%) rename MinimedKit/{ => Messages/Models}/BasalSchedule.swift (100%) rename MinimedKit/{ => Messages/Models}/CRC16.swift (100%) rename MinimedKit/{ => Messages/Models}/GlucoseEventType.swift (100%) rename MinimedKit/{ => Messages/Models}/GlucosePage.swift (100%) rename MinimedKit/{ => Messages/Models}/HistoryPage.swift (100%) rename MinimedKit/{AlertType.swift => Messages/Models/MySentryAlertType.swift} (89%) rename MinimedKit/{ => Messages/Models}/PartialDecode.swift (100%) rename MinimedKit/{ => Messages/Models}/PumpEventType.swift (100%) rename MinimedKit/{ => Messages/Models}/TimestampedGlucoseEvent.swift (100%) rename MinimedKit/{ => Messages/Models}/TimestampedHistoryEvent.swift (100%) rename MinimedKit/{ => Messages}/PacketType.swift (100%) rename MinimedKit/{ => Messages}/PumpMessage.swift (100%) rename MinimedKit/{ => Models}/BatteryChemistryType.swift (100%) create mode 100644 MinimedKit/Models/PumpColor.swift rename MinimedKit/{ => Models}/PumpModel.swift (93%) rename MinimedKit/{ => Models}/PumpRegion.swift (100%) rename {RileyLinkKit/Extensions => MinimedKit/PumpManager}/BasalProfile.swift (95%) rename {RileyLinkKit/Extensions => MinimedKit/PumpManager}/CommandSession.swift (100%) create mode 100644 MinimedKit/PumpManager/DoseStore.swift create mode 100644 MinimedKit/PumpManager/EnliteSensorDisplayable.swift rename RileyLinkKit/Extensions/HistoryPage.swift => MinimedKit/PumpManager/HistoryPage+PumpOpsSession.swift (98%) create mode 100644 MinimedKit/PumpManager/InsulinDataSource.swift create mode 100644 MinimedKit/PumpManager/MinimedPumpManager.swift create mode 100644 MinimedKit/PumpManager/MinimedPumpManagerError.swift create mode 100644 MinimedKit/PumpManager/MinimedPumpManagerState.swift rename RileyLinkKit/Extensions/PumpMessage.swift => MinimedKit/PumpManager/PumpMessage+PumpOpsSession.swift (97%) rename {RileyLinkKit => MinimedKit/PumpManager}/PumpMessageSender.swift (99%) rename {RileyLinkKit => MinimedKit/PumpManager}/PumpOps.swift (99%) rename {RileyLinkKit => MinimedKit/PumpManager}/PumpOpsError.swift (99%) create mode 100644 MinimedKit/PumpManager/PumpOpsSession+LoopKit.swift rename {RileyLinkKit => MinimedKit/PumpManager}/PumpSettings.swift (98%) rename {RileyLinkKit => MinimedKit/PumpManager}/PumpState.swift (98%) create mode 100644 MinimedKit/PumpManager/RileyLinkDevice.swift rename MinimedKit/{ => Radio}/CRC8.swift (100%) rename MinimedKit/{ => Radio}/FourByteSixByteEncoding.swift (100%) rename MinimedKit/{ => Radio}/MinimedPacket.swift (100%) rename {RileyLinkKitTests => MinimedKitTests}/PumpOpsSynchronousBuildFromFramesTests.swift (99%) rename {RileyLinkKitTests => MinimedKitTests}/PumpOpsSynchronousTests.swift (100%) create mode 100644 MinimedKitUI/Base.lproj/MinimedPumpManager.storyboard rename RileyLinkKitUI/CommandResponseViewController+RileyLinkDevice.swift => MinimedKitUI/CommandResponseViewController.swift (92%) create mode 100644 MinimedKitUI/Info.plist create mode 100644 MinimedKitUI/MinimedKitUI.h create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/5xx Blue.imageset/5xx Blue.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/5xx Blue.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/5xx Clear.imageset/5xx Clear.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/5xx Clear.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/5xx Outline.imageset/5xx Outline.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/5xx Outline.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/5xx Purple.imageset/5xx Purple.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/5xx Purple.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/5xx Small Blue.imageset/5xx Small Blue.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/5xx Small Blue.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/5xx Small Clear.imageset/5xx Small Clear.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/5xx Small Clear.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/5xx Small Outline.imageset/5xx Small Outline.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/5xx Small Outline.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/5xx Small Purple.imageset/5xx Small Purple.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/5xx Small Purple.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/5xx Small Smoke.imageset/5xx Small Smoke.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/5xx Small Smoke.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/5xx Smoke.imageset/5xx Smoke.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/5xx Smoke.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/7xx Blue.imageset/7xx Blue.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/7xx Blue.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/7xx Clear.imageset/7xx Clear.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/7xx Clear.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/7xx Outline.imageset/7xx Outline.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/7xx Outline.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/7xx Purple.imageset/7xx Purple.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/7xx Purple.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/7xx Small Blue.imageset/7xx Small Blue.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/7xx Small Blue.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/7xx Small Clear.imageset/7xx Small Clear.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/7xx Small Clear.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/7xx Small Outline.imageset/7xx Small Outline.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/7xx Small Outline.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/7xx Small Purple.imageset/7xx Small Purple.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/7xx Small Purple.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/7xx Small Smoke.imageset/7xx Small Smoke.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/7xx Small Smoke.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/7xx Smoke.imageset/7xx Smoke.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/7xx Smoke.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/Pump ID Diagram.imageset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/Pump ID Diagram.imageset/Pump ID Diagram.pdf create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/Pump Screen Background.colorset/Contents.json create mode 100644 MinimedKitUI/MinimedKitUI.xcassets/Pump Screen Text.colorset/Contents.json create mode 100644 MinimedKitUI/MinimedPumpManager+UI.swift create mode 100644 MinimedKitUI/MinimedPumpSettingsViewController.swift create mode 100644 MinimedKitUI/PumpModel.swift rename {RileyLinkKitUI => MinimedKitUI}/PumpOps.swift (96%) create mode 100644 MinimedKitUI/RadioSelectionTableViewController.swift create mode 100644 MinimedKitUI/RileyLinkMinimedDeviceTableViewController.swift create mode 100644 MinimedKitUI/Setup/MinimedPumpClockSetupViewController.swift create mode 100644 MinimedKitUI/Setup/MinimedPumpIDSetupViewController.swift create mode 100644 MinimedKitUI/Setup/MinimedPumpManagerSetupViewController.swift create mode 100644 MinimedKitUI/Setup/MinimedPumpSentrySetupViewController.swift create mode 100644 MinimedKitUI/Setup/MinimedPumpSettingsSetupViewController.swift create mode 100644 MinimedKitUI/Setup/MinimedPumpSetupCompleteViewController.swift create mode 100644 RileyLink.xcodeproj/xcshareddata/xcschemes/MinimedKitUI.xcscheme rename RileyLinkKit/{Extensions => }/RileyLinkDevice.swift (54%) create mode 100644 RileyLinkKit/RileyLinkDeviceManager.swift create mode 100644 RileyLinkKit/RileyLinkPumpManager.swift create mode 100644 RileyLinkKit/RileyLinkPumpManagerState.swift delete mode 100644 RileyLinkKitUI/RileyLinkDevice.swift create mode 100644 RileyLinkKitUI/RileyLinkDevicesHeaderView.swift create mode 100644 RileyLinkKitUI/RileyLinkDevicesTableViewDataSource.swift create mode 100644 RileyLinkKitUI/RileyLinkKitUI.xcassets/Contents.json create mode 100644 RileyLinkKitUI/RileyLinkKitUI.xcassets/RileyLink Tint.colorset/Contents.json create mode 100644 RileyLinkKitUI/RileyLinkKitUI.xcassets/RileyLink.imageset/Contents.json create mode 100644 RileyLinkKitUI/RileyLinkKitUI.xcassets/RileyLink.imageset/RileyLink.pdf create mode 100644 RileyLinkKitUI/RileyLinkManagerSetupViewController.swift create mode 100644 RileyLinkKitUI/RileyLinkSettingsViewController.swift create mode 100644 RileyLinkKitUI/RileyLinkSetupTableViewController.swift create mode 100644 RileyLinkKitUI/SetupImageTableViewCell.swift create mode 100644 RileyLinkKitUI/SetupImageTableViewCell.xib delete mode 100644 RileyLinkKitUI/TextFieldTableViewCell.swift delete mode 100644 RileyLinkKitUI/TextFieldTableViewCell.xib delete mode 100644 RileyLinkKitUI/TextFieldTableViewController.swift diff --git a/.gitignore b/.gitignore index bedeedee5..a144810b8 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,4 @@ project.xcworkspace # Pods/ Carthage/ +.gitmodules diff --git a/.travis.yml b/.travis.yml index 4fbfbf211..a4d2de34e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: objective-c -osx_image: xcode9.3 +osx_image: xcode9.4 xcode_project: RileyLink.xcodeproj xcode_scheme: RileyLink script: diff --git a/Cartfile b/Cartfile new file mode 100644 index 000000000..52d9d4af0 --- /dev/null +++ b/Cartfile @@ -0,0 +1 @@ +github "LoopKit/LoopKit" "pump-manager" diff --git a/Cartfile.resolved b/Cartfile.resolved new file mode 100644 index 000000000..756402713 --- /dev/null +++ b/Cartfile.resolved @@ -0,0 +1 @@ +github "LoopKit/LoopKit" "8afd78fac3cc20d2b99a022c01ce4f8f2853cb53" diff --git a/RileyLinkKitUI/CaseCountable.swift b/Common/CaseCountable.swift similarity index 100% rename from RileyLinkKitUI/CaseCountable.swift rename to Common/CaseCountable.swift diff --git a/Common/HKUnit.swift b/Common/HKUnit.swift new file mode 100644 index 000000000..75fb23a7e --- /dev/null +++ b/Common/HKUnit.swift @@ -0,0 +1,36 @@ +// +// HKUnit.swift +// Naterade +// +// Created by Nathan Racklyeft on 1/17/16. +// Copyright © 2016 Nathan Racklyeft. All rights reserved. +// + +import HealthKit + + +extension HKUnit { + static let milligramsPerDeciliter: HKUnit = { + return HKUnit.gramUnit(with: .milli).unitDivided(by: .literUnit(with: .deci)) + }() + + static let millimolesPerLiter: HKUnit = { + return HKUnit.moleUnit(with: .milli, molarMass: HKUnitMolarMassBloodGlucose).unitDivided(by: .liter()) + }() + + var foundationUnit: Unit? { + if self == HKUnit.milligramsPerDeciliter { + return UnitConcentrationMass.milligramsPerDeciliter + } + + if self == HKUnit.millimolesPerLiter { + return UnitConcentrationMass.millimolesPerLiter(withGramsPerMole: HKUnitMolarMassBloodGlucose) + } + + if self == HKUnit.gram() { + return UnitMass.grams + } + + return nil + } +} diff --git a/Common/Locked.swift b/Common/Locked.swift new file mode 100644 index 000000000..fd6e35b10 --- /dev/null +++ b/Common/Locked.swift @@ -0,0 +1,40 @@ +// +// Locked.swift +// LoopKit +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + +import os.lock + + +internal class Locked { + private var lock = os_unfair_lock() + private var _value: T + + init(_ value: T) { + os_unfair_lock_lock(&lock) + defer { os_unfair_lock_unlock(&lock) } + _value = value + } + + var value: T { + get { + os_unfair_lock_lock(&lock) + defer { os_unfair_lock_unlock(&lock) } + return _value + } + set { + os_unfair_lock_lock(&lock) + defer { os_unfair_lock_unlock(&lock) } + _value = newValue + } + } + + func mutate(_ changes: (_ value: inout T) -> Void) -> T { + os_unfair_lock_lock(&lock) + defer { os_unfair_lock_unlock(&lock) } + changes(&_value) + return _value + } +} diff --git a/RileyLink/Extensions/NibLoadable.swift b/Common/NibLoadable.swift similarity index 100% rename from RileyLink/Extensions/NibLoadable.swift rename to Common/NibLoadable.swift diff --git a/Common/TimeZone.swift b/Common/TimeZone.swift index 2287c377f..cfe2f4337 100644 --- a/Common/TimeZone.swift +++ b/Common/TimeZone.swift @@ -6,9 +6,14 @@ // Copyright © 2016 Pete Schwamb. All rights reserved. // +import Foundation extension TimeZone { static var currentFixed: TimeZone { return TimeZone(secondsFromGMT: TimeZone.current.secondsFromGMT())! } + + var fixed: TimeZone { + return TimeZone(secondsFromGMT: secondsFromGMT())! + } } diff --git a/RileyLink/Extensions/UIColor.swift b/Common/UIColor.swift similarity index 100% rename from RileyLink/Extensions/UIColor.swift rename to Common/UIColor.swift diff --git a/MinimedKit/CGMManager/MySentryPumpStatusMessageBody+CGMManager.swift b/MinimedKit/CGMManager/MySentryPumpStatusMessageBody+CGMManager.swift new file mode 100644 index 000000000..45b520aa6 --- /dev/null +++ b/MinimedKit/CGMManager/MySentryPumpStatusMessageBody+CGMManager.swift @@ -0,0 +1,63 @@ +// +// MySentryPumpStatusMessageBody.swift +// Loop +// +// Created by Nate Racklyeft on 7/28/16. +// Copyright © 2016 Nathan Racklyeft. All rights reserved. +// + +import LoopKit + + +extension MySentryPumpStatusMessageBody: SensorDisplayable { + public var isStateValid: Bool { + switch glucose { + case .active: + return true + default: + return false + } + } + + public var trendType: LoopKit.GlucoseTrend? { + guard case .active = glucose else { + return nil + } + + switch glucoseTrend { + case .down: + return .down + case .downDown: + return .downDown + case .up: + return .up + case .upUp: + return .upUp + case .flat: + return .flat + } + } + + public var isLocal: Bool { + return true + } + + var batteryPercentage: Int { + return batteryRemainingPercent + } + + var glucoseSyncIdentifier: String? { + guard let date = glucoseDateComponents, + let year = date.year, + let month = date.month, + let day = date.day, + let hour = date.hour, + let minute = date.minute, + let second = date.second + else { + return nil + } + + return "\(year)-\(month)-\(day) \(hour)-\(minute)-\(second)" + } +} diff --git a/MinimedKit/CGMManager/SensorValueGlucoseEvent+CGMManager.swift b/MinimedKit/CGMManager/SensorValueGlucoseEvent+CGMManager.swift new file mode 100644 index 000000000..ab76e32b6 --- /dev/null +++ b/MinimedKit/CGMManager/SensorValueGlucoseEvent+CGMManager.swift @@ -0,0 +1,26 @@ +// +// SensorValueGlucoseEvent.swift +// Loop +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + + +extension SensorValueGlucoseEvent { + var glucoseSyncIdentifier: String? { + let date = timestamp + + guard + let year = date.year, + let month = date.month, + let day = date.day, + let hour = date.hour, + let minute = date.minute, + let second = date.second + else { + return nil + } + + return "\(year)-\(month)-\(day) \(hour)-\(minute)-\(second)" + } +} diff --git a/MinimedKit/Messages/ChangeMaxBasalRateMessageBody.swift b/MinimedKit/Messages/ChangeMaxBasalRateMessageBody.swift index 108b074d1..46aa8d4f2 100644 --- a/MinimedKit/Messages/ChangeMaxBasalRateMessageBody.swift +++ b/MinimedKit/Messages/ChangeMaxBasalRateMessageBody.swift @@ -18,7 +18,9 @@ public class ChangeMaxBasalRateMessageBody: CarelinkLongMessageBody { } let ticks = UInt16(maxBasalUnitsPerHour * type(of: self).multiplier) - var data = Data(bytes: [UInt8(clamping: ticks.bitWidth / 8)]) + let length = UInt8(clamping: ticks.bitWidth / 8) + var data = Data(bytes: [length]) + data.appendBigEndian(ticks) self.init(rxData: data) diff --git a/MinimedKit/Messages/ChangeMaxBolusMessageBody.swift b/MinimedKit/Messages/ChangeMaxBolusMessageBody.swift index ebb0ae4ce..6d9c9a58b 100644 --- a/MinimedKit/Messages/ChangeMaxBolusMessageBody.swift +++ b/MinimedKit/Messages/ChangeMaxBolusMessageBody.swift @@ -12,14 +12,23 @@ public class ChangeMaxBolusMessageBody: CarelinkLongMessageBody { static let multiplier: Double = 10 - public convenience init?(maxBolusUnits: Double) { + public convenience init?(pumpModel: PumpModel, maxBolusUnits: Double) { guard maxBolusUnits >= 0 && maxBolusUnits <= 25 else { return nil } - let ticks = UInt8(maxBolusUnits * type(of: self).multiplier) - var data = Data(bytes: [UInt8(clamping: ticks.bitWidth / 8)]) - data.appendBigEndian(ticks) + var data = Data() + + if pumpModel.usesTwoBytesForMaxBolus { + let ticks = UInt16(maxBolusUnits * type(of: self).multiplier) + data.appendBigEndian(ticks) + } else { + let ticks = UInt8(maxBolusUnits * type(of: self).multiplier) + data.appendBigEndian(ticks) + } + + let length = UInt8(clamping: data.count) + data.insert(length, at: 0) self.init(rxData: data) } diff --git a/MinimedKit/MessageBody.swift b/MinimedKit/Messages/MessageBody.swift similarity index 100% rename from MinimedKit/MessageBody.swift rename to MinimedKit/Messages/MessageBody.swift diff --git a/MinimedKit/MessageType.swift b/MinimedKit/Messages/MessageType.swift similarity index 100% rename from MinimedKit/MessageType.swift rename to MinimedKit/Messages/MessageType.swift diff --git a/MinimedKit/Messages/MeterMessage.swift b/MinimedKit/Messages/MeterMessage.swift index 8779bf573..41301293a 100644 --- a/MinimedKit/Messages/MeterMessage.swift +++ b/MinimedKit/Messages/MeterMessage.swift @@ -6,20 +6,19 @@ // Copyright © 2016 Pete Schwamb. All rights reserved. // -import Foundation -public class MeterMessage { +public struct MeterMessage: MessageBody, DictionaryRepresentable { - let length = 7 + public static let length = 7 public let glucose: Int public let ackFlag: Bool let rxData: Data - public required init?(rxData: Data) { + public init?(rxData: Data) { self.rxData = rxData - if rxData.count == length, + if rxData.count == type(of: self).length, let packetType = PacketType(rawValue: rxData[0]), packetType == .meter { let flags = ((rxData[4]) & 0b110) >> 1 diff --git a/MinimedKit/BasalSchedule.swift b/MinimedKit/Messages/Models/BasalSchedule.swift similarity index 100% rename from MinimedKit/BasalSchedule.swift rename to MinimedKit/Messages/Models/BasalSchedule.swift diff --git a/MinimedKit/CRC16.swift b/MinimedKit/Messages/Models/CRC16.swift similarity index 100% rename from MinimedKit/CRC16.swift rename to MinimedKit/Messages/Models/CRC16.swift diff --git a/MinimedKit/GlucoseEventType.swift b/MinimedKit/Messages/Models/GlucoseEventType.swift similarity index 100% rename from MinimedKit/GlucoseEventType.swift rename to MinimedKit/Messages/Models/GlucoseEventType.swift diff --git a/MinimedKit/GlucosePage.swift b/MinimedKit/Messages/Models/GlucosePage.swift similarity index 100% rename from MinimedKit/GlucosePage.swift rename to MinimedKit/Messages/Models/GlucosePage.swift diff --git a/MinimedKit/HistoryPage.swift b/MinimedKit/Messages/Models/HistoryPage.swift similarity index 100% rename from MinimedKit/HistoryPage.swift rename to MinimedKit/Messages/Models/HistoryPage.swift diff --git a/MinimedKit/AlertType.swift b/MinimedKit/Messages/Models/MySentryAlertType.swift similarity index 89% rename from MinimedKit/AlertType.swift rename to MinimedKit/Messages/Models/MySentryAlertType.swift index 938e6baca..391946cee 100644 --- a/MinimedKit/AlertType.swift +++ b/MinimedKit/Messages/Models/MySentryAlertType.swift @@ -1,12 +1,12 @@ // -// AlertType.swift +// MySentryAlertType.swift // Naterade // // Created by Nathan Racklyeft on 9/13/15. // Copyright © 2015 Nathan Racklyeft. All rights reserved. // -public enum AlertType: UInt8 { +public enum MySentryAlertType: UInt8 { case noDelivery = 0x04 case maxHourlyBolus = 0x33 case lowReservoir = 0x52 diff --git a/MinimedKit/PartialDecode.swift b/MinimedKit/Messages/Models/PartialDecode.swift similarity index 100% rename from MinimedKit/PartialDecode.swift rename to MinimedKit/Messages/Models/PartialDecode.swift diff --git a/MinimedKit/PumpEventType.swift b/MinimedKit/Messages/Models/PumpEventType.swift similarity index 100% rename from MinimedKit/PumpEventType.swift rename to MinimedKit/Messages/Models/PumpEventType.swift diff --git a/MinimedKit/TimestampedGlucoseEvent.swift b/MinimedKit/Messages/Models/TimestampedGlucoseEvent.swift similarity index 100% rename from MinimedKit/TimestampedGlucoseEvent.swift rename to MinimedKit/Messages/Models/TimestampedGlucoseEvent.swift diff --git a/MinimedKit/TimestampedHistoryEvent.swift b/MinimedKit/Messages/Models/TimestampedHistoryEvent.swift similarity index 100% rename from MinimedKit/TimestampedHistoryEvent.swift rename to MinimedKit/Messages/Models/TimestampedHistoryEvent.swift diff --git a/MinimedKit/Messages/MySentryAlertClearedMessageBody.swift b/MinimedKit/Messages/MySentryAlertClearedMessageBody.swift index 74dd50c75..7c7912fd2 100644 --- a/MinimedKit/Messages/MySentryAlertClearedMessageBody.swift +++ b/MinimedKit/Messages/MySentryAlertClearedMessageBody.swift @@ -21,7 +21,7 @@ a2 594040 02 80 52 14 public struct MySentryAlertClearedMessageBody: MessageBody, DictionaryRepresentable { public static let length = 2 - public let alertType: AlertType? + public let alertType: MySentryAlertType? private let rxData: Data @@ -32,7 +32,7 @@ public struct MySentryAlertClearedMessageBody: MessageBody, DictionaryRepresenta self.rxData = rxData - alertType = AlertType(rawValue: rxData[1]) + alertType = MySentryAlertType(rawValue: rxData[1]) } public var txData: Data { diff --git a/MinimedKit/Messages/MySentryAlertMessageBody.swift b/MinimedKit/Messages/MySentryAlertMessageBody.swift index e39386749..c19d98a74 100644 --- a/MinimedKit/Messages/MySentryAlertMessageBody.swift +++ b/MinimedKit/Messages/MySentryAlertMessageBody.swift @@ -21,7 +21,7 @@ a2 594040 01 7c 65 0727070f0906 0175 4c public struct MySentryAlertMessageBody: MessageBody, DictionaryRepresentable { public static let length = 10 - public let alertType: AlertType? + public let alertType: MySentryAlertType? public let alertDate: Date private let rxData: Data @@ -35,7 +35,7 @@ public struct MySentryAlertMessageBody: MessageBody, DictionaryRepresentable { self.rxData = rxData - alertType = AlertType(rawValue: rxData[1]) + alertType = MySentryAlertType(rawValue: rxData[1]) self.alertDate = alertDate } diff --git a/MinimedKit/PacketType.swift b/MinimedKit/Messages/PacketType.swift similarity index 100% rename from MinimedKit/PacketType.swift rename to MinimedKit/Messages/PacketType.swift diff --git a/MinimedKit/PumpMessage.swift b/MinimedKit/Messages/PumpMessage.swift similarity index 100% rename from MinimedKit/PumpMessage.swift rename to MinimedKit/Messages/PumpMessage.swift diff --git a/MinimedKit/BatteryChemistryType.swift b/MinimedKit/Models/BatteryChemistryType.swift similarity index 100% rename from MinimedKit/BatteryChemistryType.swift rename to MinimedKit/Models/BatteryChemistryType.swift diff --git a/MinimedKit/Models/PumpColor.swift b/MinimedKit/Models/PumpColor.swift new file mode 100644 index 000000000..54ba9d705 --- /dev/null +++ b/MinimedKit/Models/PumpColor.swift @@ -0,0 +1,14 @@ +// +// PumpColor.swift +// Loop +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + + +public enum PumpColor: String { + case blue = "B" + case clear = "L" + case purple = "P" + case smoke = "S" +} diff --git a/MinimedKit/PumpModel.swift b/MinimedKit/Models/PumpModel.swift similarity index 93% rename from MinimedKit/PumpModel.swift rename to MinimedKit/Models/PumpModel.swift index f50b9f0d1..810d44d3e 100644 --- a/MinimedKit/PumpModel.swift +++ b/MinimedKit/Models/PumpModel.swift @@ -82,6 +82,11 @@ public enum PumpModel: String { fatalError("Unknown reservoir capacity for PumpModel.\(self)") } } + + /// Even though this is capped by the system at 250 / 10 U, the message takes a UInt16. + var usesTwoBytesForMaxBolus: Bool { + return generation >= 23 + } } diff --git a/MinimedKit/PumpRegion.swift b/MinimedKit/Models/PumpRegion.swift similarity index 100% rename from MinimedKit/PumpRegion.swift rename to MinimedKit/Models/PumpRegion.swift diff --git a/RileyLinkKit/Extensions/BasalProfile.swift b/MinimedKit/PumpManager/BasalProfile.swift similarity index 95% rename from RileyLinkKit/Extensions/BasalProfile.swift rename to MinimedKit/PumpManager/BasalProfile.swift index 0f3df9380..c49212980 100644 --- a/RileyLinkKit/Extensions/BasalProfile.swift +++ b/MinimedKit/PumpManager/BasalProfile.swift @@ -5,8 +5,6 @@ // Copyright © 2017 Pete Schwamb. All rights reserved. // -import MinimedKit - extension BasalProfile { var readMessageType: MessageType { diff --git a/RileyLinkKit/Extensions/CommandSession.swift b/MinimedKit/PumpManager/CommandSession.swift similarity index 100% rename from RileyLinkKit/Extensions/CommandSession.swift rename to MinimedKit/PumpManager/CommandSession.swift diff --git a/MinimedKit/PumpManager/DoseStore.swift b/MinimedKit/PumpManager/DoseStore.swift new file mode 100644 index 000000000..f94caa8b2 --- /dev/null +++ b/MinimedKit/PumpManager/DoseStore.swift @@ -0,0 +1,101 @@ +// +// DoseStore.swift +// Loop +// +// Created by Nate Racklyeft on 7/31/16. +// Copyright © 2016 Nathan Racklyeft. All rights reserved. +// + +import LoopKit + + +// Bridges support for MinimedKit data types +extension Collection where Element == TimestampedHistoryEvent { + func pumpEvents(from model: PumpModel) -> [NewPumpEvent] { + var events: [NewPumpEvent] = [] + var lastTempBasalAmount: DoseEntry? + // Always assume the sequence may have started rewound. LoopKit will ignore unmatched resume events. + var isRewound = true + var title: String + + for event in self { + var dose: DoseEntry? + var eventType: LoopKit.PumpEventType? + + switch event.pumpEvent { + case let bolus as BolusNormalPumpEvent: + // For entries in-progress, use the programmed amount + let units = event.isMutable() ? bolus.programmed : bolus.amount + + dose = DoseEntry(type: .bolus, startDate: event.date, endDate: event.date.addingTimeInterval(bolus.duration), value: units, unit: .units) + case is SuspendPumpEvent: + dose = DoseEntry(suspendDate: event.date) + case is ResumePumpEvent: + dose = DoseEntry(resumeDate: event.date) + case let temp as TempBasalPumpEvent: + if case .Absolute = temp.rateType { + lastTempBasalAmount = DoseEntry(type: .tempBasal, startDate: event.date, value: temp.rate, unit: .unitsPerHour) + } + case let temp as TempBasalDurationPumpEvent: + if let amount = lastTempBasalAmount, amount.startDate == event.date { + dose = DoseEntry( + type: .tempBasal, + startDate: event.date, + endDate: event.date.addingTimeInterval(TimeInterval(minutes: Double(temp.duration))), + value: amount.unitsPerHour, + unit: .unitsPerHour + ) + } + case let basal as BasalProfileStartPumpEvent: + dose = DoseEntry( + type: .basal, + startDate: event.date, + // Use the maximum-possible duration for a basal entry; its true duration will be reconciled against other entries. + endDate: event.date.addingTimeInterval(.hours(24)), + value: basal.scheduleEntry.rate, + unit: .unitsPerHour + ) + case is RewindPumpEvent: + eventType = .rewind + + /* + No insulin is delivered between the beginning of a rewind until the suggested fixed prime is delivered or cancelled. + + If the fixed prime is cancelled, it is never recorded in history. It is possible to cancel a fixed prime and perform one manually some time later, but basal delivery will have resumed during that period. + + We take the conservative approach and assume delivery is paused only between the Rewind and the first Prime event. + */ + dose = DoseEntry(suspendDate: event.date) + isRewound = true + case is PrimePumpEvent: + eventType = .prime + + if isRewound { + isRewound = false + dose = DoseEntry(resumeDate: event.date) + } + case let alarm as PumpAlarmPumpEvent: + eventType = .alarm + + if case .noDelivery = alarm.alarmType { + dose = DoseEntry(suspendDate: event.date) + } + break + case let alarm as ClearAlarmPumpEvent: + eventType = .alarmClear + + if case .noDelivery = alarm.alarmType { + dose = DoseEntry(resumeDate: event.date) + } + break + default: + break + } + + title = String(describing: event.pumpEvent) + events.append(NewPumpEvent(date: event.date, dose: dose, isMutable: event.isMutable(), raw: event.pumpEvent.rawData, title: title, type: eventType)) + } + + return events + } +} diff --git a/MinimedKit/PumpManager/EnliteSensorDisplayable.swift b/MinimedKit/PumpManager/EnliteSensorDisplayable.swift new file mode 100644 index 000000000..25cbc6444 --- /dev/null +++ b/MinimedKit/PumpManager/EnliteSensorDisplayable.swift @@ -0,0 +1,37 @@ +// +// EnliteSensorDisplayable.swift +// Loop +// +// Created by Timothy Mecklem on 12/28/16. +// Copyright © 2016 LoopKit Authors. All rights reserved. +// + +import Foundation +import LoopKit + + +struct EnliteSensorDisplayable: SensorDisplayable { + public let isStateValid: Bool + public let trendType: LoopKit.GlucoseTrend? + public let isLocal: Bool + + public init?(_ event: MinimedKit.RelativeTimestampedGlucoseEvent) { + isStateValid = event.isStateValid + trendType = event.trendType + isLocal = event.isLocal + } +} + +extension MinimedKit.RelativeTimestampedGlucoseEvent { + var isStateValid: Bool { + return self is SensorValueGlucoseEvent + } + + var trendType: LoopKit.GlucoseTrend? { + return nil + } + + var isLocal: Bool { + return true + } +} diff --git a/RileyLinkKit/Extensions/HistoryPage.swift b/MinimedKit/PumpManager/HistoryPage+PumpOpsSession.swift similarity index 98% rename from RileyLinkKit/Extensions/HistoryPage.swift rename to MinimedKit/PumpManager/HistoryPage+PumpOpsSession.swift index e913e05d5..89c192a43 100644 --- a/RileyLinkKit/Extensions/HistoryPage.swift +++ b/MinimedKit/PumpManager/HistoryPage+PumpOpsSession.swift @@ -1,12 +1,10 @@ // -// HistoryPage.swift +// HistoryPage+PumpOpsSession.swift // RileyLinkKit // // Copyright © 2017 Pete Schwamb. All rights reserved. // -import MinimedKit - extension HistoryPage { /// Returns TimestampedHistoryEvents from this page occuring after a given date diff --git a/MinimedKit/PumpManager/InsulinDataSource.swift b/MinimedKit/PumpManager/InsulinDataSource.swift new file mode 100644 index 000000000..3f38c5c43 --- /dev/null +++ b/MinimedKit/PumpManager/InsulinDataSource.swift @@ -0,0 +1,24 @@ +// +// InsulinDataSource.swift +// Loop +// +// Created by Nathan Racklyeft on 6/10/16. +// Copyright © 2016 Nathan Racklyeft. All rights reserved. +// + +import Foundation + + +public enum InsulinDataSource: Int, CustomStringConvertible { + case pumpHistory = 0 + case reservoir + + public var description: String { + switch self { + case .pumpHistory: + return NSLocalizedString("Event History", comment: "Describing the pump history insulin data source") + case .reservoir: + return NSLocalizedString("Reservoir", comment: "Describing the reservoir insulin data source") + } + } +} diff --git a/MinimedKit/PumpManager/MinimedPumpManager.swift b/MinimedKit/PumpManager/MinimedPumpManager.swift new file mode 100644 index 000000000..abaddddf5 --- /dev/null +++ b/MinimedKit/PumpManager/MinimedPumpManager.swift @@ -0,0 +1,696 @@ +// +// MinimedPumpManager.swift +// Loop +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + +import HealthKit +import LoopKit +import RileyLinkKit +import RileyLinkBLEKit +import os.log + + +public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { + public static let managerIdentifier: String = "Minimed500" + + public init(state: MinimedPumpManagerState, rileyLinkManager: RileyLinkDeviceManager?) { + self.state = state + + super.init(rileyLinkPumpManagerState: state.rileyLinkPumpManagerState, rileyLinkManager: rileyLinkManager) + + // Pump communication + let idleListeningEnabled = state.pumpModel.hasMySentry + self.pumpOps = PumpOps(pumpSettings: state.pumpSettings, pumpState: state.pumpState, delegate: self) + + self.rileyLinkManager.idleListeningState = idleListeningEnabled ? MinimedPumpManagerState.idleListeningEnabledDefaults : .disabled + } + + public required convenience init?(rawState: PumpManager.RawStateValue) { + guard let state = MinimedPumpManagerState(rawValue: rawState) else { + return nil + } + + self.init(state: state, rileyLinkManager: nil) + } + + public var rawState: PumpManager.RawStateValue { + return state.rawValue + } + + override public var rileyLinkPumpManagerState: RileyLinkPumpManagerState { + didSet { + state.rileyLinkPumpManagerState = rileyLinkPumpManagerState + } + } + + // TODO: apply lock + public private(set) var state: MinimedPumpManagerState { + didSet { + pumpManagerDelegate?.pumpManagerDidUpdateState(self) + } + } + + public weak var cgmManagerDelegate: CGMManagerDelegate? + + public weak var pumpManagerDelegate: PumpManagerDelegate? + + public let log = OSLog(category: "MinimedPumpManager") + + // MARK: - CGMManager + + public private(set) var sensorState: SensorDisplayable? + + // TODO: Isolate to queue + private var latestPumpStatus: PumpStatus? + + // TODO: Isolate to queue + private var lastAddedPumpEvents: Date = .distantPast + + // TODO: Isolate to queue + // Returns a value in the range 0 - 1 + public var pumpBatteryChargeRemaining: Double? { + if let status = latestPumpStatusFromMySentry { + return Double(status.batteryRemainingPercent) / 100 + } else if let status = latestPumpStatus { + return batteryChemistry.chargeRemaining(at: status.batteryVolts) + } else { + return nil + } + } + + // Battery monitor + private func observeBatteryDuring(_ block: () -> Void) { + let oldVal = pumpBatteryChargeRemaining + block() + pumpManagerDelegate?.pumpManagerDidUpdatePumpBatteryChargeRemaining(self, oldValue: oldVal) + } + + public func updateBLEHeartbeatPreference() { + queue.async { + /// Controls the management of the RileyLink timer tick, which is a reliably-changing BLE + /// characteristic which can cause the app to wake. For most users, the G5 Transmitter and + /// G4 Receiver are reliable as hearbeats, but users who find their resources extremely constrained + /// due to greedy apps or older devices may choose to always enable the timer by always setting `true` + self.rileyLinkManager.timerTickEnabled = self.isPumpDataStale() || (self.pumpManagerDelegate?.pumpManagerShouldProvideBLEHeartbeat(self) == true) + } + } + + public var pumpRecordsBasalProfileStartEvents: Bool? { + return pumpState?.pumpModel?.recordsBasalProfileStartEvents + } + + public var pumpReservoirCapacity: Double? { + guard let capacity = pumpState?.pumpModel?.reservoirCapacity else { + return nil + } + + return Double(capacity) + } + + public var pumpTimeZone: TimeZone? { + return pumpState?.timeZone + } + + // MARK: - RileyLink Updates + + override public func device(_ device: RileyLinkDevice, didReceivePacket packet: RFPacket) { + guard let data = MinimedPacket(encodedData: packet.data)?.data, + let message = PumpMessage(rxData: data), + message.address.hexadecimalString == state.pumpID, + case .mySentry = message.packetType + else { + return + } + + queue.async { + switch message.messageBody { + case let body as MySentryPumpStatusMessageBody: + self.updatePumpStatus(body, from: device) + case is MySentryAlertMessageBody, is MySentryAlertClearedMessageBody: + break + case let body: + // TODO: I think we've learned everything we're going to learn here. + self.log.error("Unknown MySentry Message: %d: %{public}@", message.messageType.rawValue, body.txData.hexadecimalString) + } + } + } + + override public func deviceTimerDidTick(_ device: RileyLinkDevice) { + self.pumpManagerDelegate?.pumpManagerBLEHeartbeatDidFire(self) + } + + // MARK: - CustomDebugStringConvertible + + override public var debugDescription: String { + return [ + "## MinimedPumpManager", + "latestPumpStatus: \(String(describing: latestPumpStatus))", + "latestPumpStatusFromMySentry: \(String(describing: latestPumpStatusFromMySentry))", + "pumpBatteryChargeRemaining: \(String(reflecting: pumpBatteryChargeRemaining))", + "pumpSettings: \(String(reflecting: pumpSettings))", + "pumpState: \(String(reflecting: pumpState))", + "preferredInsulinDataSource: \(preferredInsulinDataSource)", + "sensorState: \(String(describing: sensorState))", + "", + super.debugDescription, + ].joined(separator: "\n") + } + + public var localizedTitle: String { + return String(format: NSLocalizedString("Minimed %@", comment: "Pump title (1: model number)"), pumpState?.pumpModel?.rawValue ?? "") + } + + /** + Attempts to fix an extended communication failure between a RileyLink device and the pump + + - parameter device: The RileyLink device + */ + private func troubleshootPumpComms(using device: RileyLinkDevice) { + /// TODO: Isolate to queue? + // Ensuring timer tick is enabled will allow more tries to bring the pump data up-to-date. + updateBLEHeartbeatPreference() + + // How long we should wait before we re-tune the RileyLink + let tuneTolerance = TimeInterval(minutes: 14) + + let deviceState = deviceStates[device.peripheralIdentifier, default: DeviceState()] + let lastTuned = deviceState.lastTuned ?? .distantPast + + if lastTuned.timeIntervalSinceNow <= -tuneTolerance { + pumpOps.runSession(withName: "Tune pump", using: device) { (session) in + do { + let scanResult = try session.tuneRadio(current: deviceState.lastValidFrequency) + self.log.error("Device %{public}@ auto-tuned to %{public}@ MHz", device.name ?? "", String(describing: scanResult.bestFrequency)) + self.queue.async { + self.deviceStates[device.peripheralIdentifier] = DeviceState( + lastTuned: Date(), + lastValidFrequency: scanResult.bestFrequency + ) + } + } catch let error { + self.log.error("Device %{public}@ auto-tune failed with error: %{public}@", device.name ?? "", String(describing: error)) + self.rileyLinkManager.deprioritize(device) + if let error = error as? LocalizedError { + self.pumpManagerDelegate?.pumpManager(self, didError: PumpManagerError.communication(MinimedPumpManagerError.tuneFailed(error))) + } + } + } + } else { + rileyLinkManager.deprioritize(device) + } + } + + // MARK: Pump data + + /// TODO: Isolate to queue + fileprivate var latestPumpStatusFromMySentry: MySentryPumpStatusMessageBody? { + didSet { + if let sensorState = latestPumpStatusFromMySentry { + self.sensorState = sensorState + } + } + } + + /** + Handles receiving a MySentry status message, which are only posted by MM x23 pumps. + + This message has two important pieces of info about the pump: reservoir volume and battery. + + Because the RileyLink must actively listen for these packets, they are not a reliable heartbeat. However, we can still use them to assert glucose data is current. + + - parameter status: The status message body + - parameter device: The RileyLink that received the message + */ + private func updatePumpStatus(_ status: MySentryPumpStatusMessageBody, from device: RileyLinkDevice) { + dispatchPrecondition(condition: .onQueue(queue)) + + var pumpDateComponents = status.pumpDateComponents + var glucoseDateComponents = status.glucoseDateComponents + + guard let timeZone = pumpState?.timeZone else { + return + } + + pumpDateComponents.timeZone = timeZone + glucoseDateComponents?.timeZone = timeZone + + // The pump sends the same message 3x, so ignore it if we've already seen it. + guard status != latestPumpStatusFromMySentry, let pumpDate = pumpDateComponents.date else { + return + } + + // Ignore status messages without some semblance of recency. + guard abs(pumpDate.timeIntervalSinceNow) < .minutes(5) else { + log.error("Ignored MySentry status due to date mismatch: %{public}@ in %{public}", String(describing: pumpDate), String(describing: timeZone)) + return + } + + observeBatteryDuring { + latestPumpStatusFromMySentry = status + } + + device.getStatus { (deviceStatus) in + // Trigger device status upload, even if something is wrong with pumpStatus + self.queue.async { + let deviceState = self.deviceStates[device.peripheralIdentifier] + + let pumpManagerStatus = PumpManagerStatus( + date: pumpDate, + timeZone: timeZone, + device: deviceStatus.device(settings: self.pumpSettings, pumpState: self.pumpState), + lastValidFrequency: deviceState?.lastValidFrequency, + lastTuned: deviceState?.lastTuned, + battery: PumpManagerStatus.BatteryStatus(percent: Double(status.batteryRemainingPercent) / 100), + isSuspended: nil, + isBolusing: nil, + remainingReservoir: HKQuantity(unit: .internationalUnit(), doubleValue: status.reservoirRemainingUnits) + ) + + self.pumpManagerDelegate?.pumpManager(self, didUpdateStatus: pumpManagerStatus) + + switch status.glucose { + case .active(glucose: let glucose): + // Enlite data is included + if let date = glucoseDateComponents?.date { + let sample = NewGlucoseSample( + date: date, + quantity: HKQuantity(unit: .milligramsPerDeciliter, doubleValue: Double(glucose)), + isDisplayOnly: false, + syncIdentifier: status.glucoseSyncIdentifier ?? UUID().uuidString, + device: deviceStatus.device(settings: self.pumpSettings, pumpState: self.pumpState) + ) + + self.cgmManagerDelegate?.cgmManager(self, didUpdateWith: .newData([sample])) + } + case .off: + // Enlite is disabled, so assert glucose from another source + self.pumpManagerDelegate?.pumpManagerBLEHeartbeatDidFire(self) + default: + // Anything else is an Enlite error + // TODO: Provide info about status.glucose + self.cgmManagerDelegate?.cgmManager(self, didUpdateWith: .error(PumpManagerError.deviceState(nil))) + } + } + } + + // Sentry packets are sent in groups of 3, 5s apart. Wait 11s before allowing the loop data to continue to avoid conflicting comms. + queue.asyncAfter(deadline: .now() + .seconds(11)) { + self.updateReservoirVolume(status.reservoirRemainingUnits, at: pumpDate, withTimeLeft: TimeInterval(minutes: Double(status.reservoirRemainingMinutes))) + } + } + + /** + Store a new reservoir volume and notify observers of new pump data. + + - parameter units: The number of units remaining + - parameter date: The date the reservoir was read + - parameter timeLeft: The approximate time before the reservoir is empty + */ + private func updateReservoirVolume(_ units: Double, at date: Date, withTimeLeft timeLeft: TimeInterval?) { + pumpManagerDelegate?.pumpManager(self, didReadReservoirValue: units, at: date) { (result) in + /// TODO: Isolate to queue + + switch result { + case .failure: + break + case .success(let (_, _, areStoredValuesContinuous)): + // Run a loop as long as we have fresh, reliable pump data. + if self.preferredInsulinDataSource == .pumpHistory || !areStoredValuesContinuous { + self.fetchPumpHistory { (error) in + if let error = error as? PumpManagerError { + self.pumpManagerDelegate?.pumpManager(self, didError: error) + } + + if error == nil || areStoredValuesContinuous { + self.pumpManagerDelegate?.pumpManagerRecommendsLoop(self) + } + } + } else { + self.pumpManagerDelegate?.pumpManagerRecommendsLoop(self) + } + } + + // New reservoir data means we may want to adjust our timer tick requirements + self.updateBLEHeartbeatPreference() + } + } + + /// TODO: Isolate to queue + /// Polls the pump for new history events and passes them to the loop manager + /// + /// - Parameters: + /// - completion: A closure called once upon completion + /// - error: An error describing why the fetch and/or store failed + private func fetchPumpHistory(_ completion: @escaping (_ error: Error?) -> Void) { + rileyLinkManager.getDevices { (devices) in + guard let device = devices.firstConnected else { + completion(PumpManagerError.connection(nil)) + return + } + + self.pumpOps.runSession(withName: "Fetch Pump History", using: device) { (session) in + do { + guard let startDate = self.pumpManagerDelegate?.startDateToFilterNewPumpEvents(for: self) else { + assertionFailure("pumpManagerDelegate cannot be nil") + throw PumpManagerError.configuration(MinimedPumpManagerError.noDelegate) + } + + let (events, model) = try session.getHistoryEvents(since: startDate) + + self.pumpManagerDelegate?.pumpManager(self, didReadPumpEvents: events.pumpEvents(from: model), completion: { (error) in + if error != nil { + self.lastAddedPumpEvents = Date() + } + + completion(error) + }) + } catch let error { + self.troubleshootPumpComms(using: device) + + completion(PumpManagerError.communication(error as? LocalizedError)) + } + } + } + } + + /// TODO: Isolate to queue + private func isPumpDataStale() -> Bool { + // How long should we wait before we poll for new pump data? + let pumpStatusAgeTolerance = rileyLinkManager.idleListeningEnabled ? TimeInterval(minutes: 6) : TimeInterval(minutes: 4) + + return isReservoirDataOlderThan(timeIntervalSinceNow: -pumpStatusAgeTolerance) + } + + private func isReservoirDataOlderThan(timeIntervalSinceNow: TimeInterval) -> Bool { + var lastReservoirDate = pumpManagerDelegate?.startDateToFilterNewReservoirEvents(for: self) ?? .distantPast + + // Look for reservoir data from MySentry that hasn't yet been written (due to 11-second imposed delay) + if let sentryStatus = latestPumpStatusFromMySentry, let timeZone = pumpState?.timeZone { + var components = sentryStatus.pumpDateComponents + components.timeZone = timeZone + + lastReservoirDate = max(components.date ?? .distantPast, lastReservoirDate) + } + + return lastReservoirDate.timeIntervalSinceNow <= timeIntervalSinceNow + } + + /** + Ensures pump data is current by either waking and polling, or ensuring we're listening to sentry packets. + */ + /// TODO: Isolate to queue + public func assertCurrentPumpData() { + rileyLinkManager.assertIdleListening(forcingRestart: true) + + guard isPumpDataStale() else { + return + } + + self.log.debug("Pump data is stale, fetching.") + + rileyLinkManager.getDevices { (devices) in + guard let device = devices.firstConnected else { + let error = PumpManagerError.connection(nil) + self.log.error("No devices found while fetching pump data") + self.pumpManagerDelegate?.pumpManager(self, didError: error) + return + } + + self.pumpOps.runSession(withName: "Get Pump Status", using: device) { (session) in + do { + let status = try session.getCurrentPumpStatus() + guard var date = status.clock.date else { + assertionFailure("Could not interpret a valid date from \(status.clock) in the system calendar") + return + } + + // Check if the clock should be reset + if abs(date.timeIntervalSinceNow) > .seconds(20) { + self.log.error("Pump clock is more than 20 seconds off. Resetting.") + self.pumpManagerDelegate?.pumpManager(self, didAdjustPumpClockBy: date.timeIntervalSinceNow) + try session.setTimeToNow() + + guard let newDate = try session.getTime().date else { + throw PumpManagerError.configuration(MinimedPumpManagerError.noDate) + } + + date = newDate + } + + self.observeBatteryDuring { + self.latestPumpStatus = status + } + + self.updateReservoirVolume(status.reservoir, at: date, withTimeLeft: nil) + + device.getStatus { (deviceStatus) in + self.queue.async { + let deviceState = self.deviceStates[device.peripheralIdentifier] + let pumpManagerStatus = PumpManagerStatus( + date: date, + timeZone: session.pump.timeZone, + device: deviceStatus.device(settings: self.pumpSettings, pumpState: self.pumpState), + lastValidFrequency: deviceState?.lastValidFrequency, + lastTuned: deviceState?.lastTuned, + battery: PumpManagerStatus.BatteryStatus( + voltage: status.batteryVolts, + state: { + switch status.batteryStatus { + case .normal: + return .normal + case .low: + return .low + case .unknown: + return nil + } + }() + ), + isSuspended: status.suspended, + isBolusing: status.bolusing, + remainingReservoir: HKQuantity(unit: .internationalUnit(), doubleValue: status.reservoir) + ) + + self.pumpManagerDelegate?.pumpManager(self, didUpdateStatus: pumpManagerStatus) + } + } + } catch let error { + self.log.error("Failed to fetch pump status: %{public}@", String(describing: error)) + self.pumpManagerDelegate?.pumpManager(self, didError: PumpManagerError.communication(error as? LocalizedError)) + self.troubleshootPumpComms(using: device) + } + } + } + } + + // TODO: Isolate to queue + public func enactBolus(units: Double, at startDate: Date, willRequest: @escaping (_ units: Double, _ date: Date) -> Void, completion: @escaping (_ error: Error?) -> Void) { + guard units > 0 else { + completion(nil) + return + } + + // If we don't have recent pump data, or the pump was recently rewound, read new pump data before bolusing. + let shouldReadReservoir = isReservoirDataOlderThan(timeIntervalSinceNow: .minutes(-6)) + + pumpOps.runSession(withName: "Bolus", using: rileyLinkManager.firstConnectedDevice) { (session) in + guard let session = session else { + completion(PumpManagerError.connection(nil)) + return + } + + if shouldReadReservoir { + do { + let reservoir = try session.getRemainingInsulin() + + self.pumpManagerDelegate?.pumpManager(self, didReadReservoirValue: reservoir.units, at: reservoir.clock.date!) { _ in + // Ignore result + } + } catch let error as PumpOpsError { + self.log.error("Failed to fetch pump status: %{public}@", String(describing: error)) + completion(SetBolusError.certain(error)) + return + } catch let error as PumpCommandError { + self.log.error("Failed to fetch pump status: %{public}@", String(describing: error)) + switch error { + case .arguments(let error): + completion(SetBolusError.certain(error)) + case .command(let error): + completion(SetBolusError.certain(error)) + } + return + } catch let error { + completion(error) + return + } + } + + do { + willRequest(units, Date()) + try session.setNormalBolus(units: units) + completion(nil) + } catch let error { + self.log.error("Failed to bolus: %{public}@", String(describing: error)) + completion(error) + } + } + } + + public func enactTempBasal(unitsPerHour: Double, for duration: TimeInterval, completion: @escaping (PumpManagerResult) -> Void) { + pumpOps.runSession(withName: "Set Temp Basal", using: rileyLinkManager.firstConnectedDevice) { (session) in + guard let session = session else { + completion(.failure(PumpManagerError.connection(nil))) + return + } + + do { + let response = try session.setTempBasal(unitsPerHour, duration: duration) + + let now = Date() + let endDate = now.addingTimeInterval(response.timeRemaining) + let startDate = endDate.addingTimeInterval(-duration) + completion(.success(DoseEntry( + type: .tempBasal, + startDate: startDate, + endDate: endDate, + value: response.rate, + unit: .unitsPerHour + ))) + + // Continue below + } catch let error { + completion(.failure(error)) + return + } + + do { + // If we haven't fetched history in a while, our preferredInsulinDataSource is probably .reservoir, so + // let's take advantage of the pump radio being on. + if self.lastAddedPumpEvents.timeIntervalSinceNow < .minutes(-4) { + let clock = try session.getTime() + // Check if the clock should be reset + if let date = clock.date, abs(date.timeIntervalSinceNow) > .seconds(20) { + self.log.error("Pump clock is more than 20 seconds off. Resetting.") + self.pumpManagerDelegate?.pumpManager(self, didAdjustPumpClockBy: date.timeIntervalSinceNow) + try session.setTimeToNow() + } + + self.fetchPumpHistory { (error) in + if let error = error { + self.log.error("Post-basal history fetch failed: %{public}@", String(describing: error)) + } + } + } + } catch let error { + self.log.error("Post-basal time sync failed: %{public}@", String(describing: error)) + } + } + } + + // MARK: - Configuration + + // MARK: Pump + + public func getStateForDevice(_ device: RileyLinkDevice, completion: @escaping (_ deviceState: DeviceState, _ pumpState: PumpState?, _ pumpSettings: PumpSettings?, _ pumpOps: PumpOps) -> Void) { + queue.async { + completion(self.deviceStates[device.peripheralIdentifier, default: DeviceState()], self.pumpState, self.pumpSettings, self.pumpOps) + } + } + + public private(set) var pumpOps: PumpOps! + + private var pumpSettings: PumpSettings { + return state.pumpSettings + } + + private var pumpState: PumpState? { + return state.pumpState + } + + /// The user's preferred method of fetching insulin data from the pump + public var preferredInsulinDataSource: InsulinDataSource { + get { + return state.preferredInsulinDataSource + } + set { + state.preferredInsulinDataSource = newValue + } + } + + /// The pump battery chemistry, for voltage -> percentage calculation + public var batteryChemistry: BatteryChemistryType { + get { + return state.batteryChemistry + } + set { + state.batteryChemistry = newValue + } + } +} + + +extension MinimedPumpManager: PumpOpsDelegate { + public func pumpOps(_ pumpOps: PumpOps, didChange state: PumpState) { + // We don't care + } +} + + +extension MinimedPumpManager: CGMManager { + public var shouldSyncToRemoteService: Bool { + return true + } + + public var providesBLEHeartbeat: Bool { + return false + } + + public var managedDataInterval: TimeInterval? { + return nil + } + + public var device: HKDevice? { + return nil + } + + public func fetchNewDataIfNeeded(_ completion: @escaping (CGMResult) -> Void) { + rileyLinkManager.getDevices { (devices) in + guard let device = devices.firstConnected else { + completion(.error(PumpManagerError.connection(nil))) + return + } + + let latestGlucoseDate = self.cgmManagerDelegate?.startDateToFilterNewData(for: self) ?? Date(timeIntervalSinceNow: TimeInterval(hours: -24)) + + guard latestGlucoseDate.timeIntervalSinceNow <= TimeInterval(minutes: -4.5) else { + completion(.noData) + return + } + + self.pumpOps.runSession(withName: "Fetch Enlite History", using: device) { (session) in + do { + let events = try session.getGlucoseHistoryEvents(since: latestGlucoseDate.addingTimeInterval(.minutes(1))) + + if let latestSensorEvent = events.compactMap({ $0.glucoseEvent as? RelativeTimestampedGlucoseEvent }).last { + self.sensorState = EnliteSensorDisplayable(latestSensorEvent) + } + + let unit = HKUnit.milligramsPerDeciliter + let glucoseValues: [NewGlucoseSample] = events + // TODO: Is the { $0.date > latestGlucoseDate } filter duplicative? + .filter({ $0.glucoseEvent is SensorValueGlucoseEvent && $0.date > latestGlucoseDate }) + .map { + let glucoseEvent = $0.glucoseEvent as! SensorValueGlucoseEvent + let quantity = HKQuantity(unit: unit, doubleValue: Double(glucoseEvent.sgv)) + return NewGlucoseSample(date: $0.date, quantity: quantity, isDisplayOnly: false, syncIdentifier: glucoseEvent.glucoseSyncIdentifier ?? UUID().uuidString, device: self.device) + } + + completion(.newData(glucoseValues)) + } catch let error { + completion(.error(error)) + } + } + } + } +} diff --git a/MinimedKit/PumpManager/MinimedPumpManagerError.swift b/MinimedKit/PumpManager/MinimedPumpManagerError.swift new file mode 100644 index 000000000..ae1311507 --- /dev/null +++ b/MinimedKit/PumpManager/MinimedPumpManagerError.swift @@ -0,0 +1,28 @@ +// +// MinimedPumpManagerError.swift +// Loop +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + +import Foundation + +public enum MinimedPumpManagerError: Error { + case noDate + case noDelegate + case tuneFailed(LocalizedError) +} + + +extension MinimedPumpManagerError: LocalizedError { + public var errorDescription: String? { + switch self { + case .noDate: + return nil + case .noDelegate: + return nil + case .tuneFailed(let error): + return [NSLocalizedString("RileyLink radio tune failed", comment: "Error description"), error.errorDescription].compactMap({ $0 }).joined(separator: ". ") + } + } +} diff --git a/MinimedKit/PumpManager/MinimedPumpManagerState.swift b/MinimedKit/PumpManager/MinimedPumpManagerState.swift new file mode 100644 index 000000000..fb8b6d00d --- /dev/null +++ b/MinimedKit/PumpManager/MinimedPumpManagerState.swift @@ -0,0 +1,140 @@ +// +// MinimedPumpManagerState.swift +// Loop +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + +import LoopKit +import RileyLinkKit +import RileyLinkBLEKit + + +public struct MinimedPumpManagerState: RawRepresentable, Equatable { + public typealias RawValue = PumpManager.RawStateValue + + public static let version = 1 + + public var batteryChemistry: BatteryChemistryType + + public var preferredInsulinDataSource: InsulinDataSource + + public var pumpColor: PumpColor + + public var pumpModel: PumpModel + + public var pumpID: String + + public var pumpRegion: PumpRegion + + public var pumpSettings: PumpSettings { + get { + return PumpSettings(pumpID: pumpID, pumpRegion: pumpRegion) + } + set { + pumpID = newValue.pumpID + pumpRegion = newValue.pumpRegion + } + } + + public var pumpState: PumpState { + get { + var state = PumpState() + state.pumpModel = pumpModel + state.timeZone = timeZone + return state + } + set { + if let model = newValue.pumpModel { + pumpModel = model + } + timeZone = newValue.timeZone + } + } + + public var rileyLinkPumpManagerState: RileyLinkPumpManagerState + + public var timeZone: TimeZone + + public init(batteryChemistry: BatteryChemistryType = .alkaline, preferredInsulinDataSource: InsulinDataSource = .pumpHistory, pumpColor: PumpColor, pumpID: String, pumpModel: PumpModel, pumpRegion: PumpRegion, rileyLinkPumpManagerState: RileyLinkPumpManagerState, timeZone: TimeZone) { + self.batteryChemistry = batteryChemistry + self.preferredInsulinDataSource = preferredInsulinDataSource + self.pumpColor = pumpColor + self.pumpID = pumpID + self.pumpModel = pumpModel + self.pumpRegion = pumpRegion + self.rileyLinkPumpManagerState = rileyLinkPumpManagerState + self.timeZone = timeZone + } + + public init?(rawValue: RawValue) { + guard + let batteryChemistryRaw = rawValue["batteryChemistry"] as? BatteryChemistryType.RawValue, + let insulinDataSourceRaw = rawValue["insulinDataSource"] as? InsulinDataSource.RawValue, + let pumpColorRaw = rawValue["pumpColor"] as? PumpColor.RawValue, + let pumpID = rawValue["pumpID"] as? String, + let pumpModelNumber = rawValue["pumpModel"] as? PumpModel.RawValue, + let pumpRegionRaw = rawValue["pumpRegion"] as? PumpRegion.RawValue, + let rileyLinkPumpManagerStateRaw = rawValue["rileyLinkPumpManagerState"] as? RileyLinkPumpManagerState.RawValue, + let timeZoneSeconds = rawValue["timeZone"] as? Int, + + let batteryChemistry = BatteryChemistryType(rawValue: batteryChemistryRaw), + let insulinDataSource = InsulinDataSource(rawValue: insulinDataSourceRaw), + let pumpColor = PumpColor(rawValue: pumpColorRaw), + let pumpModel = PumpModel(rawValue: pumpModelNumber), + let pumpRegion = PumpRegion(rawValue: pumpRegionRaw), + let rileyLinkPumpManagerState = RileyLinkPumpManagerState(rawValue: rileyLinkPumpManagerStateRaw), + let timeZone = TimeZone(secondsFromGMT: timeZoneSeconds) + else { + return nil + } + + self.init( + batteryChemistry: batteryChemistry, + preferredInsulinDataSource: insulinDataSource, + pumpColor: pumpColor, + pumpID: pumpID, + pumpModel: pumpModel, + pumpRegion: pumpRegion, + rileyLinkPumpManagerState: rileyLinkPumpManagerState, + timeZone: timeZone + ) + } + + public var rawValue: RawValue { + return [ + "batteryChemistry": batteryChemistry.rawValue, + "insulinDataSource": preferredInsulinDataSource.rawValue, + "pumpColor": pumpColor.rawValue, + "pumpID": pumpID, + "pumpModel": pumpModel.rawValue, + "pumpRegion": pumpRegion.rawValue, + "rileyLinkPumpManagerState": rileyLinkPumpManagerState.rawValue, + "timeZone": timeZone.secondsFromGMT(), + + "version": MinimedPumpManagerState.version, + ] + } +} + + +extension MinimedPumpManagerState { + static let idleListeningEnabledDefaults: RileyLinkDevice.IdleListeningState = .enabled(timeout: .minutes(4), channel: 0) +} + + +extension MinimedPumpManagerState: CustomDebugStringConvertible { + public var debugDescription: String { + return [ + "## MinimedPumpManagerState", + "batteryChemistry: \(batteryChemistry)", + "preferredInsulinDataSource: \(preferredInsulinDataSource)", + "pumpColor: \(pumpColor)", + "pumpID: ✔︎", + "pumpModel: \(pumpModel.rawValue)", + "pumpRegion: \(pumpRegion)", + "timeZone: \(timeZone)", + String(reflecting: rileyLinkPumpManagerState), + ].joined(separator: "\n") + } +} diff --git a/RileyLinkKit/Extensions/PumpMessage.swift b/MinimedKit/PumpManager/PumpMessage+PumpOpsSession.swift similarity index 97% rename from RileyLinkKit/Extensions/PumpMessage.swift rename to MinimedKit/PumpManager/PumpMessage+PumpOpsSession.swift index c61bfc561..f1f33d1d5 100644 --- a/RileyLinkKit/Extensions/PumpMessage.swift +++ b/MinimedKit/PumpManager/PumpMessage+PumpOpsSession.swift @@ -5,8 +5,6 @@ // Copyright © 2017 Pete Schwamb. All rights reserved. // -import MinimedKit - extension PumpMessage { /// Initializes a Carelink message using settings and a default body diff --git a/RileyLinkKit/PumpMessageSender.swift b/MinimedKit/PumpManager/PumpMessageSender.swift similarity index 99% rename from RileyLinkKit/PumpMessageSender.swift rename to MinimedKit/PumpManager/PumpMessageSender.swift index f40df7f7e..017f33edc 100644 --- a/RileyLinkKit/PumpMessageSender.swift +++ b/MinimedKit/PumpManager/PumpMessageSender.swift @@ -7,7 +7,6 @@ // import Foundation -import MinimedKit import RileyLinkBLEKit import os.log diff --git a/RileyLinkKit/PumpOps.swift b/MinimedKit/PumpManager/PumpOps.swift similarity index 99% rename from RileyLinkKit/PumpOps.swift rename to MinimedKit/PumpManager/PumpOps.swift index bea775877..409e7f6aa 100644 --- a/RileyLinkKit/PumpOps.swift +++ b/MinimedKit/PumpManager/PumpOps.swift @@ -7,7 +7,7 @@ // import Foundation -import MinimedKit +import RileyLinkKit import RileyLinkBLEKit diff --git a/RileyLinkKit/PumpOpsError.swift b/MinimedKit/PumpManager/PumpOpsError.swift similarity index 99% rename from RileyLinkKit/PumpOpsError.swift rename to MinimedKit/PumpManager/PumpOpsError.swift index be72427f0..eae6c1560 100644 --- a/RileyLinkKit/PumpOpsError.swift +++ b/MinimedKit/PumpManager/PumpOpsError.swift @@ -7,7 +7,6 @@ // import Foundation -import MinimedKit import RileyLinkBLEKit diff --git a/MinimedKit/PumpManager/PumpOpsSession+LoopKit.swift b/MinimedKit/PumpManager/PumpOpsSession+LoopKit.swift new file mode 100644 index 000000000..00f5949b4 --- /dev/null +++ b/MinimedKit/PumpManager/PumpOpsSession+LoopKit.swift @@ -0,0 +1,39 @@ +// +// PumpOpsSession.swift +// Loop +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + +import Foundation +import LoopKit + + +extension PumpOpsSession { + public func getBasalRateSchedule(for profile: BasalProfile) throws -> BasalRateSchedule? { + let basalSchedule = try getBasalSchedule(for: profile) + + return BasalRateSchedule(dailyItems: basalSchedule?.entries.map { $0.repeatingScheduleValue } ?? [], timeZone: pump.timeZone) + } +} + + + +extension BasalSchedule { + public init(repeatingScheduleValues: [LoopKit.RepeatingScheduleValue]) { + self.init(entries: repeatingScheduleValues.enumerated().map({ (index, value) -> BasalScheduleEntry in + return BasalScheduleEntry(index: index, repeatingScheduleValue: value) + })) + } +} + + +extension MinimedKit.BasalScheduleEntry { + init(index: Int, repeatingScheduleValue: LoopKit.RepeatingScheduleValue) { + self.init(index: index, timeOffset: repeatingScheduleValue.startTime, rate: repeatingScheduleValue.value) + } + + var repeatingScheduleValue: LoopKit.RepeatingScheduleValue { + return RepeatingScheduleValue(startTime: timeOffset, value: rate) + } +} diff --git a/RileyLinkKit/PumpSettings.swift b/MinimedKit/PumpManager/PumpSettings.swift similarity index 98% rename from RileyLinkKit/PumpSettings.swift rename to MinimedKit/PumpManager/PumpSettings.swift index e36e90fc2..72bc91f38 100644 --- a/RileyLinkKit/PumpSettings.swift +++ b/MinimedKit/PumpManager/PumpSettings.swift @@ -5,8 +5,6 @@ // Copyright © 2017 Pete Schwamb. All rights reserved. // -import MinimedKit - public struct PumpSettings: RawRepresentable { public typealias RawValue = [String: Any] diff --git a/RileyLinkKit/PumpState.swift b/MinimedKit/PumpManager/PumpState.swift similarity index 98% rename from RileyLinkKit/PumpState.swift rename to MinimedKit/PumpManager/PumpState.swift index 18f6aaf97..24ed8172b 100644 --- a/RileyLinkKit/PumpState.swift +++ b/MinimedKit/PumpManager/PumpState.swift @@ -7,7 +7,6 @@ // import Foundation -import MinimedKit public struct PumpState: RawRepresentable, Equatable { diff --git a/MinimedKit/PumpManager/RileyLinkDevice.swift b/MinimedKit/PumpManager/RileyLinkDevice.swift new file mode 100644 index 000000000..72d1e926c --- /dev/null +++ b/MinimedKit/PumpManager/RileyLinkDevice.swift @@ -0,0 +1,25 @@ +// +// RileyLinkDevice.swift +// Loop +// +// Copyright © 2017 LoopKit Authors. All rights reserved. +// + +import HealthKit +import RileyLinkBLEKit + + +extension RileyLinkDevice.Status { + func device(settings: PumpSettings?, pumpState: PumpState?) -> HKDevice { + return HKDevice( + name: name, + manufacturer: "Medtronic", + model: pumpState?.pumpModel?.rawValue, + hardwareVersion: nil, + firmwareVersion: radioFirmwareVersion?.description, + softwareVersion: String(MinimedKitVersionNumber), + localIdentifier: settings?.pumpID, + udiDeviceIdentifier: nil + ) + } +} diff --git a/MinimedKit/CRC8.swift b/MinimedKit/Radio/CRC8.swift similarity index 100% rename from MinimedKit/CRC8.swift rename to MinimedKit/Radio/CRC8.swift diff --git a/MinimedKit/FourByteSixByteEncoding.swift b/MinimedKit/Radio/FourByteSixByteEncoding.swift similarity index 100% rename from MinimedKit/FourByteSixByteEncoding.swift rename to MinimedKit/Radio/FourByteSixByteEncoding.swift diff --git a/MinimedKit/MinimedPacket.swift b/MinimedKit/Radio/MinimedPacket.swift similarity index 100% rename from MinimedKit/MinimedPacket.swift rename to MinimedKit/Radio/MinimedPacket.swift diff --git a/MinimedKitTests/Messages/ChangeMaxBolusMessageBodyTests.swift b/MinimedKitTests/Messages/ChangeMaxBolusMessageBodyTests.swift index eb99f0bb6..67a090764 100644 --- a/MinimedKitTests/Messages/ChangeMaxBolusMessageBodyTests.swift +++ b/MinimedKitTests/Messages/ChangeMaxBolusMessageBodyTests.swift @@ -10,21 +10,34 @@ import XCTest class ChangeMaxBolusMessageBodyTests: XCTestCase { - func testMaxBolus() { - let body = ChangeMaxBolusMessageBody(maxBolusUnits: 6.4)! + func testMaxBolus522() { + let body = ChangeMaxBolusMessageBody(pumpModel: .model522, maxBolusUnits: 6.4)! XCTAssertEqual(Data(hexadecimalString: "0140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")!, body.txData, body.txData.hexadecimalString) } - func testMaxBolusRounded() { - let body = ChangeMaxBolusMessageBody(maxBolusUnits: 2.25)! + func testMaxBolus523() { + let body = ChangeMaxBolusMessageBody(pumpModel: .model523, maxBolusUnits: 6.4)! + + XCTAssertEqual(Data(hexadecimalString: "0200400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")!, body.txData, body.txData.hexadecimalString) + } + + func testMaxBolusRounded522() { + let body = ChangeMaxBolusMessageBody(pumpModel: .model522, maxBolusUnits: 2.25)! XCTAssertEqual(Data(hexadecimalString: "0116000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")!, body.txData, body.txData.hexadecimalString) } + + func testMaxBolusRounded523() { + let body = ChangeMaxBolusMessageBody(pumpModel: .model523, maxBolusUnits: 2.25)! + + XCTAssertEqual(Data(hexadecimalString: "0200160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")!, body.txData, body.txData.hexadecimalString) + } + func testMaxBolusOutOfRange() { - XCTAssertNil(ChangeMaxBolusMessageBody(maxBolusUnits: -1)) - XCTAssertNil(ChangeMaxBolusMessageBody(maxBolusUnits: 26)) + XCTAssertNil(ChangeMaxBolusMessageBody(pumpModel: .model522, maxBolusUnits: -1)) + XCTAssertNil(ChangeMaxBolusMessageBody(pumpModel: .model523, maxBolusUnits: 26)) } } diff --git a/RileyLinkKitTests/PumpOpsSynchronousBuildFromFramesTests.swift b/MinimedKitTests/PumpOpsSynchronousBuildFromFramesTests.swift similarity index 99% rename from RileyLinkKitTests/PumpOpsSynchronousBuildFromFramesTests.swift rename to MinimedKitTests/PumpOpsSynchronousBuildFromFramesTests.swift index f9ca7348f..5f94a948f 100644 --- a/RileyLinkKitTests/PumpOpsSynchronousBuildFromFramesTests.swift +++ b/MinimedKitTests/PumpOpsSynchronousBuildFromFramesTests.swift @@ -9,8 +9,8 @@ import XCTest @testable import RileyLinkKit -import MinimedKit -import RileyLinkBLEKit +@testable import MinimedKit +@testable import RileyLinkBLEKit class PumpOpsSynchronousBuildFromFramesTests: XCTestCase { diff --git a/RileyLinkKitTests/PumpOpsSynchronousTests.swift b/MinimedKitTests/PumpOpsSynchronousTests.swift similarity index 100% rename from RileyLinkKitTests/PumpOpsSynchronousTests.swift rename to MinimedKitTests/PumpOpsSynchronousTests.swift diff --git a/MinimedKitUI/Base.lproj/MinimedPumpManager.storyboard b/MinimedKitUI/Base.lproj/MinimedPumpManager.storyboard new file mode 100644 index 000000000..7719d3ed5 --- /dev/null +++ b/MinimedKitUI/Base.lproj/MinimedPumpManager.storyboard @@ -0,0 +1,585 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RileyLinkKitUI/CommandResponseViewController+RileyLinkDevice.swift b/MinimedKitUI/CommandResponseViewController.swift similarity index 92% rename from RileyLinkKitUI/CommandResponseViewController+RileyLinkDevice.swift rename to MinimedKitUI/CommandResponseViewController.swift index 7ff5900d7..35b8dfa22 100644 --- a/RileyLinkKitUI/CommandResponseViewController+RileyLinkDevice.swift +++ b/MinimedKitUI/CommandResponseViewController.swift @@ -1,13 +1,16 @@ // -// CommandResponseViewController+RileyLinkDevice.swift -// RileyLinkKitUI +// CommandResponseViewController.swift +// MinimedKitUI // -// Copyright © 2017 Pete Schwamb. All rights reserved. +// Copyright © 2018 Pete Schwamb. All rights reserved. // -import RileyLinkBLEKit -import RileyLinkKit +import UIKit +import LoopKit +import LoopKitUI import MinimedKit +import RileyLinkKit +import RileyLinkBLEKit extension CommandResponseViewController { @@ -20,11 +23,31 @@ extension CommandResponseViewController { ops?.runSession(withName: "Set time", using: device) { (session) in let response: String do { - try session.setTime { () -> DateComponents in - let calendar = Calendar(identifier: .gregorian) - return calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: Date()) + try session.setTimeToNow(in: .current) + response = self.successText + } catch let error { + response = String(describing: error) + } + + DispatchQueue.main.async { + completionHandler(response) + } + } + + return NSLocalizedString("Changing time…", comment: "Progress message for changing pump time.") + } + } + + static func changeTime(ops: PumpOps?, rileyLinkManager: RileyLinkDeviceManager) -> T { + return T { (completionHandler) -> String in + ops?.runSession(withName: "Set time", using: rileyLinkManager.firstConnectedDevice) { (session) in + let response: String + do { + guard let session = session else { + throw PumpManagerError.connection(nil) } + try session.setTimeToNow(in: .current) response = self.successText } catch let error { response = String(describing: error) @@ -227,7 +250,7 @@ extension CommandResponseViewController { return NSLocalizedString("Reading basal schedule…", comment: "Progress message for reading basal schedule") } } - + static func enableLEDs(ops: PumpOps?, device: RileyLinkDevice) -> T { return T { (completionHandler) -> String in device.enableBLELEDs() @@ -239,7 +262,7 @@ extension CommandResponseViewController { } catch let error { response = String(describing: error) } - + DispatchQueue.main.async { completionHandler(response) } diff --git a/MinimedKitUI/Info.plist b/MinimedKitUI/Info.plist new file mode 100644 index 000000000..1007fd9dd --- /dev/null +++ b/MinimedKitUI/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/MinimedKitUI/MinimedKitUI.h b/MinimedKitUI/MinimedKitUI.h new file mode 100644 index 000000000..77c6c4600 --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.h @@ -0,0 +1,19 @@ +// +// MinimedKitUI.h +// MinimedKitUI +// +// Created by Nathan Racklyeft on 6/23/18. +// Copyright © 2018 Pete Schwamb. All rights reserved. +// + +#import + +//! Project version number for MinimedKitUI. +FOUNDATION_EXPORT double MinimedKitUIVersionNumber; + +//! Project version string for MinimedKitUI. +FOUNDATION_EXPORT const unsigned char MinimedKitUIVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/MinimedKitUI/MinimedKitUI.xcassets/5xx Blue.imageset/5xx Blue.pdf b/MinimedKitUI/MinimedKitUI.xcassets/5xx Blue.imageset/5xx Blue.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e21ed93c25bbb939cf456fddf90cb1f30bf4b37d GIT binary patch literal 4577 zcmai2cT`i`(+wCY0TGoB%9TfNNk~GGUPA<>igZXI^d^KNh!iQ(q>G?{6sb}aRHXMJ zJP-i^rHC|-+cJG zwH<;4V1O&m0U{#MTB$#sG7YK0q;({J7EcU6}*+JH6DFYT4dZ`0N}#mc|g#zf9{!@LM^sov$D2z}ZIJL2rpiuNIWCx!;x4wp42 zKYclSIJW6DlgHU0Kj6rDB7b#jV~UGV-8h|KbcZg;MlhV|F%0FA)g3Wma&&o%znePc zhEy6F18CQ(&l{3aiKqHguv`oK04`pLF@Z~Ol-)Ua+D@?oS4{I2O<2>(VkuT1YkX<> zltS4wjFD@t30H-2n){3CA^hws|EB;%=Uf7Oij159a&OMeX5J^SJSb(gl8pr6XzFjq ztLUYn7Z;6HwI4Z6MhT8Vo_H2Fn+;?XC6U!fE(x~9Dg7UP=}JJIUT zX>nhg2kE|fkgdr^dbcrdNbHw4kHsrIq+;2P9BM|-wNC(gJ~Seer@~I~u6(eNb)pdm z6~LfF=@*_*b+QY~SS30l&g{scQ_%$dfLK$u_bw1O8!07n+YuqRPLU4hR(gt-D*kSU z=IhZgxuz`es*Sb%{_T!;ApnRUJ)?{FaP@Sz!g~PXKLBM{7Xs1l z0g(Dkm()K$2q{dYCfCCag0{~D} z9|BsBKy1qIHZ;*DNwPuY&V>l&XV6ERsh7RYlQe~jI6^t9E-k{fRZ_-gwogI&Mq+TsSZBC>eb{I{L z&c7HQwO#cet_Ep;4F)$849NnKS%wTNi%q7d&vdu$kh9Q}(HW98PTAOi(Yq?-gJ0`p zQ&S7n+bgzLL<6mB-U~Nq^Lo5J3W(>DQ0ArpK~#stWp45^&ypwURkX2+9f4nMB@2j! z!Nr)esIwn)O}CagZRgJk)pXrU;ho81GwNlnMP@|TXiuc^Oyxv_vrO;te6Y>AL5Z)^ z$E1N~clZYeb{}YhU<|1iJ@dR-P7z|N46G{=8{{CWq*kd~ce2|hT}q$z;ST-Lbfc90-(4-j4>B8>*F!&D(fO1_9TH(z6DkvA7$<5C z2?-dQ3SbfEqh!6A?#N*0X#w&NmC~-lPT8E zppZay`eS#GiK>&^D}bLW%8h^^itrIKuUigopur&D*Wk;+;%*eC;H!-%+-PV6(F%~T zCJh+bM36mI@ESd1wqj8nQ|`%BrML9###Gmp6}2T9jT3^T5$^X$~rMbN2@oAI1li%#H7-E>4E35QxVCsHYNQXT78Go)f)S5b;H|5ML*w8(zdj^`!bK*Aih@idTN4TLUd4_zC<-MrIPu-6Z zX*IBnwKOSDd2(z7yCls)*U`xOk;Cm~6^p5u3#t_S;^c62P2gh7i7DQ7pIX5QhSlJc zO&)8w8|UjG0UQD6CSy6<8~Ea=jlqt=C(qvnxShE5>Dj2}sSZOqKG?u;nbVmNp&Co*8dxS4gi1yU=6^f3-xX1ubzb>|biE?A@8S&S6SwMw}&0Slg! z3G&)W{JacW7dcdwMlVZUe5r6<;kxo8-4g{agN8--s?&|N>QwwM`a{u)h?LEg>8_H* z;&{j8#S}jtt)$@;?-UEsOg@YA0T;jJeXSzbX;Ns?3(6@s$WoiCY?ckhsHSBn<8I^9 za1pp$A5m>OJhcfy2`^4-6)G&0zu|dwo=s`s(e*b~m6s|nyu-hPokdIJ9t;yT1IlwRaqq%{b0;B~+{j5-_)i5AE7<@b4K^rc%Mk7mAxe=e_% z@U7Z+_|o!O_H!az8e2UZE87*e6l6P!HO(chD{VGy9@$Z8XH4@9Y&>f`|I8egoVwDZ zZ^Kg&C6!fDx|}c4FPA%BEL&n#P+@4BbGf4Tj9G%HiG<<{(-(T)N?ICFL#RcW&T5vN zPG(7FZUef(B;Zx!Yv7$_l;ZuSf~?4_25bg4XUgiYqWI!|!5rfp>2^u0=hq_F<)%$| z%Olb;37D9!OL`-N6Z)3beU*K*j&pXr$YNAYM|Sy`k?58#xt;XdJYbUPyiFaDYk|DjWhpQfsM*Q2K?`TY2v3}Esn z(~WusdQbG`(9klkF%OEcxc6V1s^V~u7qu3Rw(xPw8ocs8dD?h!zvt3$%)D2tbL;qs z?C4?DfzU~flkw=Nj->p=dA2?p^V=z9SL3giy-3)>tvamc%UzI*kc*K!Q}0z@><`_= z9+Dq=?T>E`ug&idA83Ik!H=mwL2|)rU;|1y8ZqkA$34Lyi3=suK3*a@dk_FR8^E)Yt&;q-*lp*Vwg0Tyw$qUZK^}) zOR9dVDXJPNhQdY_GiuSs(LkOo6DK>PAGeo#;m(_JjqvHEkC5pVQH1H;iluk%&t?m| z`%2?1nvAXqo@3`cJ4t^Oai+O&RIBWR{DDK05T08!Xq__uvXitGYhM+nPz6 zap^wWwb^xW6J>+)_Oz|{`WE)J3AN%#R}%WR)b#z!%id;9)l*;U7h|0PXZ6vwZnf?h zJo}_ew*Mt;=d z8B184H1fZ?H{P=yvRwCQ`_X~-2QMn`vGIlKO~X{2k@@KB(hp`OvppNx8!u|EF4Y@g zO|DsxeIrnoATWs1~-DkfS%jxer-VZlSItL7p#T;v+lsm`3 zQ5(>?qwQFt=-h@Kn|j>Rx0wC8y1_QUB0yzXeLcPp9g2R`(H!eJBt1ARQ6P~d-W-$A z{$%=EhwI^oFUo#riWjsIIWKp?lINw?KX&YLu4d56j9!oQFIwO`%-nwd+BniU>+RUv zi08TD_I{dvlM8_Z>1TV-ipbwTy0I0#otjqh%2uN`mB{T0!Aza#T8*#-ZJ!+y%bljib0 zzLJM_hgM6|*?bT!!HgpLlEb0hVVlCbt)+*R-%0K-&b;Y;P-lzlYF%^eUrd$1I8jh9wf}b8 zdEWZd%z(H3YF>WiL~*_RcF^>aQC(*jsxLxj2dO6XX3xlHu_G#8k!-uuiVFKh%K7FBxEf zclWS&bpfDoQRMIAe~AeGOIRyFOAjyv;6xsdAUf%IV%-V80FnNGR}4M`fnRyRe{I%9Z^zPds-3YJN!o)P-UWOClJ@9LgMh>V-h9) zC0Fa;fB&OSeBALi5EuYQLSX-Y0pchW0tMIrKQSasoT!sX7vS;>gGnNYoBAh)kQ5`P z@Fxa?i4oWJFHDlOzyHFdNU#4-3?U&&6gPija2SjzsQ!(i{xdH^LY!DSfBGS${yP>S zCGnqmk+9$MAh=`go$&78|2NUI_a*Kr5`gNux)LjhR3*gC#kknG63gkwvkI}GWNONk}*n2I1jR)l!4} EA8FpvY5)KL literal 0 HcmV?d00001 diff --git a/MinimedKitUI/MinimedKitUI.xcassets/5xx Blue.imageset/Contents.json b/MinimedKitUI/MinimedKitUI.xcassets/5xx Blue.imageset/Contents.json new file mode 100644 index 000000000..bbde5d76f --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.xcassets/5xx Blue.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "5xx Blue.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MinimedKitUI/MinimedKitUI.xcassets/5xx Clear.imageset/5xx Clear.pdf b/MinimedKitUI/MinimedKitUI.xcassets/5xx Clear.imageset/5xx Clear.pdf new file mode 100644 index 0000000000000000000000000000000000000000..729e073d9929e6f34a3eb5f03622617231ab9e5b GIT binary patch literal 5266 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 WhbJjqetsmlw73ia1X9se1^f?R*D;j< literal 0 HcmV?d00001 diff --git a/MinimedKitUI/MinimedKitUI.xcassets/5xx Clear.imageset/Contents.json b/MinimedKitUI/MinimedKitUI.xcassets/5xx Clear.imageset/Contents.json new file mode 100644 index 000000000..38f640272 --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.xcassets/5xx Clear.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "5xx Clear.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MinimedKitUI/MinimedKitUI.xcassets/5xx Outline.imageset/5xx Outline.pdf b/MinimedKitUI/MinimedKitUI.xcassets/5xx Outline.imageset/5xx Outline.pdf new file mode 100644 index 0000000000000000000000000000000000000000..98c7454802c7e797c5b251892749f7a60b02d8a6 GIT binary patch literal 4941 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 NVtmw*)HBux{~z{A&$R#m literal 0 HcmV?d00001 diff --git a/MinimedKitUI/MinimedKitUI.xcassets/5xx Purple.imageset/Contents.json b/MinimedKitUI/MinimedKitUI.xcassets/5xx Purple.imageset/Contents.json new file mode 100644 index 000000000..f61c02d21 --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.xcassets/5xx Purple.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "5xx Purple.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MinimedKitUI/MinimedKitUI.xcassets/5xx Small Blue.imageset/5xx Small Blue.pdf b/MinimedKitUI/MinimedKitUI.xcassets/5xx Small Blue.imageset/5xx Small Blue.pdf new file mode 100644 index 0000000000000000000000000000000000000000..bf39cbf9abea44e1893c4c01ace1b34fd502c12f GIT binary patch literal 4513 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 literal 0 HcmV?d00001 diff --git a/MinimedKitUI/MinimedKitUI.xcassets/5xx Small Blue.imageset/Contents.json b/MinimedKitUI/MinimedKitUI.xcassets/5xx Small Blue.imageset/Contents.json new file mode 100644 index 000000000..614bfff56 --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.xcassets/5xx Small Blue.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "5xx Small Blue.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MinimedKitUI/MinimedKitUI.xcassets/5xx Small Clear.imageset/5xx Small Clear.pdf b/MinimedKitUI/MinimedKitUI.xcassets/5xx Small Clear.imageset/5xx Small Clear.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3bc6bffa7f6fb3e103253e90e504d7e8d0fc25ff GIT binary patch literal 5177 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 literal 0 HcmV?d00001 diff --git a/MinimedKitUI/MinimedKitUI.xcassets/5xx Small Clear.imageset/Contents.json b/MinimedKitUI/MinimedKitUI.xcassets/5xx Small Clear.imageset/Contents.json new file mode 100644 index 000000000..5de7a81c1 --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.xcassets/5xx Small Clear.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "5xx Small Clear.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MinimedKitUI/MinimedKitUI.xcassets/5xx Small Outline.imageset/5xx Small Outline.pdf b/MinimedKitUI/MinimedKitUI.xcassets/5xx Small Outline.imageset/5xx Small Outline.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c66a87458a319603fdb206365b716f84c259bdd4 GIT binary patch literal 4808 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 kNHHW@3M@%h`1D(ikDYeONHux0Nqn!r~m)} literal 0 HcmV?d00001 diff --git a/MinimedKitUI/MinimedKitUI.xcassets/5xx Small Outline.imageset/Contents.json b/MinimedKitUI/MinimedKitUI.xcassets/5xx Small Outline.imageset/Contents.json new file mode 100644 index 000000000..51fcb1b73 --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.xcassets/5xx Small Outline.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "5xx Small Outline.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template", + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/MinimedKitUI/MinimedKitUI.xcassets/5xx Small Purple.imageset/5xx Small Purple.pdf b/MinimedKitUI/MinimedKitUI.xcassets/5xx Small Purple.imageset/5xx Small Purple.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d4d725fc415d6f1e4161926a44d61542827abd31 GIT binary patch literal 4511 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 literal 0 HcmV?d00001 diff --git a/MinimedKitUI/MinimedKitUI.xcassets/5xx Small Smoke.imageset/Contents.json b/MinimedKitUI/MinimedKitUI.xcassets/5xx Small Smoke.imageset/Contents.json new file mode 100644 index 000000000..0b6fe5c06 --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.xcassets/5xx Small Smoke.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "5xx Small Smoke.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MinimedKitUI/MinimedKitUI.xcassets/5xx Smoke.imageset/5xx Smoke.pdf b/MinimedKitUI/MinimedKitUI.xcassets/5xx Smoke.imageset/5xx Smoke.pdf new file mode 100644 index 0000000000000000000000000000000000000000..19819d2f7da07c04441058e098ba3aba39a8f5c2 GIT binary patch literal 4578 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 I^fkf%2Oz`HDgXcg literal 0 HcmV?d00001 diff --git a/MinimedKitUI/MinimedKitUI.xcassets/5xx Smoke.imageset/Contents.json b/MinimedKitUI/MinimedKitUI.xcassets/5xx Smoke.imageset/Contents.json new file mode 100644 index 000000000..9f0dcfcfe --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.xcassets/5xx Smoke.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "5xx Smoke.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MinimedKitUI/MinimedKitUI.xcassets/7xx Blue.imageset/7xx Blue.pdf b/MinimedKitUI/MinimedKitUI.xcassets/7xx Blue.imageset/7xx Blue.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ec7130208f7f89a123614a233a14834042e24857 GIT binary patch literal 4559 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 literal 0 HcmV?d00001 diff --git a/MinimedKitUI/MinimedKitUI.xcassets/7xx Blue.imageset/Contents.json b/MinimedKitUI/MinimedKitUI.xcassets/7xx Blue.imageset/Contents.json new file mode 100644 index 000000000..58550d002 --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.xcassets/7xx Blue.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "7xx Blue.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MinimedKitUI/MinimedKitUI.xcassets/7xx Clear.imageset/7xx Clear.pdf b/MinimedKitUI/MinimedKitUI.xcassets/7xx Clear.imageset/7xx Clear.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8076474d4c0b67147ab24c446584686a694fc49d GIT binary patch literal 5167 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 atNaW|S2Q79e*7eumc((R0eJU literal 0 HcmV?d00001 diff --git a/MinimedKitUI/MinimedKitUI.xcassets/7xx Clear.imageset/Contents.json b/MinimedKitUI/MinimedKitUI.xcassets/7xx Clear.imageset/Contents.json new file mode 100644 index 000000000..a4c179442 --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.xcassets/7xx Clear.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "7xx Clear.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MinimedKitUI/MinimedKitUI.xcassets/7xx Outline.imageset/7xx Outline.pdf b/MinimedKitUI/MinimedKitUI.xcassets/7xx Outline.imageset/7xx Outline.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9733fc76f4c3625f6b0889e674ec8c930d74eb4b GIT binary patch literal 4920 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 literal 0 HcmV?d00001 diff --git a/MinimedKitUI/MinimedKitUI.xcassets/7xx Outline.imageset/Contents.json b/MinimedKitUI/MinimedKitUI.xcassets/7xx Outline.imageset/Contents.json new file mode 100644 index 000000000..6d85bf062 --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.xcassets/7xx Outline.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "7xx Outline.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template", + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/MinimedKitUI/MinimedKitUI.xcassets/7xx Purple.imageset/7xx Purple.pdf b/MinimedKitUI/MinimedKitUI.xcassets/7xx Purple.imageset/7xx Purple.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0ce7433e90b53f1256adc264e0d54cbb131736d6 GIT binary patch literal 4555 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 literal 0 HcmV?d00001 diff --git a/MinimedKitUI/MinimedKitUI.xcassets/7xx Purple.imageset/Contents.json b/MinimedKitUI/MinimedKitUI.xcassets/7xx Purple.imageset/Contents.json new file mode 100644 index 000000000..812786407 --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.xcassets/7xx Purple.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "7xx Purple.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Blue.imageset/7xx Small Blue.pdf b/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Blue.imageset/7xx Small Blue.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ea29cab18745a7b555f1830c8401b554681e26e6 GIT binary patch literal 4496 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 Z`A$e@5}7XFUJ?R|lmhedDPvIJ{{VAJq#*zR literal 0 HcmV?d00001 diff --git a/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Blue.imageset/Contents.json b/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Blue.imageset/Contents.json new file mode 100644 index 000000000..cedc61779 --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Blue.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "7xx Small Blue.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Clear.imageset/7xx Small Clear.pdf b/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Clear.imageset/7xx Small Clear.pdf new file mode 100644 index 0000000000000000000000000000000000000000..41cc88bd386d677f5bdb6369b0fedf65888b95df GIT binary patch literal 5090 zcmai2cRbbK|2J;ok|_O@3E>`hEL+`{Vn5ydU>{?(;RydOcp}`8onxN-82yQ8-Ybd1`HHA$L9fLvsrd z0fK;>%$W|vUv=2#?Z>^Ar+6j2!y?7I~8uw@`u9?bM!Wocf9? zI&T|cbh5QADVCs?X@68k>NUn+e3giHP)GW8%8tME_B?ldoSCs>PS9d`892badF4XO z(~sBlmu$v`4h%P{Kk0;{L!DF-d-BNUS+#P zp|GMI9@ukQYICXRHD1eyg+W%;-BrX6-bPXAbT3?a@~dvO!v)wmpDVIyTnP!mSJU)# z0A}O-dDqV(sTXI%s@H4=CzpenS+iLAqT`OaU45eXCR_H&GCS+OI`RD&O+%bi(>vO- z789unoh>5c^O*$xz}Jx_#u+6~h_BOxS??{o^7v)u+Zz&Q-5&r(UDJdU-uaw#gR`|n0okl9S;p0((0q}4*6=( zmcyK@dhXtVQgH5>HSf$QHo}$KnY(>l>jOxlhlzaGyE49Yt%dkpy-@m5WJHZ!f1yP3 zO7{WF8Aj#KsMN7&!p|umkr~04S=Q<|BJ2tH6@@CnT+V{Da=~4ABzsN*Q*n10 znlYSjQuTIOdQ)%ot+{Y6sV!cQ#*EA@^&<0h4dyS|UsjZuras&3Ic^b77z~E^WEHHH zuyHw5F|cx;e0YD8-KrYmg3Q>dJzbR((IxFVGTReu*m`30vD3azpXXX$HP6SsWPLB# z;LB%`51XpWEJuwm>0Rw(*WfrK(s`?A``CM7LZmItkt8(d5&r#YyLDDwPa6C8>MX_f z6>}JQk&Vy2*OokN?|YnHAcg~VMm$-4KA7Fw?2?$_y*@aiSNiGo^HG=+$!W6}d6Y(AX1%w)xQa$zM2aW{ zH]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 literal 0 HcmV?d00001 diff --git a/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Clear.imageset/Contents.json b/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Clear.imageset/Contents.json new file mode 100644 index 000000000..15058ebca --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Clear.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "7xx Small Clear.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Outline.imageset/7xx Small Outline.pdf b/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Outline.imageset/7xx Small Outline.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a5439cd58de2d9a4d4942c945e69162915c14ae7 GIT binary patch literal 4788 zcmai&cT`i`5{D^KASj?9NKqq~1nCJ0O{E412uMdjS`tEsUMZzQCSEk3p;X2$ae=c5vPd5;w^C?85y7pk$^)x z0zD`r4CEhhNt~$J5%6GOQi{E#eR-8WKzf&wnwp`6(;^00x61z_+nV*I|C6Kv6`t0- zj5*}DSVmi8^IIlD9LmxwzNn8|_{7{369;y4~@vV%oR8rDWEo%6;cU{3nYUObrzyQ+VHtBzDfU>nN>KyAl*lZ~{Ryq8@kEi=(Vjo`AN;@`8Ag#Br>wQ1dq7O`~ zum~W zX(DA0%nns&m5y$6zE}~<{e%mgrbF?B1uN5hPt5>AJz6BUfl8T}nP;Bem1Pd<4iUv> z%z&Xfa@;ENrk(<7w>GCukg^pot1(c_6L+Q-ai}`yT6yq9?`Z3LKzTz|FXe~U0;C1) z6zx3Z181Bc>zc$2kk8`%zTPK#X0c}tM&TvY2_Y;^zRXbmr_Lt4${Ku@ikkyXiErBY zg4b?A2A$8faWdK6>x(3w%X`Kl*^qNpM|i+F`I8nt=OTB26kiD3d~*Of@zMww5UFY= za-J9Xu_k4o?;bo=RQA}dWG${|AW?22b67`LhIB6NRVxQ;_0d2ID-m~xrrgYx;8#JO z4R=o}QVr_Enx9LSF)m4ezobH&%BDVQ} zm;13N%T(y}UbIS%xf0)>o#+HDH~0bwp{mM`on0|^&32y1ik`8)0I$7)pb})?@DZ#Z z)#7t3IhR0aZw{-)*Z1~M2g #$J^M4eB<2uvJ%5&A&#dy=2t?r5~~*Pib6^WHQe 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 N2^bIzR?<`k{s(FiPxk-- literal 0 HcmV?d00001 diff --git a/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Outline.imageset/Contents.json b/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Outline.imageset/Contents.json new file mode 100644 index 000000000..f72a3b339 --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Outline.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "7xx Small Outline.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template", + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Purple.imageset/7xx Small Purple.pdf b/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Purple.imageset/7xx Small Purple.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3357082d1df8a9cac2f423e313272d2c1b5ac775 GIT binary patch literal 4494 zcmai22{@GN`$n=1NfD9i%dw;|t7T61eM0s!vdu7dMl)k6$&w`+*&CE)kTpw(vV|;J z;%AaA3Q0q@5K$!mnL7PX=bYbl{l06i`QEvo=Y8JqeZTv;uKONIQyo1ys5~4b*-rmR zUnpG5dEVXuLI4l|kM#hlr~qIioR2HX4Nzb}<^WjF-HU`HFz#L$5>5x_gm=aPYHA=N ziGag+g92H-Em1yVP~OLzrvv%;(J8fA#4ezL;%cGs^*Iv8d22;E3;xa0OI(wt zM@R3)<-=;}?{BkmQYpmsqrPvw)@R5X)>VEcmc(Wli2w4+ee-!VE&)=qMqgL7n@;E_ z@#@-jsoZJ5@xV(^CCFfWdFX9;xcgO%T%|6z@Gz_5hhW)^rvB+OTXm(JtjgP;(vL0V ziv$-&?^h~V9jQ1LuHprD0-aY*%oNZrBVy9F=%t|i$xrNj!EM)wK1hg)uTRKFS3c*P;$DNnuy zhRFEx_y#tInSE4)Mx~nONRd{D=qQVv8w(vBj!pay+FK>v8|IHW_pJ<$Qd-BAcdVtK z89J=XDclXwi%T=xJiE*7!e6`i;@*8XfiZ5?69QDBB7r!olp4yTYz1EH*pn4ede8Z7 zc`?W!Nyu44NB&2>>ETx67Io6T&e2J`v^f+W-?6&v;uy8k#-Vbxz2s_Rf5H}-zr$o9 z#&4_v5+rj&w}UUj$%qp7!STYhNwv6r*}~2%zpoFeonxkJ4|89df+tpGLWhw1VALjR z zHr@+Qu<*q=;Q(eEX%nG<(w_wYux=np--5(wq37>B6(QxXvsX{>fXsPk%O|Y*(c(_Jf;`v5u_N3c z`As`o%ye|=<77|ne!9w3WIWX|~t`Q4FFx{bdR*LEs1Je~0`4IDw zjfE?v9r>8Rck>IPDauZM~ZJ z7DPC-0)JbVRTAx;?v}VzCbqPM9-eXg(mXnO?3%@nYS)!*t5vB*T9zg`3q9$zcpuy- z#Ihk_bLVJPQ>qn9wKs0q{U3gU% z?cerD_^4lD3tqU$4+V8KJ$5TgtRTk2u6&!_I?iJo>oaAfDQ+>d!5i;Pkj#}8$(xMu zYGFH=z)8vhA;RP#Y_g8~#6sb|dnN#uh)@ImJ-7GB8?d=+u>YZ{_L2pp34O`xf8E2E zWiaf@bM|xLioP7S>=&Nw^X1_U)z<(;wHQKJC&Jvh!dLhYt-bI5xk)N0`4Qxk&A;rm;NE7+?inm{39A;%`;k9RanCve-adxq~n zaT}2ElCb0#<(lQ%i8#=TFbgX(A&E!vUv9U>$~?IBQu8rNOzK>+ASy~i*jz#;y*kVi z7G?De+_Pt7DBCxs=|95gA`n5%ptdGCa% z*1)~XFKVletA8KEjX{p;E9GwwB+orvKmNXPof{{KyGTDt7o&^PtDc#2v_c#|!_7tR zk(0>{`kp?IHQnI9eesAd8mifY^QaHG00XKITg8mdB^IdDZ!3(G1ZhQ4vuqQ3|3%K_tT` zqdSA1F^lM|cC+Dm$ZkWonSE#vNlpLIYw03cbrVS~D_<&<>sQMkFI6pbDyp(}%{y1s zCt#N(e^E)Z#HK+D7sYz=m(Fk7aonPrz{=Qry&UkrKnZn0Bh_D;S@7SXL}I>EFB*d?v%La$Kn4Tmx-`Z$o@rY8%R_8XXwj$hY~D z#rf*+g9uKeZitwP^VM70gZ1G_UZkG`xEtVcBT|2&x+D`>~ByiE+k&4 zs7czyE_*B&s{O7OqZX$o(B$7#8Vvr7*KEXcfIJ+zZoZFC={UAt^ZVaNZ(jDNSC5(NU@ehSH06C+mL|*RiWcY4h2d0 z6N)!qj2lKzFTMp$e~^dU-mY34BRr%R_t44{99qzqP8~aP{OBbAZj3-{G2N(q-Jvdk z&OVad5WSr=+i`j}Zq@EH?rS1DCE|~WejQ4?U5pc|9CZja&1Rzc@QvRe4j;qb6{jSm zbq7dNc+T{N&>T8R_2T#7T z$l-F^S9RwC>{{xlJ~b`GdjsAEqbognJ#n}rlRmK%gJwBql}(OrRm(FST6J1xQ;l+c z7x}!NdL8mw8h5EG^LRxOx9|Ui?Rgvf)kgiQr&oWK#r9VAdXX9~}&`^>I<0=fFO z^YiiLEMAq-%dx>FbJ9E68;_pb#M)4YUk}GT%2#v`G76fU3mwQj+ILh={m$;yb@E1f zM%6P{Lt0|rp}TjG*#Xx+YIQ`e-i#5B{`~?;t-ku*i_G%M@`;`>N`?Ju9ijMDM5H_rK1?cAO&yVbNecy`Nf8$7X5A56cs zn|Wlk+D zKPQIQhW^+FSes$7NsMRGVM_S#H5q=~81MY+@4w7RAOYtBVw?>E1o{69P*hNWD*!IQ zpBNme%&5)00H2>2LB*N(jce{T*X$;J?g;G2Y-m@|0o!r5=Rgo&J%BgfaZp zKQX0$tqWIFW>~ww=fRa>j3fRhrp#d2KQJVM!Iz&HiGXqU!V$jz$zkDsg>j|`0BnxO zGZ@5V3FB~4J}!6$oqmjU7=%($!a@;>E{ZT590|i9p$ZC$P$eu90fWO_kXWR$k{alL ar~Du!k;I_O_m_l#C@6s>C3Q{oK>r7DaH?Ve literal 0 HcmV?d00001 diff --git a/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Purple.imageset/Contents.json b/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Purple.imageset/Contents.json new file mode 100644 index 000000000..b1b91d440 --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Purple.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "7xx Small Purple.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Smoke.imageset/7xx Small Smoke.pdf b/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Smoke.imageset/7xx Small Smoke.pdf new file mode 100644 index 0000000000000000000000000000000000000000..cd6d4b56331c78a2c9c340d9dc4ecb262af356e9 GIT binary patch literal 4495 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 c_`g$r5z+%sqRY=iffG0DrNfXaE2J literal 0 HcmV?d00001 diff --git a/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Smoke.imageset/Contents.json b/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Smoke.imageset/Contents.json new file mode 100644 index 000000000..af301d6d8 --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.xcassets/7xx Small Smoke.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "7xx Small Smoke.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MinimedKitUI/MinimedKitUI.xcassets/7xx Smoke.imageset/7xx Smoke.pdf b/MinimedKitUI/MinimedKitUI.xcassets/7xx Smoke.imageset/7xx Smoke.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4c22c87599fc7dc70bdf754aedd50b5f0e06af3d GIT binary patch literal 4551 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 ZoBV7@Pb|J&eiR7~#TSX6UlpZB{T~)4yp;d| literal 0 HcmV?d00001 diff --git a/MinimedKitUI/MinimedKitUI.xcassets/7xx Smoke.imageset/Contents.json b/MinimedKitUI/MinimedKitUI.xcassets/7xx Smoke.imageset/Contents.json new file mode 100644 index 000000000..38c272c21 --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.xcassets/7xx Smoke.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "7xx Smoke.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MinimedKitUI/MinimedKitUI.xcassets/Contents.json b/MinimedKitUI/MinimedKitUI.xcassets/Contents.json new file mode 100644 index 000000000..da4a164c9 --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MinimedKitUI/MinimedKitUI.xcassets/Pump ID Diagram.imageset/Contents.json b/MinimedKitUI/MinimedKitUI.xcassets/Pump ID Diagram.imageset/Contents.json new file mode 100644 index 000000000..9f62caa6d --- /dev/null +++ b/MinimedKitUI/MinimedKitUI.xcassets/Pump ID Diagram.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Pump ID Diagram.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/MinimedKitUI/MinimedKitUI.xcassets/Pump ID Diagram.imageset/Pump ID Diagram.pdf b/MinimedKitUI/MinimedKitUI.xcassets/Pump ID Diagram.imageset/Pump ID Diagram.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6273873e893f1812a6f1b1a81ed6f6c34d2f7c71 GIT binary patch literal 36344 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 (UIViewController & PumpManagerSetupViewController) { + return MinimedPumpManagerSetupViewController.instantiateFromStoryboard() + } + + public func settingsViewController() -> UIViewController { + return MinimedPumpSettingsViewController(pumpManager: self) + } + + public var smallImage: UIImage? { + return state.smallPumpImage + } +} + + +// MARK: - DeliveryLimitSettingsTableViewControllerSyncSource +extension MinimedPumpManager { + public func syncDeliveryLimitSettings(for viewController: DeliveryLimitSettingsTableViewController, completion: @escaping (DeliveryLimitSettingsResult) -> Void) { + pumpOps.runSession(withName: "Save Settings", using: rileyLinkManager.firstConnectedDevice) { (session) in + guard let session = session else { + completion(.failure(PumpManagerError.connection(nil))) + return + } + + do { + if let maxBasalRate = viewController.maximumBasalRatePerHour { + try session.setMaxBasalRate(unitsPerHour: maxBasalRate) + } + + if let maxBolus = viewController.maximumBolus { + try session.setMaxBolus(units: maxBolus) + } + + let settings = try session.getSettings() + completion(.success(maximumBasalRatePerHour: settings.maxBasal, maximumBolus: settings.maxBolus)) + } catch let error { + self.log.error("Save delivery limit settings failed: %{public}@", String(describing: error)) + completion(.failure(error)) + } + } + } + + public func syncButtonTitle(for viewController: DeliveryLimitSettingsTableViewController) -> String { + return NSLocalizedString("Save to Pump…", comment: "Title of button to save delivery limit settings to pump") + } + + public func syncButtonDetailText(for viewController: DeliveryLimitSettingsTableViewController) -> String? { + return nil + } + + public func deliveryLimitSettingsTableViewControllerIsReadOnly(_ viewController: DeliveryLimitSettingsTableViewController) -> Bool { + return false + } +} + + +// MARK: - SingleValueScheduleTableViewControllerSyncSource +extension MinimedPumpManager { + public func syncScheduleValues(for viewController: SingleValueScheduleTableViewController, completion: @escaping (RepeatingScheduleValueResult) -> Void) { + pumpOps.runSession(withName: "Save Basal Profile", using: rileyLinkManager.firstConnectedDevice) { (session) in + guard let session = session else { + completion(.failure(PumpManagerError.connection(nil))) + return + } + + do { + let newSchedule = BasalSchedule(repeatingScheduleValues: viewController.scheduleItems) + try session.setBasalSchedule(newSchedule, for: .standard) + + completion(.success(scheduleItems: viewController.scheduleItems, timeZone: session.pump.timeZone)) + } catch let error { + self.log.error("Save basal profile failed: %{public}@", String(describing: error)) + completion(.failure(error)) + } + } + } + + public func syncButtonTitle(for viewController: SingleValueScheduleTableViewController) -> String { + return NSLocalizedString("Save to Pump…", comment: "Title of button to save basal profile to pump") + } + + public func syncButtonDetailText(for viewController: SingleValueScheduleTableViewController) -> String? { + return nil + } + + public func singleValueScheduleTableViewControllerIsReadOnly(_ viewController: SingleValueScheduleTableViewController) -> Bool { + return false + } +} diff --git a/MinimedKitUI/MinimedPumpSettingsViewController.swift b/MinimedKitUI/MinimedPumpSettingsViewController.swift new file mode 100644 index 000000000..95996d93a --- /dev/null +++ b/MinimedKitUI/MinimedPumpSettingsViewController.swift @@ -0,0 +1,281 @@ +// +// MinimedPumpSettingsViewController.swift +// Loop +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + +import UIKit +import LoopKitUI +import MinimedKit +import RileyLinkKitUI + + +class MinimedPumpSettingsViewController: RileyLinkSettingsViewController { + + let pumpManager: MinimedPumpManager + + init(pumpManager: MinimedPumpManager) { + self.pumpManager = pumpManager + super.init(rileyLinkPumpManager: pumpManager, devicesSectionIndex: Section.rileyLinks.rawValue, style: .grouped) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func viewDidLoad() { + super.viewDidLoad() + + title = NSLocalizedString("Pump Settings", comment: "Title of the pump settings view controller") + + tableView.rowHeight = UITableViewAutomaticDimension + tableView.estimatedRowHeight = 44 + + tableView.sectionHeaderHeight = UITableViewAutomaticDimension + tableView.estimatedSectionHeaderHeight = 55 + + tableView.register(SettingsTableViewCell.self, forCellReuseIdentifier: SettingsTableViewCell.className) + tableView.register(TextButtonTableViewCell.self, forCellReuseIdentifier: TextButtonTableViewCell.className) + + let imageView = UIImageView(image: pumpManager.state.largePumpImage) + imageView.contentMode = .bottom + imageView.frame.size.height += 18 // feels right + tableView.tableHeaderView = imageView + } + + // MARK: - Data Source + + private enum Section: Int { + case info = 0 + case settings + case rileyLinks + case delete + + static let count = 4 + } + + private enum InfoRow: Int { + case pumpID = 0 + case pumpModel + + static let count = 2 + } + + private enum SettingsRow: Int { + case timeZoneOffset = 0 + case batteryChemistry + case preferredInsulinDataSource + + static let count = 3 + } + + // MARK: UITableViewDataSource + + override func numberOfSections(in tableView: UITableView) -> Int { + return Section.count + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + switch Section(rawValue: section)! { + case .info: + return InfoRow.count + case .settings: + return SettingsRow.count + case .rileyLinks: + return super.tableView(tableView, numberOfRowsInSection: section) + case .delete: + return 1 + } + } + + override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + switch Section(rawValue: section)! { + case .info: + return nil + case .settings: + return NSLocalizedString("Configuration", comment: "The title of the configuration section in settings") + case .rileyLinks: + return super.tableView(tableView, titleForHeaderInSection: section) + case .delete: + return " " // Use an empty string for more dramatic spacing + } + } + + override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + switch Section(rawValue: section)! { + case .rileyLinks: + return super.tableView(tableView, viewForHeaderInSection: section) + case .info, .settings, .delete: + return nil + } + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + switch Section(rawValue: indexPath.section)! { + case .info: + switch InfoRow(rawValue: indexPath.row)! { + case .pumpID: + let cell = tableView.dequeueReusableCell(withIdentifier: SettingsTableViewCell.className, for: indexPath) + cell.textLabel?.text = NSLocalizedString("Pump ID", comment: "The title text for the pump ID config value") + cell.detailTextLabel?.text = pumpManager.state.pumpID + return cell + case .pumpModel: + let cell = tableView.dequeueReusableCell(withIdentifier: SettingsTableViewCell.className, for: indexPath) + cell.textLabel?.text = NSLocalizedString("Pump Model", comment: "The title of the cell showing the pump model number") + cell.detailTextLabel?.text = String(describing: pumpManager.state.pumpModel) + return cell + } + case .settings: + let cell = tableView.dequeueReusableCell(withIdentifier: SettingsTableViewCell.className, for: indexPath) + + switch SettingsRow(rawValue: indexPath.row)! { + case .batteryChemistry: + cell.textLabel?.text = NSLocalizedString("Pump Battery Type", comment: "The title text for the battery type value") + cell.detailTextLabel?.text = String(describing: pumpManager.batteryChemistry) + case .preferredInsulinDataSource: + cell.textLabel?.text = NSLocalizedString("Preferred Data Source", comment: "The title text for the preferred insulin data source config") + cell.detailTextLabel?.text = String(describing: pumpManager.preferredInsulinDataSource) + case .timeZoneOffset: + cell.textLabel?.text = NSLocalizedString("Change Time Zone", comment: "The title of the command to change pump time zone") + + let localTimeZone = TimeZone.current + let localTimeZoneName = localTimeZone.abbreviation() ?? localTimeZone.identifier + + let timeZoneDiff = TimeInterval(pumpManager.state.timeZone.secondsFromGMT() - localTimeZone.secondsFromGMT()) + let formatter = DateComponentsFormatter() + formatter.allowedUnits = [.hour, .minute] + let diffString = timeZoneDiff != 0 ? formatter.string(from: abs(timeZoneDiff)) ?? String(abs(timeZoneDiff)) : "" + + cell.detailTextLabel?.text = String(format: NSLocalizedString("%1$@%2$@%3$@", comment: "The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00)"), localTimeZoneName, timeZoneDiff != 0 ? (timeZoneDiff < 0 ? "-" : "+") : "", diffString) + } + + cell.accessoryType = .disclosureIndicator + return cell + case .rileyLinks: + return super.tableView(tableView, cellForRowAt: indexPath) + case .delete: + let cell = tableView.dequeueReusableCell(withIdentifier: TextButtonTableViewCell.className, for: indexPath) as! TextButtonTableViewCell + + cell.textLabel?.text = NSLocalizedString("Delete Pump", comment: "Title text for the button to remove a pump from Loop") + cell.textLabel?.textAlignment = .center + cell.tintColor = .deleteColor + cell.isEnabled = true + return cell + } + } + + override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool { + switch Section(rawValue: indexPath.section)! { + case .info: + return false + case .settings, .rileyLinks, .delete: + return true + } + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let sender = tableView.cellForRow(at: indexPath) + + switch Section(rawValue: indexPath.section)! { + case .info: + break + case .settings: + switch SettingsRow(rawValue: indexPath.row)! { + case .timeZoneOffset: + let vc = CommandResponseViewController.changeTime(ops: pumpManager.pumpOps, rileyLinkManager: pumpManager.rileyLinkManager) + vc.title = sender?.textLabel?.text + + show(vc, sender: indexPath) + case .batteryChemistry: + let vc = RadioSelectionTableViewController.batteryChemistryType(pumpManager.batteryChemistry) + vc.title = sender?.textLabel?.text + vc.delegate = self + + show(vc, sender: sender) + case .preferredInsulinDataSource: + let vc = RadioSelectionTableViewController.insulinDataSource(pumpManager.preferredInsulinDataSource) + vc.title = sender?.textLabel?.text + vc.delegate = self + + show(vc, sender: sender) + } + case .rileyLinks: + let device = devicesDataSource.devices[indexPath.row] + + pumpManager.getStateForDevice(device) { (deviceState, pumpState, pumpSettings, pumpOps) in + DispatchQueue.main.async { + let vc = RileyLinkMinimedDeviceTableViewController( + device: device, + deviceState: deviceState, + pumpSettings: pumpSettings, + pumpState: pumpState, + pumpOps: pumpOps + ) + + self.show(vc, sender: sender) + } + } + case .delete: + let confirmVC = UIAlertController(pumpDeletionHandler: { + self.pumpManager.pumpManagerDelegate?.pumpManagerWillDeactivate(self.pumpManager) + self.navigationController?.popViewController(animated: true) + }) + + present(confirmVC, animated: true) { + tableView.deselectRow(at: indexPath, animated: true) + } + } + } +} + + +extension MinimedPumpSettingsViewController: RadioSelectionTableViewControllerDelegate { + func radioSelectionTableViewControllerDidChangeSelectedIndex(_ controller: RadioSelectionTableViewController) { + guard let indexPath = self.tableView.indexPathForSelectedRow else { + return + } + + switch Section(rawValue: indexPath.section)! { + case .settings: + switch SettingsRow(rawValue: indexPath.row)! { + case .preferredInsulinDataSource: + if let selectedIndex = controller.selectedIndex, let dataSource = InsulinDataSource(rawValue: selectedIndex) { + pumpManager.preferredInsulinDataSource = dataSource + } + case .batteryChemistry: + if let selectedIndex = controller.selectedIndex, let dataSource = MinimedKit.BatteryChemistryType(rawValue: selectedIndex) { + pumpManager.batteryChemistry = dataSource + } + default: + assertionFailure() + } + default: + assertionFailure() + } + + tableView.reloadRows(at: [indexPath], with: .none) + } +} + + +private extension UIAlertController { + convenience init(pumpDeletionHandler handler: @escaping () -> Void) { + self.init( + title: nil, + message: NSLocalizedString("Are you sure you want to delete this pump?", comment: "Confirmation message for deleting a pump"), + preferredStyle: .actionSheet + ) + + addAction(UIAlertAction( + title: NSLocalizedString("Delete Pump", comment: "Button title to delete pump"), + style: .destructive, + handler: { (_) in + handler() + } + )) + + let cancel = NSLocalizedString("Cancel", comment: "The title of the cancel action in an action sheet") + addAction(UIAlertAction(title: cancel, style: .cancel, handler: nil)) + } +} diff --git a/MinimedKitUI/PumpModel.swift b/MinimedKitUI/PumpModel.swift new file mode 100644 index 000000000..24c377baf --- /dev/null +++ b/MinimedKitUI/PumpModel.swift @@ -0,0 +1,62 @@ +// +// PumpModel.swift +// MinimedUI +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + +import UIKit +import MinimedKit + + +extension UIImage { + static func pumpImage(in color: PumpColor?, isLargerModel: Bool, isSmallImage: Bool) -> UIImage { + var nameComponents = [String]() + + nameComponents.append(isLargerModel ? "7xx" : "5xx") + + if isSmallImage { + nameComponents.append("Small") + } + + nameComponents.append({ () -> String in + switch color { + case .blue?: + return "Blue" + case .clear?: + return "Clear" + case .purple?: + return "Purple" + case .smoke?: + return "Smoke" + case .none: + return "Outline" + } + }()) + + let name = nameComponents.joined(separator: " ") + return UIImage(named: name, in: Bundle(for: MinimedPumpSettingsViewController.self), compatibleWith: nil)! + } +} + + +extension PumpModel { + func largeImage(in color: PumpColor?) -> UIImage { + return UIImage.pumpImage(in: color, isLargerModel: reservoirCapacity > 200, isSmallImage: false) + } + + func smallImage(in color: PumpColor?) -> UIImage { + return UIImage.pumpImage(in: color, isLargerModel: reservoirCapacity > 200, isSmallImage: true) + } +} + + +extension MinimedPumpManagerState { + var largePumpImage: UIImage { + return UIImage.pumpImage(in: pumpColor, isLargerModel: pumpModel.reservoirCapacity > 200, isSmallImage: false) + } + + var smallPumpImage: UIImage { + return UIImage.pumpImage(in: pumpColor, isLargerModel: pumpModel.reservoirCapacity > 200, isSmallImage: true) + } +} diff --git a/RileyLinkKitUI/PumpOps.swift b/MinimedKitUI/PumpOps.swift similarity index 96% rename from RileyLinkKitUI/PumpOps.swift rename to MinimedKitUI/PumpOps.swift index bc2a24671..a1b054472 100644 --- a/RileyLinkKitUI/PumpOps.swift +++ b/MinimedKitUI/PumpOps.swift @@ -5,7 +5,7 @@ // Copyright © 2017 Pete Schwamb. All rights reserved. // -import RileyLinkKit +import MinimedKit /// Provide a notification contract that clients can use to inform RileyLink UI of changes to PumpOps.PumpState diff --git a/MinimedKitUI/RadioSelectionTableViewController.swift b/MinimedKitUI/RadioSelectionTableViewController.swift new file mode 100644 index 000000000..754541a8b --- /dev/null +++ b/MinimedKitUI/RadioSelectionTableViewController.swift @@ -0,0 +1,37 @@ +// +// RadioSelectionTableViewController.swift +// Loop +// +// Created by Nate Racklyeft on 8/26/16. +// Copyright © 2016 Nathan Racklyeft. All rights reserved. +// + +import UIKit +import LoopKitUI +import MinimedKit + + +extension RadioSelectionTableViewController: IdentifiableClass { + typealias T = RadioSelectionTableViewController + + static func insulinDataSource(_ value: InsulinDataSource) -> T { + let vc = T() + + vc.selectedIndex = value.rawValue + vc.options = (0..<2).compactMap({ InsulinDataSource(rawValue: $0) }).map { String(describing: $0) } + vc.contextHelp = NSLocalizedString("Insulin delivery can be determined from the pump by either interpreting the event history or comparing the reservoir volume over time. Reading event history allows for a more accurate status graph and uploading up-to-date treatment data to Nightscout, at the cost of faster pump battery drain and the possibility of a higher radio error rate compared to reading only reservoir volume. If the selected source cannot be used for any reason, the system will attempt to fall back to the other option.", comment: "Instructions on selecting an insulin data source") + + return vc + } + + static func batteryChemistryType(_ value: MinimedKit.BatteryChemistryType) -> T { + let vc = T() + + vc.selectedIndex = value.rawValue + vc.options = (0..<2).compactMap({ BatteryChemistryType(rawValue: $0) }).map { String(describing: $0) } + vc.contextHelp = NSLocalizedString("Alkaline and Lithium batteries decay at differing rates. Alkaline tend to have a linear voltage drop over time whereas lithium cell batteries tend to maintain voltage until halfway through their lifespan. Under normal usage in a Non-MySentry compatible Minimed (x22/x15) insulin pump running Loop, Alkaline batteries last approximately 4 to 5 days. Lithium batteries last between 1-2 weeks. This selection will use different battery voltage decay rates for each of the battery chemistry types and alert the user when a battery is approximately 8 to 10 hours from failure.", comment: "Instructions on selecting battery chemistry type") + + return vc + } + +} diff --git a/MinimedKitUI/RileyLinkMinimedDeviceTableViewController.swift b/MinimedKitUI/RileyLinkMinimedDeviceTableViewController.swift new file mode 100644 index 000000000..c207d6afe --- /dev/null +++ b/MinimedKitUI/RileyLinkMinimedDeviceTableViewController.swift @@ -0,0 +1,536 @@ +// +// RileyLinkMinimedDeviceTableViewController.swift +// Naterade +// +// Created by Nathan Racklyeft on 3/5/16. +// Copyright © 2016 Nathan Racklyeft. All rights reserved. +// + +import UIKit +import CoreBluetooth +import LoopKitUI +import MinimedKit +import RileyLinkBLEKit +import RileyLinkKit +import RileyLinkKitUI + +let CellIdentifier = "Cell" + +public class RileyLinkMinimedDeviceTableViewController: UITableViewController { + + public let device: RileyLinkDevice + + private var deviceState: DeviceState + + private let ops: PumpOps? + + private var pumpState: PumpState? { + didSet { + // Update the UI if its visible + guard rssiFetchTimer != nil else { return } + + switch (oldValue, pumpState) { + case (.none, .some): + tableView.insertSections(IndexSet(integer: Section.commands.rawValue), with: .automatic) + case (.some, .none): + tableView.deleteSections(IndexSet(integer: Section.commands.rawValue), with: .automatic) + case (_, let state?): + if let cell = cellForRow(.awake) { + cell.setAwakeUntil(state.awakeUntil, formatter: dateFormatter) + } + + if let cell = cellForRow(.model) { + cell.setPumpModel(state.pumpModel) + } + default: + break + } + } + } + + private let pumpSettings: PumpSettings? + + private var bleRSSI: Int? + + private var firmwareVersion: String? { + didSet { + guard isViewLoaded else { + return + } + + cellForRow(.version)?.detailTextLabel?.text = firmwareVersion + } + } + + private var lastIdle: Date? { + didSet { + guard isViewLoaded else { + return + } + + cellForRow(.idleStatus)?.setDetailDate(lastIdle, formatter: dateFormatter) + } + } + + var rssiFetchTimer: Timer? { + willSet { + rssiFetchTimer?.invalidate() + } + } + + private var appeared = false + + public init(device: RileyLinkDevice, deviceState: DeviceState, pumpSettings: PumpSettings?, pumpState: PumpState?, pumpOps: PumpOps?) { + self.device = device + self.deviceState = deviceState + self.pumpSettings = pumpSettings + self.pumpState = pumpState + self.ops = pumpOps + + super.init(style: .grouped) + + updateDeviceStatus() + } + + required public init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + public override func viewDidLoad() { + super.viewDidLoad() + + title = device.name + + self.observe() + } + + @objc func updateRSSI() { + device.readRSSI() + } + + func updateDeviceStatus() { + device.getStatus { (status) in + DispatchQueue.main.async { + self.lastIdle = status.lastIdle + self.firmwareVersion = status.firmwareDescription + } + } + } + + // References to registered notification center observers + private var notificationObservers: [Any] = [] + + deinit { + for observer in notificationObservers { + NotificationCenter.default.removeObserver(observer) + } + } + + private func observe() { + let center = NotificationCenter.default + let mainQueue = OperationQueue.main + + notificationObservers = [ + center.addObserver(forName: .DeviceNameDidChange, object: device, queue: mainQueue) { [weak self] (note) -> Void in + if let cell = self?.cellForRow(.customName) { + cell.detailTextLabel?.text = self?.device.name + } + + self?.title = self?.device.name + }, + center.addObserver(forName: .DeviceConnectionStateDidChange, object: device, queue: mainQueue) { [weak self] (note) -> Void in + if let cell = self?.cellForRow(.connection) { + cell.detailTextLabel?.text = self?.device.peripheralState.description + } + }, + center.addObserver(forName: .DeviceRSSIDidChange, object: device, queue: mainQueue) { [weak self] (note) -> Void in + self?.bleRSSI = note.userInfo?[RileyLinkDevice.notificationRSSIKey] as? Int + + if let cell = self?.cellForRow(.rssi), let formatter = self?.integerFormatter { + cell.setDetailRSSI(self?.bleRSSI, formatter: formatter) + } + }, + center.addObserver(forName: .DeviceDidStartIdle, object: device, queue: mainQueue) { [weak self] (note) in + self?.updateDeviceStatus() + }, + center.addObserver(forName: .PumpOpsStateDidChange, object: ops, queue: mainQueue) { [weak self] (note) in + if let state = note.userInfo?[PumpOps.notificationPumpStateKey] as? PumpState { + self?.pumpState = state + } + } + ] + } + + public override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + if appeared { + tableView.reloadData() + } + + rssiFetchTimer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(updateRSSI), userInfo: nil, repeats: true) + + appeared = true + + updateRSSI() + } + + public override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + rssiFetchTimer = nil + } + + + // MARK: - Formatters + + private lazy var dateFormatter: DateFormatter = { + let dateFormatter = DateFormatter() + + dateFormatter.dateStyle = .none + dateFormatter.timeStyle = .medium + + return dateFormatter + }() + + private lazy var integerFormatter = NumberFormatter() + + private lazy var measurementFormatter: MeasurementFormatter = { + let formatter = MeasurementFormatter() + + formatter.numberFormatter = decimalFormatter + + return formatter + }() + + private lazy var decimalFormatter: NumberFormatter = { + let decimalFormatter = NumberFormatter() + + decimalFormatter.numberStyle = .decimal + decimalFormatter.minimumSignificantDigits = 5 + + return decimalFormatter + }() + + // MARK: - Table view data source + + private enum Section: Int, CaseCountable { + case device + case pump + case commands + } + + private enum DeviceRow: Int, CaseCountable { + case customName + case version + case rssi + case connection + case idleStatus + } + + private enum PumpRow: Int, CaseCountable { + case id + case model + case awake + } + + private enum CommandRow: Int, CaseCountable { + case tune + case changeTime + case mySentryPair + case dumpHistory + case fetchGlucose + case getPumpModel + case pressDownButton + case readPumpStatus + case readBasalSchedule + case enableLED + case discoverCommands + case getStatistics + } + + private func cellForRow(_ row: DeviceRow) -> UITableViewCell? { + return tableView.cellForRow(at: IndexPath(row: row.rawValue, section: Section.device.rawValue)) + } + + private func cellForRow(_ row: PumpRow) -> UITableViewCell? { + return tableView.cellForRow(at: IndexPath(row: row.rawValue, section: Section.pump.rawValue)) + } + + public override func numberOfSections(in tableView: UITableView) -> Int { + if pumpState == nil { + return Section.count - 1 + } else { + return Section.count + } + } + + public override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + switch Section(rawValue: section)! { + case .device: + return DeviceRow.count + case .pump: + return PumpRow.count + case .commands: + return CommandRow.count + } + } + + public override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell: UITableViewCell + + if let reusableCell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier) { + cell = reusableCell + } else { + cell = UITableViewCell(style: .value1, reuseIdentifier: CellIdentifier) + } + + cell.accessoryType = .none + + switch Section(rawValue: indexPath.section)! { + case .device: + switch DeviceRow(rawValue: indexPath.row)! { + case .customName: + cell.textLabel?.text = NSLocalizedString("Name", comment: "The title of the cell showing device name") + cell.detailTextLabel?.text = device.name + cell.accessoryType = .disclosureIndicator + case .version: + cell.textLabel?.text = NSLocalizedString("Firmware", comment: "The title of the cell showing firmware version") + cell.detailTextLabel?.text = firmwareVersion + case .connection: + cell.textLabel?.text = NSLocalizedString("Connection State", comment: "The title of the cell showing BLE connection state") + cell.detailTextLabel?.text = device.peripheralState.description + case .rssi: + cell.textLabel?.text = NSLocalizedString("Signal Strength", comment: "The title of the cell showing BLE signal strength (RSSI)") + + cell.setDetailRSSI(bleRSSI, formatter: integerFormatter) + case .idleStatus: + cell.textLabel?.text = NSLocalizedString("On Idle", comment: "The title of the cell showing the last idle") + cell.setDetailDate(lastIdle, formatter: dateFormatter) + } + case .pump: + switch PumpRow(rawValue: indexPath.row)! { + case .id: + cell.textLabel?.text = NSLocalizedString("Pump ID", comment: "The title of the cell showing pump ID") + if let pumpID = pumpSettings?.pumpID { + cell.detailTextLabel?.text = pumpID + } else { + cell.detailTextLabel?.text = "–" + } + case .model: + cell.textLabel?.text = NSLocalizedString("Pump Model", comment: "The title of the cell showing the pump model number") + cell.setPumpModel(pumpState?.pumpModel) + case .awake: + cell.setAwakeUntil(pumpState?.awakeUntil, formatter: dateFormatter) + } + case .commands: + cell.accessoryType = .disclosureIndicator + cell.detailTextLabel?.text = nil + + switch CommandRow(rawValue: indexPath.row)! { + case .tune: + switch (deviceState.lastValidFrequency, deviceState.lastTuned) { + case (let frequency?, let date?): + cell.textLabel?.text = measurementFormatter.string(from: frequency) + cell.setDetailDate(date, formatter: dateFormatter) + default: + cell.textLabel?.text = NSLocalizedString("Tune Radio Frequency", comment: "The title of the command to re-tune the radio") + } + + case .changeTime: + cell.textLabel?.text = NSLocalizedString("Change Time", comment: "The title of the command to change pump time") + + let localTimeZone = TimeZone.current + let localTimeZoneName = localTimeZone.abbreviation() ?? localTimeZone.identifier + + if let pumpTimeZone = pumpState?.timeZone { + let timeZoneDiff = TimeInterval(pumpTimeZone.secondsFromGMT() - localTimeZone.secondsFromGMT()) + let formatter = DateComponentsFormatter() + formatter.allowedUnits = [.hour, .minute] + let diffString = timeZoneDiff != 0 ? formatter.string(from: abs(timeZoneDiff)) ?? String(abs(timeZoneDiff)) : "" + + cell.detailTextLabel?.text = String(format: NSLocalizedString("%1$@%2$@%3$@", comment: "The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00)"), localTimeZoneName, timeZoneDiff != 0 ? (timeZoneDiff < 0 ? "-" : "+") : "", diffString) + } else { + cell.detailTextLabel?.text = localTimeZoneName + } + case .mySentryPair: + cell.textLabel?.text = NSLocalizedString("MySentry Pair", comment: "The title of the command to pair with mysentry") + + case .dumpHistory: + cell.textLabel?.text = NSLocalizedString("Fetch Recent History", comment: "The title of the command to fetch recent history") + + case .fetchGlucose: + cell.textLabel?.text = NSLocalizedString("Fetch Enlite Glucose", comment: "The title of the command to fetch recent glucose") + + case .getPumpModel: + cell.textLabel?.text = NSLocalizedString("Get Pump Model", comment: "The title of the command to get pump model") + + case .pressDownButton: + cell.textLabel?.text = NSLocalizedString("Send Button Press", comment: "The title of the command to send a button press") + + case .readPumpStatus: + cell.textLabel?.text = NSLocalizedString("Read Pump Status", comment: "The title of the command to read pump status") + + case .readBasalSchedule: + cell.textLabel?.text = NSLocalizedString("Read Basal Schedule", comment: "The title of the command to read basal schedule") + + case .enableLED: + cell.textLabel?.text = NSLocalizedString("Enable Diagnostic LEDs", comment: "The title of the command to enable diagnostic LEDs") + + case .discoverCommands: + cell.textLabel?.text = NSLocalizedString("Discover Commands", comment: "The title of the command to discover commands") + + case .getStatistics: + cell.textLabel?.text = NSLocalizedString("RileyLink Statistics", comment: "The title of the command to fetch RileyLink statistics") + } + } + + return cell + } + + public override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + switch Section(rawValue: section)! { + case .device: + return NSLocalizedString("Device", comment: "The title of the section describing the device") + case .pump: + return NSLocalizedString("Pump", comment: "The title of the section describing the pump") + case .commands: + return NSLocalizedString("Commands", comment: "The title of the section describing commands") + } + } + + // MARK: - UITableViewDelegate + + public override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool { + switch Section(rawValue: indexPath.section)! { + case .device: + switch DeviceRow(rawValue: indexPath.row)! { + case .customName: + return true + default: + return false + } + case .pump: + return false + case .commands: + return device.peripheralState == .connected + } + } + + public override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + switch Section(rawValue: indexPath.section)! { + case .device: + switch DeviceRow(rawValue: indexPath.row)! { + case .customName: + let vc = TextFieldTableViewController() + if let cell = tableView.cellForRow(at: indexPath) { + vc.title = cell.textLabel?.text + vc.value = device.name + vc.delegate = self + vc.keyboardType = .default + } + + show(vc, sender: indexPath) + default: + break + } + case .commands: + let vc: CommandResponseViewController + + switch CommandRow(rawValue: indexPath.row)! { + case .tune: + vc = .tuneRadio(ops: ops, device: device, current: deviceState.lastValidFrequency, measurementFormatter: measurementFormatter) + case .changeTime: + vc = .changeTime(ops: ops, device: device) + case .mySentryPair: + vc = .mySentryPair(ops: ops, device: device) + case .dumpHistory: + vc = .dumpHistory(ops: ops, device: device) + case .fetchGlucose: + vc = .fetchGlucose(ops: ops, device: device) + case .getPumpModel: + vc = .getPumpModel(ops: ops, device: device) + case .pressDownButton: + vc = .pressDownButton(ops: ops, device: device) + case .readPumpStatus: + vc = .readPumpStatus(ops: ops, device: device, measurementFormatter: measurementFormatter) + case .readBasalSchedule: + vc = .readBasalSchedule(ops: ops, device: device, integerFormatter: integerFormatter) + case .enableLED: + vc = .enableLEDs(ops: ops, device: device) + case .discoverCommands: + vc = .discoverCommands(ops: ops, device: device) + case .getStatistics: + vc = .getStatistics(ops: ops, device: device) + } + + if let cell = tableView.cellForRow(at: indexPath) { + vc.title = cell.textLabel?.text + } + + show(vc, sender: indexPath) + case .pump: + break + } + } +} + + +extension RileyLinkMinimedDeviceTableViewController: TextFieldTableViewControllerDelegate { + public func textFieldTableViewControllerDidReturn(_ controller: TextFieldTableViewController) { + _ = navigationController?.popViewController(animated: true) + } + + public func textFieldTableViewControllerDidEndEditing(_ controller: TextFieldTableViewController) { + if let indexPath = tableView.indexPathForSelectedRow { + switch Section(rawValue: indexPath.section)! { + case .device: + switch DeviceRow(rawValue: indexPath.row)! { + case .customName: + device.setCustomName(controller.value!) + default: + break + } + default: + break + + } + } + } +} + + +private extension UITableViewCell { + func setDetailDate(_ date: Date?, formatter: DateFormatter) { + if let date = date { + detailTextLabel?.text = formatter.string(from: date) + } else { + detailTextLabel?.text = "-" + } + } + + func setDetailRSSI(_ decibles: Int?, formatter: NumberFormatter) { + detailTextLabel?.text = formatter.decibleString(from: decibles) ?? "-" + } + + func setAwakeUntil(_ awakeUntil: Date?, formatter: DateFormatter) { + switch awakeUntil { + case let until? where until.timeIntervalSinceNow < 0: + textLabel?.text = NSLocalizedString("Last Awake", comment: "The title of the cell describing an awake radio") + setDetailDate(until, formatter: formatter) + case let until?: + textLabel?.text = NSLocalizedString("Awake Until", comment: "The title of the cell describing an awake radio") + setDetailDate(until, formatter: formatter) + default: + textLabel?.text = NSLocalizedString("Listening Off", comment: "The title of the cell describing no radio awake data") + detailTextLabel?.text = nil + } + } + + func setPumpModel(_ pumpModel: PumpModel?) { + if let pumpModel = pumpModel { + detailTextLabel?.text = String(describing: pumpModel) + } else { + detailTextLabel?.text = NSLocalizedString("Unknown", comment: "The detail text for an unknown pump model") + } + } +} diff --git a/MinimedKitUI/Setup/MinimedPumpClockSetupViewController.swift b/MinimedKitUI/Setup/MinimedPumpClockSetupViewController.swift new file mode 100644 index 000000000..564aada38 --- /dev/null +++ b/MinimedKitUI/Setup/MinimedPumpClockSetupViewController.swift @@ -0,0 +1,17 @@ +// +// MinimedPumpClockSetupViewController.swift +// Loop +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + +import UIKit +import LoopKitUI + +class MinimedPumpClockSetupViewController: SetupTableViewController { + + override func viewDidLoad() { + super.viewDidLoad() + } + +} diff --git a/MinimedKitUI/Setup/MinimedPumpIDSetupViewController.swift b/MinimedKitUI/Setup/MinimedPumpIDSetupViewController.swift new file mode 100644 index 000000000..6208aa148 --- /dev/null +++ b/MinimedKitUI/Setup/MinimedPumpIDSetupViewController.swift @@ -0,0 +1,439 @@ +// +// MinimedPumpIDSetupViewController.swift +// Loop +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + +import UIKit +import LoopKit +import LoopKitUI +import MinimedKit +import RileyLinkKit + + +class MinimedPumpIDSetupViewController: SetupTableViewController { + + var rileyLinkPumpManager: RileyLinkPumpManager! + + private enum RegionCode: String { + case northAmerica = "NA" + case canada = "CA" + case worldWide = "WW" + + var region: PumpRegion { + switch self { + case .northAmerica, .canada: + return .northAmerica + case .worldWide: + return .worldWide + } + } + } + + private var pumpRegionCode: RegionCode? { + didSet { + regionAndColorPickerCell.regionLabel.text = pumpRegionCode?.region.description + regionAndColorPickerCell.regionLabel.textColor = .darkText + + updateStateForSettings() + } + } + + private var pumpColor: PumpColor? { + didSet { + regionAndColorPickerCell.pumpImageView.image = .pumpImage(in: pumpColor, isLargerModel: true, isSmallImage: true) + + updateStateForSettings() + } + } + + private var pumpID: String? { + get { + return pumpIDTextField.text + } + set { + pumpIDTextField.text = newValue + } + } + + private var pumpOps: PumpOps? + + private var pumpState: PumpState? + + var maxBasalRateUnitsPerHour: Double? + + var maxBolusUnits: Double? + + var basalSchedule: BasalRateSchedule? + + private var isSentrySetUpNeeded: Bool = false + + var pumpManagerState: MinimedPumpManagerState? { + get { + guard let pumpColor = pumpColor, + let pumpID = pumpID, + let pumpModel = pumpState?.pumpModel, + let pumpRegion = pumpRegionCode?.region, + let timeZone = pumpState?.timeZone + else { + return nil + } + + return MinimedPumpManagerState( + pumpColor: pumpColor, + pumpID: pumpID, + pumpModel: pumpModel, + pumpRegion: pumpRegion, + rileyLinkPumpManagerState: self.rileyLinkPumpManager.rileyLinkPumpManagerState, + timeZone: timeZone + ) + } + } + + var pumpManager: MinimedPumpManager? { + guard let pumpManagerState = pumpManagerState else { + return nil + } + + return MinimedPumpManager(state: pumpManagerState, rileyLinkManager: rileyLinkPumpManager.rileyLinkManager) + } + + // MARK: - + + @IBOutlet weak var pumpIDTextField: UITextField! + + @IBOutlet fileprivate weak var regionAndColorPickerCell: RegionAndColorPickerTableViewCell! + + @IBOutlet weak var activityIndicator: SetupIndicatorView! + + @IBOutlet weak var loadingLabel: UILabel! + + override func viewDidLoad() { + super.viewDidLoad() + + regionAndColorPickerCell.pickerView.delegate = self + regionAndColorPickerCell.pickerView.dataSource = self + + continueState = .inputSettings + + NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidHide), name: .UIKeyboardDidHide, object: nil) + } + + override func setEditing(_ editing: Bool, animated: Bool) { + super.setEditing(editing, animated: animated) + } + + // MARK: - UITableViewDelegate + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + guard continueState != .reading else { + return + } + + if let cell = tableView.cellForRow(at: indexPath) as? RegionAndColorPickerTableViewCell { + cell.becomeFirstResponder() + + // Apply initial values to match the picker + if pumpRegionCode == nil { + pumpRegionCode = MinimedPumpIDSetupViewController.regionRows[0] + } + if pumpColor == nil { + pumpColor = MinimedPumpIDSetupViewController.colorRows[0] + } + } + + tableView.deselectRow(at: indexPath, animated: true) + } + + // MARK: - Navigation + + private enum State { + case loadingView + case inputSettings + case readyToRead + case reading + case completed + } + + private var continueState: State = .loadingView { + didSet { + switch continueState { + case .loadingView: + updateStateForSettings() + case .inputSettings: + pumpIDTextField.isEnabled = true + activityIndicator.state = .hidden + footerView.primaryButton.isEnabled = false + footerView.primaryButton.setConnectTitle() + lastError = nil + case .readyToRead: + pumpIDTextField.isEnabled = true + activityIndicator.state = .hidden + footerView.primaryButton.isEnabled = true + footerView.primaryButton.setConnectTitle() + case .reading: + pumpIDTextField.isEnabled = false + activityIndicator.state = .loading + footerView.primaryButton.isEnabled = false + footerView.primaryButton.setConnectTitle() + lastError = nil + case .completed: + pumpOps = nil + pumpIDTextField.isEnabled = true + activityIndicator.state = .completed + footerView.primaryButton.isEnabled = true + footerView.primaryButton.resetTitle() + lastError = nil + } + } + } + + private var lastError: Error? { + didSet { + guard oldValue != nil || lastError != nil else { + return + } + + var errorText = lastError?.localizedDescription + + if let error = lastError as? LocalizedError { + let localizedText = [error.errorDescription, error.failureReason, error.recoverySuggestion].compactMap({ $0 }).joined(separator: ". ") + + if !localizedText.isEmpty { + errorText = localizedText + } + } + + tableView.beginUpdates() + loadingLabel.text = errorText + + let isHidden = (errorText == nil) + loadingLabel.isHidden = isHidden + tableView.endUpdates() + // If we changed the error text, update the continue state + if !isHidden { + updateStateForSettings() + } + } + } + + private func updateStateForSettings() { + let isReadyToRead = pumpRegionCode != nil && pumpColor != nil && pumpID?.count == 6 + + if isReadyToRead { + continueState = .readyToRead + } else { + continueState = .inputSettings + } + } + + private func readPumpState(with settings: PumpSettings) { + continueState = .reading + + let pumpOps = PumpOps(pumpSettings: settings, pumpState: pumpState, delegate: self) + self.pumpOps = pumpOps + pumpOps.runSession(withName: "Pump ID Setup", using: rileyLinkPumpManager.rileyLinkManager.firstConnectedDevice, { (session) in + guard let session = session else { + DispatchQueue.main.async { + self.lastError = PumpManagerError.connection(nil) + } + return + } + + do { + _ = try session.tuneRadio(current: nil) + let model = try session.getPumpModel() + var isSentrySetUpNeeded = false + + // Radio + if model.hasMySentry { + let isSentryEnabled = try session.getOtherDevicesEnabled() + + if isSentryEnabled { + let sentryIDCount = try session.getOtherDevicesIDs().ids.count + + isSentrySetUpNeeded = (sentryIDCount == 0) + } else { + isSentrySetUpNeeded = true + } + } else { + // Pre-sentry models need a remote ID to decrease the radio wake interval + let remoteIDCount = try session.getRemoteControlIDs().ids.count + + if remoteIDCount == 0 { + try session.setRemoteControlID(Data(bytes: [9, 9, 9, 9, 9, 9]), atIndex: 2) + } + + try session.setRemoteControlEnabled(true) + } + + // Settings + let settings = try session.getSettings() + let basalRateSchedule = try session.getBasalRateSchedule(for: .standard) + try session.selectBasalProfile(.standard) + try session.setTimeToNow(in: .current) + + DispatchQueue.main.async { + self.isSentrySetUpNeeded = isSentrySetUpNeeded + self.maxBasalRateUnitsPerHour = settings.maxBasal + self.maxBolusUnits = settings.maxBolus + self.basalSchedule = basalRateSchedule + + if self.pumpState != nil { + self.continueState = .completed + } else { + self.lastError = PumpManagerError.connection(nil) + } + } + } catch let error { + DispatchQueue.main.async { + self.lastError = error + } + } + }) + } + + override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool { + return continueState == .completed + } + + override func continueButtonPressed(_ sender: Any) { + if case .completed = continueState { + if isSentrySetUpNeeded { + performSegue(withIdentifier: "Sentry", sender: sender) + } else { + super.continueButtonPressed(sender) + } + } else if case .readyToRead = continueState, let pumpID = pumpID, let pumpRegion = pumpRegionCode?.region { + readPumpState(with: PumpSettings(pumpID: pumpID, pumpRegion: pumpRegion)) + } + } + + override func cancelButtonPressed(_ sender: Any) { + if regionAndColorPickerCell.isFirstResponder { + regionAndColorPickerCell.resignFirstResponder() + } else if pumpIDTextField.isFirstResponder { + pumpIDTextField.resignFirstResponder() + } else { + super.cancelButtonPressed(sender) + } + } + + @objc func keyboardDidHide() { + regionAndColorPickerCell.resignFirstResponder() + } +} + + +extension MinimedPumpIDSetupViewController: UIPickerViewDelegate, UIPickerViewDataSource { + private static let regionRows: [RegionCode] = [.northAmerica, .canada, .worldWide] + + private static let colorRows: [PumpColor] = [.blue, .clear, .purple, .smoke] + + private enum PickerViewComponent: Int { + case region + case color + + static let count = 2 + } + + func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { + switch PickerViewComponent(rawValue: component)! { + case .region: + return MinimedPumpIDSetupViewController.regionRows[row].rawValue + case .color: + return MinimedPumpIDSetupViewController.colorRows[row].rawValue + } + } + + func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { + switch PickerViewComponent(rawValue: component)! { + case .region: + pumpRegionCode = MinimedPumpIDSetupViewController.regionRows[row] + case .color: + pumpColor = MinimedPumpIDSetupViewController.colorRows[row] + } + } + + func numberOfComponents(in pickerView: UIPickerView) -> Int { + return PickerViewComponent.count + } + + func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { + switch PickerViewComponent(rawValue: component)! { + case .region: + return MinimedPumpIDSetupViewController.regionRows.count + case .color: + return MinimedPumpIDSetupViewController.colorRows.count + } + } +} + + +extension MinimedPumpIDSetupViewController: UITextFieldDelegate { + func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + guard let text = textField.text, let stringRange = Range(range, in: text) else { + updateStateForSettings() + return true + } + + let newText = text.replacingCharacters(in: stringRange, with: string) + + if newText.count >= 6 { + if newText.count == 6 { + textField.text = newText + textField.resignFirstResponder() + } + + updateStateForSettings() + return false + } + + textField.text = newText + updateStateForSettings() + return false + } + + func textFieldShouldEndEditing(_ textField: UITextField) -> Bool { + return true + } + + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + textField.resignFirstResponder() + return true + } +} + + +extension MinimedPumpIDSetupViewController: PumpOpsDelegate { + func pumpOps(_ pumpOps: PumpOps, didChange state: PumpState) { + DispatchQueue.main.async { + self.pumpState = state + } + } +} + + +class RegionAndColorPickerTableViewCell: UITableViewCell { + override var canBecomeFirstResponder: Bool { + return true + } + + fileprivate private(set) lazy var pickerView = UIPickerView() + + override var inputView: UIView? { + return pickerView + } + + @IBOutlet weak var regionLabel: UILabel! + + @IBOutlet weak var pumpImageView: UIImageView! +} + + +private extension SetupButton { + func setConnectTitle() { + setTitle(NSLocalizedString("Connect", comment: "Button title to connect to pump during setup"), for: .normal) + } +} diff --git a/MinimedKitUI/Setup/MinimedPumpManagerSetupViewController.swift b/MinimedKitUI/Setup/MinimedPumpManagerSetupViewController.swift new file mode 100644 index 000000000..a95c1875c --- /dev/null +++ b/MinimedKitUI/Setup/MinimedPumpManagerSetupViewController.swift @@ -0,0 +1,115 @@ +// +// MinimedPumpSetupViewController.swift +// Loop +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + +import UIKit +import LoopKit +import LoopKitUI +import MinimedKit +import RileyLinkBLEKit +import RileyLinkKit +import RileyLinkKitUI + + +public class MinimedPumpManagerSetupViewController: RileyLinkManagerSetupViewController { + + class func instantiateFromStoryboard() -> MinimedPumpManagerSetupViewController { + return UIStoryboard(name: "MinimedPumpManager", bundle: Bundle(for: MinimedPumpManagerSetupViewController.self)).instantiateInitialViewController() as! MinimedPumpManagerSetupViewController + } + + override public func viewDidLoad() { + super.viewDidLoad() + + view.backgroundColor = .white + navigationBar.shadowImage = UIImage() + } + + private(set) var pumpManager: MinimedPumpManager? + + /* + 1. RileyLink + - RileyLinkPumpManagerState + + 2. Pump + - PumpSettings + - PumpColor + -- Submit -- + - PumpOps + - PumpState + + 3. (Optional) Connect Devices + + 4. Time + + 5. Basal Rates & Delivery Limits + + 6. Pump Setup Complete + */ + + override public func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) { + super.navigationController(navigationController, willShow: viewController, animated: animated) + + // Read state values + let viewControllers = navigationController.viewControllers + let count = navigationController.viewControllers.count + + if count >= 2 { + switch viewControllers[count - 2] { + case let vc as MinimedPumpIDSetupViewController: + pumpManager = vc.pumpManager + maxBasalRateUnitsPerHour = vc.maxBasalRateUnitsPerHour + maxBolusUnits = vc.maxBolusUnits + basalSchedule = vc.basalSchedule + default: + break + } + } + + // Set state values + switch viewController { + case let vc as MinimedPumpIDSetupViewController: + vc.rileyLinkPumpManager = rileyLinkPumpManager + case let vc as MinimedPumpSentrySetupViewController: + vc.pumpManager = pumpManager + case is MinimedPumpClockSetupViewController: + break + case let vc as MinimedPumpSettingsSetupViewController: + vc.pumpManager = pumpManager + case let vc as MinimedPumpSetupCompleteViewController: + vc.pumpImage = pumpManager?.state.largePumpImage + default: + break + } + + // Adjust the appearance for the main setup view controllers only + if viewController is SetupTableViewController { + navigationBar.isTranslucent = false + navigationBar.shadowImage = UIImage() + } else { + navigationBar.isTranslucent = true + navigationBar.shadowImage = nil + viewController.navigationItem.largeTitleDisplayMode = .never + } + } + + public func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) { + + // Adjust the appearance for the main setup view controllers only + if viewController is SetupTableViewController { + navigationBar.isTranslucent = false + navigationBar.shadowImage = UIImage() + } else { + navigationBar.isTranslucent = true + navigationBar.shadowImage = nil + } + } + + func completeSetup() { + if let pumpManager = pumpManager { + setupDelegate?.pumpManagerSetupViewController(self, didSetUpPumpManager: pumpManager) + } + } +} diff --git a/MinimedKitUI/Setup/MinimedPumpSentrySetupViewController.swift b/MinimedKitUI/Setup/MinimedPumpSentrySetupViewController.swift new file mode 100644 index 000000000..acb11ddde --- /dev/null +++ b/MinimedKitUI/Setup/MinimedPumpSentrySetupViewController.swift @@ -0,0 +1,175 @@ +// +// MinimedPumpSentrySetupViewController.swift +// Loop +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + +import UIKit +import LoopKit +import LoopKitUI +import MinimedKit + + +class MinimedPumpSentrySetupViewController: SetupTableViewController { + + var pumpManager: MinimedPumpManager? + + @IBOutlet weak var activityIndicator: SetupIndicatorView! + + @IBOutlet weak var loadingLabel: UILabel! + + override func viewDidLoad() { + super.viewDidLoad() + + lastError = nil + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + if pumpManager == nil { + navigationController?.popViewController(animated: true) + } + + // Select the first row + tableView.selectRow(at: [1, 0], animated: true, scrollPosition: .none) + } + + override func continueButtonPressed(_ sender: Any) { + switch continueState { + case .notStarted: + listenForPairing() + case .listening: + break + case .completed: + super.continueButtonPressed(sender) + } + } + + // MARK: - + + private enum State { + case notStarted + case listening + case completed + } + + private var continueState: State = .notStarted { + didSet { + switch continueState { + case .notStarted: + footerView.primaryButton.isEnabled = true + activityIndicator.state = .hidden + footerView.primaryButton.setTitle(NSLocalizedString("Retry", comment: "Button title to retry sentry setup"), for: .normal) + case .listening: + lastError = nil + activityIndicator.state = .loading + footerView.primaryButton.isEnabled = false + case .completed: + lastError = nil + activityIndicator.state = .completed + footerView.primaryButton.isEnabled = true + footerView.primaryButton.resetTitle() + } + } + } + + private func listenForPairing() { + guard let pumpManager = pumpManager else { + continueState = .notStarted + lastError = PumpManagerError.connection(nil) + return + } + + continueState = .listening + + pumpManager.pumpOps.runSession(withName: "MySentry Pairing", using: pumpManager.rileyLinkManager.firstConnectedDevice) { (session) in + guard let session = session else { + DispatchQueue.main.async { + self.continueState = .notStarted + self.lastError = PumpManagerError.connection(nil) + } + return + } + + let watchdogID = Data(bytes: [0xd0, 0x00, 0x07]) + do { + try session.changeWatchdogMarriageProfile(watchdogID) + DispatchQueue.main.async { + self.continueState = .completed + } + } catch let error { + DispatchQueue.main.async { + self.continueState = .notStarted + self.lastError = error + } + } + } + } + + private var lastError: Error? { + didSet { + guard oldValue != nil || lastError != nil else { + return + } + + var errorText = lastError?.localizedDescription + + if let error = lastError as? LocalizedError { + let localizedText = [error.errorDescription, error.failureReason, error.recoverySuggestion].compactMap({ $0 }).joined(separator: ". ") + + if !localizedText.isEmpty { + errorText = localizedText + } + } + + tableView.beginUpdates() + loadingLabel.text = errorText + + let isHidden = (errorText == nil) + loadingLabel.isHidden = isHidden + tableView.endUpdates() + } + } + +} + + +class PumpMenuItemTableViewCell: UITableViewCell { + override func awakeFromNib() { + super.awakeFromNib() + + updateLabel(selected: false) + } + + private func updateLabel(selected: Bool) { + let font = UIFont(name: "Menlo-Bold", size: 14) ?? UIFont.monospacedDigitSystemFont(ofSize: 14, weight: .medium) + let metrics = UIFontMetrics(forTextStyle: .body) + metrics.scaledFont(for: font) + + let paragraphStyle = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle + paragraphStyle.firstLineHeadIndent = 15 + + let bundle = Bundle(for: type(of: self)) + let textColor = UIColor(named: "Pump Screen Text", in: bundle, compatibleWith: traitCollection)! + let backgroundColor = UIColor(named: "Pump Screen Background", in: bundle, compatibleWith: traitCollection)! + + textLabel?.backgroundColor = backgroundColor + textLabel?.attributedText = NSAttributedString( + string: textLabel?.text ?? "", + attributes: [ + .backgroundColor: selected ? textColor : backgroundColor, + .foregroundColor: selected ? backgroundColor : textColor, + .font: metrics.scaledFont(for: font), + .paragraphStyle: paragraphStyle, + ] + ) + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + updateLabel(selected: selected) + } +} diff --git a/MinimedKitUI/Setup/MinimedPumpSettingsSetupViewController.swift b/MinimedKitUI/Setup/MinimedPumpSettingsSetupViewController.swift new file mode 100644 index 000000000..b6898e0e9 --- /dev/null +++ b/MinimedKitUI/Setup/MinimedPumpSettingsSetupViewController.swift @@ -0,0 +1,177 @@ +// +// MinimedPumpSettingsSetupViewController.swift +// Loop +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + +import UIKit +import HealthKit +import LoopKit +import LoopKitUI +import MinimedKit + +class MinimedPumpSettingsSetupViewController: SetupTableViewController { + + var pumpManager: MinimedPumpManager? + + private var pumpManagerSetupViewController: MinimedPumpManagerSetupViewController? { + return setupViewController as? MinimedPumpManagerSetupViewController + } + + override func viewDidLoad() { + super.viewDidLoad() + + tableView.register(SettingsTableViewCell.self, forCellReuseIdentifier: SettingsTableViewCell.className) + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + if pumpManager == nil { + navigationController?.popViewController(animated: true) + } + } + + fileprivate lazy var quantityFormatter: QuantityFormatter = { + let quantityFormatter = QuantityFormatter() + quantityFormatter.numberFormatter.minimumFractionDigits = 0 + quantityFormatter.numberFormatter.maximumFractionDigits = 3 + + return quantityFormatter + }() + + // MARK: - Table view data source + + private enum Section: Int { + case description + case configuration + + static let count = 2 + } + + private enum ConfigurationRow: Int { + case basalRates + case deliveryLimits + + static let count = 2 + } + + override func numberOfSections(in tableView: UITableView) -> Int { + return Section.count + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + switch Section(rawValue: section)! { + case .description: + return 1 + case .configuration: + return 2 + } + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + switch Section(rawValue: indexPath.section)! { + case .description: + return tableView.dequeueReusableCell(withIdentifier: "DescriptionCell", for: indexPath) + case .configuration: + let cell = tableView.dequeueReusableCell(withIdentifier: SettingsTableViewCell.className, for: indexPath) + + switch ConfigurationRow(rawValue: indexPath.row)! { + case .basalRates: + cell.textLabel?.text = NSLocalizedString("Basal Rates", comment: "The title text for the basal rate schedule") + + if let basalRateSchedule = setupViewController?.basalSchedule { + let unit = HKUnit.internationalUnit() + let total = HKQuantity(unit: unit, doubleValue: basalRateSchedule.total()) + cell.detailTextLabel?.text = quantityFormatter.string(from: total, for: unit) + } else { + cell.detailTextLabel?.text = SettingsTableViewCell.TapToSetString + } + case .deliveryLimits: + cell.textLabel?.text = NSLocalizedString("Delivery Limits", comment: "Title text for delivery limits") + + if setupViewController?.maxBolusUnits == nil || setupViewController?.maxBasalRateUnitsPerHour == nil { + cell.detailTextLabel?.text = SettingsTableViewCell.TapToSetString + } else { + cell.detailTextLabel?.text = SettingsTableViewCell.EnabledString + } + } + + cell.accessoryType = .disclosureIndicator + + return cell + } + } + + override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool { + switch Section(rawValue: indexPath.section)! { + case .description: + return false + case .configuration: + return true + } + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let sender = tableView.cellForRow(at: indexPath) + + switch Section(rawValue: indexPath.section)! { + case .description: + break + case .configuration: + switch ConfigurationRow(rawValue: indexPath.row)! { + case .basalRates: + let vc = SingleValueScheduleTableViewController(style: .grouped) + + if let profile = setupViewController?.basalSchedule { + vc.scheduleItems = profile.items + vc.timeZone = profile.timeZone + } else if let timeZone = pumpManager?.pumpTimeZone { + vc.timeZone = timeZone + } + + vc.title = sender?.textLabel?.text + vc.delegate = self + vc.syncSource = pumpManager + + show(vc, sender: sender) + case .deliveryLimits: + let vc = DeliveryLimitSettingsTableViewController(style: .grouped) + + vc.maximumBasalRatePerHour = setupViewController?.maxBasalRateUnitsPerHour + vc.maximumBolus = setupViewController?.maxBolusUnits + + vc.title = sender?.textLabel?.text + vc.delegate = self + vc.syncSource = pumpManager + + show(vc, sender: sender) + } + } + } +} + +extension MinimedPumpSettingsSetupViewController: DailyValueScheduleTableViewControllerDelegate { + func dailyValueScheduleTableViewControllerWillFinishUpdating(_ controller: DailyValueScheduleTableViewController) { + if let controller = controller as? SingleValueScheduleTableViewController { + pumpManagerSetupViewController?.basalSchedule = BasalRateSchedule(dailyItems: controller.scheduleItems, timeZone: controller.timeZone) + } + + tableView.reloadRows(at: [[Section.configuration.rawValue, ConfigurationRow.basalRates.rawValue]], with: .none) + } +} + +extension MinimedPumpSettingsSetupViewController: DeliveryLimitSettingsTableViewControllerDelegate { + func deliveryLimitSettingsTableViewControllerDidUpdateMaximumBasalRatePerHour(_ vc: DeliveryLimitSettingsTableViewController) { + pumpManagerSetupViewController?.maxBasalRateUnitsPerHour = vc.maximumBasalRatePerHour + + tableView.reloadRows(at: [[Section.configuration.rawValue, ConfigurationRow.deliveryLimits.rawValue]], with: .none) + } + + func deliveryLimitSettingsTableViewControllerDidUpdateMaximumBolus(_ vc: DeliveryLimitSettingsTableViewController) { + pumpManagerSetupViewController?.maxBolusUnits = vc.maximumBolus + + tableView.reloadRows(at: [[Section.configuration.rawValue, ConfigurationRow.deliveryLimits.rawValue]], with: .none) + } +} diff --git a/MinimedKitUI/Setup/MinimedPumpSetupCompleteViewController.swift b/MinimedKitUI/Setup/MinimedPumpSetupCompleteViewController.swift new file mode 100644 index 000000000..8314f1a3f --- /dev/null +++ b/MinimedKitUI/Setup/MinimedPumpSetupCompleteViewController.swift @@ -0,0 +1,37 @@ +// +// MinimedPumpSetupCompleteViewController.swift +// Loop +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + +import UIKit +import LoopKitUI + +class MinimedPumpSetupCompleteViewController: SetupTableViewController { + + @IBOutlet private var pumpImageView: UIImageView! + + var pumpImage: UIImage? { + didSet { + if isViewLoaded { + pumpImageView.image = pumpImage + } + } + } + + override func viewDidLoad() { + super.viewDidLoad() + + pumpImageView.image = pumpImage + + self.navigationItem.hidesBackButton = true + self.navigationItem.rightBarButtonItem = nil + } + + override func continueButtonPressed(_ sender: Any) { + if let setupViewController = setupViewController as? MinimedPumpManagerSetupViewController { + setupViewController.completeSetup() + } + } +} diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 47c880b9a..60b6e74b8 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -6,12 +6,23 @@ objectVersion = 47; objects = { +/* Begin PBXAggregateTarget section */ + 43FB610120DDEF26002B996B /* Cartfile */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 43FB610420DDEF26002B996B /* Build configuration list for PBXAggregateTarget "Cartfile" */; + buildPhases = ( + 43FB610520DDEF32002B996B /* Build Carthage Dependencies */, + ); + dependencies = ( + ); + name = Cartfile; + productName = Cartfile; + }; +/* End PBXAggregateTarget section */ + /* Begin PBXBuildFile section */ 2B19B9881DF3EF68006AB65F /* NewTimePumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B19B9871DF3EF68006AB65F /* NewTimePumpEvent.swift */; }; - 2F962EBF1E678BAA0070EFBD /* PumpOpsSynchronousTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F962EBE1E678BAA0070EFBD /* PumpOpsSynchronousTests.swift */; }; 2F962EC11E6872170070EFBD /* TimestampedHistoryEventTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F962EC01E6872170070EFBD /* TimestampedHistoryEventTests.swift */; }; - 2F962EC31E6873A10070EFBD /* PumpMessageSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F962EC21E6873A10070EFBD /* PumpMessageSender.swift */; }; - 2F962EC51E705C6E0070EFBD /* PumpOpsSynchronousBuildFromFramesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F962EC41E705C6D0070EFBD /* PumpOpsSynchronousBuildFromFramesTests.swift */; }; 2F962EC81E7074E60070EFBD /* BolusNormalPumpEventTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F962EC71E7074E60070EFBD /* BolusNormalPumpEventTests.swift */; }; 2F962ECA1E70831F0070EFBD /* PumpModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F962EC91E70831F0070EFBD /* PumpModelTests.swift */; }; 2FDE1A071E57B12D00B56A27 /* ReadCurrentPageNumberMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FDE1A061E57B12D00B56A27 /* ReadCurrentPageNumberMessageBody.swift */; }; @@ -47,31 +58,84 @@ 43323EAA1FA81C1B003FB0FA /* RileyLinkDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43323EA91FA81C1B003FB0FA /* RileyLinkDevice.swift */; }; 433568761CF67FA800FD9D54 /* ReadRemainingInsulinMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 433568751CF67FA800FD9D54 /* ReadRemainingInsulinMessageBody.swift */; }; 433ABFFC2016FDF700E6C1FF /* RileyLinkDeviceError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 433ABFFB2016FDF700E6C1FF /* RileyLinkDeviceError.swift */; }; - 4345D1CE1DA16AF300BAAD22 /* TimeZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4345D1CD1DA16AF300BAAD22 /* TimeZone.swift */; }; 43462E8B1CCB06F500F958A8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43462E8A1CCB06F500F958A8 /* AppDelegate.swift */; }; - 434AB0961CBA0DF600422F4A /* PumpOps.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434AB0921CBA0DF600422F4A /* PumpOps.swift */; }; - 434AB0971CBA0DF600422F4A /* PumpOpsSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434AB0931CBA0DF600422F4A /* PumpOpsSession.swift */; }; - 434AB0981CBA0DF600422F4A /* PumpState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434AB0941CBA0DF600422F4A /* PumpState.swift */; }; 434AB0C71CBCB76400422F4A /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BA1C826B92006DBA60 /* Data.swift */; }; 434FF1DC1CF268BD000DB779 /* IdentifiableClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 431185AE1CF25A590059ED98 /* IdentifiableClass.swift */; }; 434FF1DE1CF268F3000DB779 /* RileyLinkDeviceTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434FF1DD1CF268F3000DB779 /* RileyLinkDeviceTableViewCell.swift */; }; + 4352A71220DEC68100CAC200 /* RileyLinkKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43722FAE1CB9F7630038B7F2 /* RileyLinkKit.framework */; }; + 4352A71520DEC72500CAC200 /* PumpMessageSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F962EC21E6873A10070EFBD /* PumpMessageSender.swift */; }; + 4352A71620DEC78B00CAC200 /* PumpSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4384C8C71FB937E500D916E6 /* PumpSettings.swift */; }; + 4352A71720DEC78B00CAC200 /* PumpState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434AB0941CBA0DF600422F4A /* PumpState.swift */; }; + 4352A71820DEC7B900CAC200 /* PumpMessage+PumpOpsSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435535DB1FB8B37E00CE5A23 /* PumpMessage+PumpOpsSession.swift */; }; + 4352A71920DEC7C100CAC200 /* BasalProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43BF58B11FF5A22200499C46 /* BasalProfile.swift */; }; + 4352A71A20DEC7CB00CAC200 /* CommandSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 436CCEF11FB953E800A6822B /* CommandSession.swift */; }; + 4352A71B20DEC7DC00CAC200 /* HistoryPage+PumpOpsSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4384C8C51FB92F8100D916E6 /* HistoryPage+PumpOpsSession.swift */; }; + 4352A71C20DEC8C100CAC200 /* TimeZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4345D1CD1DA16AF300BAAD22 /* TimeZone.swift */; }; + 4352A71D20DEC8CC00CAC200 /* TimeZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4345D1CD1DA16AF300BAAD22 /* TimeZone.swift */; }; + 4352A71E20DEC93300CAC200 /* PumpOpsSynchronousTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F962EBE1E678BAA0070EFBD /* PumpOpsSynchronousTests.swift */; }; + 4352A71F20DEC93300CAC200 /* PumpOpsSynchronousBuildFromFramesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F962EC41E705C6D0070EFBD /* PumpOpsSynchronousBuildFromFramesTests.swift */; }; + 4352A72920DEC9B700CAC200 /* MinimedKitUI.h in Headers */ = {isa = PBXBuildFile; fileRef = 4352A72720DEC9B700CAC200 /* MinimedKitUI.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4352A72C20DEC9B700CAC200 /* MinimedKitUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4352A72520DEC9B700CAC200 /* MinimedKitUI.framework */; }; + 4352A72D20DEC9B700CAC200 /* MinimedKitUI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 4352A72520DEC9B700CAC200 /* MinimedKitUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 4352A73220DEC9D600CAC200 /* CommandResponseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4352A73120DEC9D600CAC200 /* CommandResponseViewController.swift */; }; + 4352A73320DEC9FC00CAC200 /* RileyLinkKitUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43D5E78E1FAF7BFB004ACDB7 /* RileyLinkKitUI.framework */; }; + 4352A73420DECAE000CAC200 /* LoopKitUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43FB610A20DDF55E002B996B /* LoopKitUI.framework */; }; + 4352A73720DECB7300CAC200 /* PumpOps.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435535D71FB7987000CE5A23 /* PumpOps.swift */; }; + 4352A73920DECBAA00CAC200 /* RileyLinkMinimedDeviceTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4352A73820DECBAA00CAC200 /* RileyLinkMinimedDeviceTableViewController.swift */; }; + 4352A73A20DECDB300CAC200 /* MinimedKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C10D9BC11C8269D500378342 /* MinimedKit.framework */; }; + 4352A73F20DED02C00CAC200 /* HKUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4352A73D20DED01700CAC200 /* HKUnit.swift */; }; + 4352A74120DED23100CAC200 /* RileyLinkDeviceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4352A74020DED23000CAC200 /* RileyLinkDeviceManager.swift */; }; + 4352A74220DED3D200CAC200 /* CaseCountable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1C659181E16BA9D0025CC58 /* CaseCountable.swift */; }; + 4352A74320DED3F200CAC200 /* NumberFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43323EA61FA81A0F003FB0FA /* NumberFormatter.swift */; }; + 4352A74620DED4AB00CAC200 /* LoopKitUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43FB610A20DDF55E002B996B /* LoopKitUI.framework */; }; + 4352A74720DED4AF00CAC200 /* LoopKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43FB610B20DDF55F002B996B /* LoopKit.framework */; }; + 4352A74820DED80300CAC200 /* TimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EBE4501EAD238C0073A0B5 /* TimeInterval.swift */; }; + 4352A74920DED81D00CAC200 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BA1C826B92006DBA60 /* Data.swift */; }; + 4352A74A20DED87500CAC200 /* LoopKit.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 43FB610B20DDF55F002B996B /* LoopKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 4352A74B20DED87F00CAC200 /* LoopKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43FB610B20DDF55F002B996B /* LoopKit.framework */; }; + 4352A74C20DED8C200CAC200 /* LoopKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43FB610B20DDF55F002B996B /* LoopKit.framework */; }; + 4352A74D20DED8FC00CAC200 /* LoopKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43FB610B20DDF55F002B996B /* LoopKit.framework */; }; + 4352A74F20DEDE8400CAC200 /* LoopKitUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43FB610A20DDF55E002B996B /* LoopKitUI.framework */; }; + 4352A75020DEDE8700CAC200 /* LoopKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43FB610B20DDF55F002B996B /* LoopKit.framework */; }; + 4352A75120DEDE9B00CAC200 /* LoopKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43FB610B20DDF55F002B996B /* LoopKit.framework */; }; 435535D61FB6D98400CE5A23 /* UserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435535D51FB6D98400CE5A23 /* UserDefaults.swift */; }; - 435535D81FB7987000CE5A23 /* PumpOps.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435535D71FB7987000CE5A23 /* PumpOps.swift */; }; - 435535DA1FB836CB00CE5A23 /* CommandResponseViewController+RileyLinkDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435535D91FB836CB00CE5A23 /* CommandResponseViewController+RileyLinkDevice.swift */; }; - 435535DC1FB8B37E00CE5A23 /* PumpMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435535DB1FB8B37E00CE5A23 /* PumpMessage.swift */; }; - 436CCEF21FB953E800A6822B /* CommandSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 436CCEF11FB953E800A6822B /* CommandSession.swift */; }; - 4370A37E1FAF8EF200EC666A /* TextFieldTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C1B4A9531D1E613A003B8985 /* TextFieldTableViewCell.xib */; }; + 435D26B020DA08CE00891C17 /* RileyLinkPumpManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435D26AF20DA08CE00891C17 /* RileyLinkPumpManager.swift */; }; + 435D26B220DA091C00891C17 /* RileyLinkPumpManagerState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435D26B120DA091B00891C17 /* RileyLinkPumpManagerState.swift */; }; + 435D26B420DA0AAE00891C17 /* RileyLinkDevicesHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435D26B320DA0AAE00891C17 /* RileyLinkDevicesHeaderView.swift */; }; + 435D26B620DA0BCC00891C17 /* RileyLinkDevicesTableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435D26B520DA0BCC00891C17 /* RileyLinkDevicesTableViewDataSource.swift */; }; + 435D26B920DC83F300891C17 /* Locked.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435D26B720DC83E400891C17 /* Locked.swift */; }; + 43709ABD20DF1C6400F941B3 /* RileyLinkSetupTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43709ABA20DF1C6400F941B3 /* RileyLinkSetupTableViewController.swift */; }; + 43709ABE20DF1C6400F941B3 /* RileyLinkManagerSetupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43709ABB20DF1C6400F941B3 /* RileyLinkManagerSetupViewController.swift */; }; + 43709ABF20DF1C6400F941B3 /* RileyLinkSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43709ABC20DF1C6400F941B3 /* RileyLinkSettingsViewController.swift */; }; + 43709AC420DF1C8B00F941B3 /* PumpModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43709AC020DF1C8B00F941B3 /* PumpModel.swift */; }; + 43709AC520DF1C8B00F941B3 /* RadioSelectionTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43709AC120DF1C8B00F941B3 /* RadioSelectionTableViewController.swift */; }; + 43709AC620DF1C8B00F941B3 /* MinimedPumpSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43709AC220DF1C8B00F941B3 /* MinimedPumpSettingsViewController.swift */; }; + 43709AC720DF1C8B00F941B3 /* MinimedPumpManager+UI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43709AC320DF1C8B00F941B3 /* MinimedPumpManager+UI.swift */; }; + 43709AC920DF1C9A00F941B3 /* MinimedKitUI.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 43709AC820DF1C9A00F941B3 /* MinimedKitUI.xcassets */; }; + 43709AD320DF1CF800F941B3 /* MinimedPumpClockSetupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43709ACD20DF1CF700F941B3 /* MinimedPumpClockSetupViewController.swift */; }; + 43709AD420DF1CF800F941B3 /* MinimedPumpIDSetupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43709ACE20DF1CF700F941B3 /* MinimedPumpIDSetupViewController.swift */; }; + 43709AD520DF1CF800F941B3 /* MinimedPumpManagerSetupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43709ACF20DF1CF700F941B3 /* MinimedPumpManagerSetupViewController.swift */; }; + 43709AD620DF1CF800F941B3 /* MinimedPumpSentrySetupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43709AD020DF1CF700F941B3 /* MinimedPumpSentrySetupViewController.swift */; }; + 43709AD720DF1CF800F941B3 /* MinimedPumpSetupCompleteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43709AD120DF1CF700F941B3 /* MinimedPumpSetupCompleteViewController.swift */; }; + 43709AD820DF1CF800F941B3 /* MinimedPumpSettingsSetupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43709AD220DF1CF800F941B3 /* MinimedPumpSettingsSetupViewController.swift */; }; + 43709ADE20DF1D5400F941B3 /* MinimedPumpManager.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 43709AE020DF1D5400F941B3 /* MinimedPumpManager.storyboard */; }; + 43709AE120DF1F0D00F941B3 /* IdentifiableClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 431185AE1CF25A590059ED98 /* IdentifiableClass.swift */; }; + 43709AE220DF1FDD00F941B3 /* UITableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1B4A9581D1E6357003B8985 /* UITableViewCell.swift */; }; + 43709AE320DF20D400F941B3 /* OSLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 431CE7941F9B0DAE00255374 /* OSLog.swift */; }; + 43709AE420DF20D500F941B3 /* OSLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 431CE7941F9B0DAE00255374 /* OSLog.swift */; }; + 43709AE720DF22E400F941B3 /* UIColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14FFC601D3D75470049CF85 /* UIColor.swift */; }; + 43709AE820DF22E700F941B3 /* UIColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14FFC601D3D75470049CF85 /* UIColor.swift */; }; + 43709AEC20E0056F00F941B3 /* RileyLinkKitUI.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 43709AEB20E0056F00F941B3 /* RileyLinkKitUI.xcassets */; }; + 43709AEE20E008F300F941B3 /* SetupImageTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43709AED20E008F300F941B3 /* SetupImageTableViewCell.swift */; }; + 43709AF020E0120F00F941B3 /* SetupImageTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 43709AEF20E0120F00F941B3 /* SetupImageTableViewCell.xib */; }; + 43709AF120E0127000F941B3 /* NibLoadable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14FFC5A1D3D74F90049CF85 /* NibLoadable.swift */; }; 43722FB11CB9F7640038B7F2 /* RileyLinkKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 43722FB01CB9F7640038B7F2 /* RileyLinkKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 43722FB81CB9F7640038B7F2 /* RileyLinkKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43722FAE1CB9F7630038B7F2 /* RileyLinkKit.framework */; }; 43722FC31CB9F7640038B7F2 /* RileyLinkKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43722FAE1CB9F7630038B7F2 /* RileyLinkKit.framework */; }; 43722FC41CB9F7640038B7F2 /* RileyLinkKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 43722FAE1CB9F7630038B7F2 /* RileyLinkKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 43722FCB1CB9F7DB0038B7F2 /* MinimedKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C10D9BC11C8269D500378342 /* MinimedKit.framework */; }; 437462391FA9287A00643383 /* RileyLinkDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437462381FA9287A00643383 /* RileyLinkDevice.swift */; }; 437F54071FBD52120070FF2C /* DeviceState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437F54061FBD52120070FF2C /* DeviceState.swift */; }; - 437F54091FBF9E0A0070FF2C /* RileyLinkDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437F54081FBF9E0A0070FF2C /* RileyLinkDevice.swift */; }; 437F540A1FBFDAA60070FF2C /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6BA1C826B92006DBA60 /* Data.swift */; }; - 4384C8C61FB92F8100D916E6 /* HistoryPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4384C8C51FB92F8100D916E6 /* HistoryPage.swift */; }; - 4384C8C81FB937E500D916E6 /* PumpSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4384C8C71FB937E500D916E6 /* PumpSettings.swift */; }; 4384C8C91FB941FB00D916E6 /* TimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EBE4501EAD238C0073A0B5 /* TimeInterval.swift */; }; 438D39221D19011700D40CA4 /* PlaceholderPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 438D39211D19011700D40CA4 /* PlaceholderPumpEvent.swift */; }; 43A068EC1CF6BA6900F9EFE4 /* ReadRemainingInsulinMessageBodyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43A068EB1CF6BA6900F9EFE4 /* ReadRemainingInsulinMessageBodyTests.swift */; }; @@ -86,7 +150,6 @@ 43BA719B202591A70058961E /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43BA719A202591A70058961E /* Response.swift */; }; 43BA719D2026C9B00058961E /* ResponseBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43BA719C2026C9B00058961E /* ResponseBuffer.swift */; }; 43BF58B01FF594CB00499C46 /* SelectBasalProfileMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43BF58AF1FF594CB00499C46 /* SelectBasalProfileMessageBody.swift */; }; - 43BF58B21FF5A22200499C46 /* BasalProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43BF58B11FF5A22200499C46 /* BasalProfile.swift */; }; 43BF58B31FF6079600499C46 /* TimeInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EBE4501EAD238C0073A0B5 /* TimeInterval.swift */; }; 43C0196C1FA6B8AE007ABFA1 /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43CA93241CB8BB33000026B5 /* CoreBluetooth.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 43C246971D8918AE0031F8D1 /* Crypto.h in Headers */ = {isa = PBXBuildFile; fileRef = 43C246951D8918AE0031F8D1 /* Crypto.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -114,14 +177,28 @@ 43D5E79A1FAF7C47004ACDB7 /* RileyLinkDeviceTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439731261CF21C3C00F474E5 /* RileyLinkDeviceTableViewCell.swift */; }; 43D5E79B1FAF7C47004ACDB7 /* CommandResponseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C170C9961CECD80000F3D8E5 /* CommandResponseViewController.swift */; }; 43D5E79C1FAF7C47004ACDB7 /* RileyLinkDeviceTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C170C9981CECD80000F3D8E5 /* RileyLinkDeviceTableViewController.swift */; }; - 43D5E79D1FAF7C47004ACDB7 /* TextFieldTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1B4A9521D1E613A003B8985 /* TextFieldTableViewCell.swift */; }; - 43D5E79E1FAF7C47004ACDB7 /* TextFieldTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1B4A9541D1E613A003B8985 /* TextFieldTableViewController.swift */; }; 43D5E79F1FAF7C98004ACDB7 /* IdentifiableClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 431185AE1CF25A590059ED98 /* IdentifiableClass.swift */; }; 43D5E7A01FAF7CCA004ACDB7 /* NumberFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43323EA61FA81A0F003FB0FA /* NumberFormatter.swift */; }; 43D5E7A11FAF7CE0004ACDB7 /* UITableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1B4A9581D1E6357003B8985 /* UITableViewCell.swift */; }; 43D5E7A21FAF7CF2004ACDB7 /* CaseCountable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1C659181E16BA9D0025CC58 /* CaseCountable.swift */; }; 43D5E7A31FAF7D05004ACDB7 /* CBPeripheralState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C170C98D1CECD6F300F3D8E5 /* CBPeripheralState.swift */; }; - 43D5E7A41FAF7D4D004ACDB7 /* TimeZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4345D1CD1DA16AF300BAAD22 /* TimeZone.swift */; }; + 43D8708820DE1A63006B549E /* LoopKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43FB610B20DDF55F002B996B /* LoopKit.framework */; }; + 43D8708B20DE1BCA006B549E /* PumpColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D8708A20DE1BC9006B549E /* PumpColor.swift */; }; + 43D8708D20DE1C05006B549E /* DoseStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D8708C20DE1C05006B549E /* DoseStore.swift */; }; + 43D8708F20DE1C23006B549E /* EnliteSensorDisplayable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D8708E20DE1C23006B549E /* EnliteSensorDisplayable.swift */; }; + 43D8709120DE1C3B006B549E /* MySentryPumpStatusMessageBody+CGMManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D8709020DE1C3B006B549E /* MySentryPumpStatusMessageBody+CGMManager.swift */; }; + 43D8709320DE1C80006B549E /* PumpOpsSession+LoopKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D8709220DE1C80006B549E /* PumpOpsSession+LoopKit.swift */; }; + 43D8709520DE1C91006B549E /* RileyLinkDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D8709420DE1C91006B549E /* RileyLinkDevice.swift */; }; + 43D8709720DE1CA1006B549E /* SensorValueGlucoseEvent+CGMManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D8709620DE1CA1006B549E /* SensorValueGlucoseEvent+CGMManager.swift */; }; + 43D8709B20DE1CB6006B549E /* MinimedPumpManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D8709820DE1CB6006B549E /* MinimedPumpManager.swift */; }; + 43D8709C20DE1CB6006B549E /* MinimedPumpManagerError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D8709920DE1CB6006B549E /* MinimedPumpManagerError.swift */; }; + 43D8709D20DE1CB6006B549E /* MinimedPumpManagerState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D8709A20DE1CB6006B549E /* MinimedPumpManagerState.swift */; }; + 43D8709F20DE1D1C006B549E /* RileyLinkBLEKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 431CE76F1F98564100255374 /* RileyLinkBLEKit.framework */; }; + 43D870A020DE1D28006B549E /* LoopKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43FB610B20DDF55F002B996B /* LoopKit.framework */; }; + 43D870A220DE1DCF006B549E /* InsulinDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D870A120DE1DCF006B549E /* InsulinDataSource.swift */; }; + 43D870A320DE1E1E006B549E /* PumpOpsSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434AB0931CBA0DF600422F4A /* PumpOpsSession.swift */; }; + 43D870A420DE1E88006B549E /* PumpOps.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434AB0921CBA0DF600422F4A /* PumpOps.swift */; }; + 43D870A520DE1E88006B549E /* PumpOpsError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A7215F1EC29C0B0080FAD7 /* PumpOpsError.swift */; }; 43DAD00220A6A470000F8529 /* ReadOtherDevicesStatusMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43DAD00120A6A470000F8529 /* ReadOtherDevicesStatusMessageBody.swift */; }; 43DAD00420A6A677000F8529 /* ReadOtherDevicesIDsMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43DAD00320A6A677000F8529 /* ReadOtherDevicesIDsMessageBody.swift */; }; 43DAD00620A6B10A000F8529 /* ReadOtherDevicesIDsMessageBodyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43DAD00520A6B10A000F8529 /* ReadOtherDevicesIDsMessageBodyTests.swift */; }; @@ -321,7 +398,6 @@ C1A492651D4A5DEB008964FF /* BatteryStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A492641D4A5DEB008964FF /* BatteryStatus.swift */; }; C1A492671D4A65D9008964FF /* RecommendedTempBasal.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A492661D4A65D9008964FF /* RecommendedTempBasal.swift */; }; C1A492691D4A66C0008964FF /* LoopEnacted.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A492681D4A66C0008964FF /* LoopEnacted.swift */; }; - C1A721601EC29C0B0080FAD7 /* PumpOpsError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A7215F1EC29C0B0080FAD7 /* PumpOpsError.swift */; }; C1A721621EC3E0500080FAD7 /* PumpErrorMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A721611EC3E0500080FAD7 /* PumpErrorMessageBody.swift */; }; C1A721661EC4BCE30080FAD7 /* PartialDecode.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1A721651EC4BCE30080FAD7 /* PartialDecode.swift */; }; C1AF21E21D4838C90088C41D /* DeviceStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1AF21E11D4838C90088C41D /* DeviceStatus.swift */; }; @@ -348,7 +424,7 @@ C1D00E9D1E8986A400B733B7 /* PumpSuspendTreatment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1D00E9C1E8986A400B733B7 /* PumpSuspendTreatment.swift */; }; C1D00EA11E8986F900B733B7 /* PumpResumeTreatment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1D00EA01E8986F900B733B7 /* PumpResumeTreatment.swift */; }; C1E5BEAD1D5E26F200BD4390 /* RileyLinkStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1E5BEAC1D5E26F200BD4390 /* RileyLinkStatus.swift */; }; - C1EAD6B31C826B6D006DBA60 /* AlertType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6AE1C826B6D006DBA60 /* AlertType.swift */; }; + C1EAD6B31C826B6D006DBA60 /* MySentryAlertType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6AE1C826B6D006DBA60 /* MySentryAlertType.swift */; }; C1EAD6B41C826B6D006DBA60 /* MessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6AF1C826B6D006DBA60 /* MessageBody.swift */; }; C1EAD6B51C826B6D006DBA60 /* MessageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6B01C826B6D006DBA60 /* MessageType.swift */; }; C1EAD6B61C826B6D006DBA60 /* PacketType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1EAD6B11C826B6D006DBA60 /* PacketType.swift */; }; @@ -405,6 +481,55 @@ remoteGlobalIDString = 431CE76E1F98564100255374; remoteInfo = RileyLinkBLEKit; }; + 4327EEB820E1E55D002598CB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C12EA22F198B436800309FA4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = C12EA236198B436800309FA4; + remoteInfo = RileyLink; + }; + 4327EEBA20E1E562002598CB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C12EA22F198B436800309FA4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = C12EA236198B436800309FA4; + remoteInfo = RileyLink; + }; + 4352A71020DEC67300CAC200 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C12EA22F198B436800309FA4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 43FB610120DDEF26002B996B; + remoteInfo = Cartfile; + }; + 4352A71320DEC68700CAC200 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C12EA22F198B436800309FA4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 43FB610120DDEF26002B996B; + remoteInfo = Cartfile; + }; + 4352A72A20DEC9B700CAC200 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C12EA22F198B436800309FA4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4352A72420DEC9B700CAC200; + remoteInfo = MinimedKitUI; + }; + 4352A73520DECAE900CAC200 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C12EA22F198B436800309FA4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 43FB610120DDEF26002B996B; + remoteInfo = Cartfile; + }; + 4352A74420DED49C00CAC200 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C12EA22F198B436800309FA4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 43FB610120DDEF26002B996B; + remoteInfo = Cartfile; + }; 43722FB91CB9F7640038B7F2 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = C12EA22F198B436800309FA4 /* Project object */; @@ -440,6 +565,13 @@ remoteGlobalIDString = 43D5E78D1FAF7BFB004ACDB7; remoteInfo = RileyLinkKitUI; }; + 43FB610820DDF509002B996B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = C12EA22F198B436800309FA4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 43FB610120DDEF26002B996B; + remoteInfo = Cartfile; + }; C10D9BCC1C8269D500378342 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = C12EA22F198B436800309FA4 /* Project object */; @@ -492,6 +624,7 @@ dstSubfolderSpec = 10; files = ( 43C9071C1D863782002BAD29 /* MinimedKit.framework in CopyFiles */, + 4352A74A20DED87500CAC200 /* LoopKit.framework in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -506,6 +639,7 @@ C10D9BD71C8269D500378342 /* MinimedKit.framework in Embed Frameworks */, 43D5E7961FAF7BFB004ACDB7 /* RileyLinkKitUI.framework in Embed Frameworks */, C1B383211CD0665D00CE7782 /* NightscoutUploadKit.framework in Embed Frameworks */, + 4352A72D20DEC9B700CAC200 /* MinimedKitUI.framework in Embed Frameworks */, 431CE7851F98564200255374 /* RileyLinkBLEKit.framework in Embed Frameworks */, ); name = "Embed Frameworks"; @@ -550,14 +684,43 @@ 4345D1CD1DA16AF300BAAD22 /* TimeZone.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeZone.swift; sourceTree = ""; }; 43462E8A1CCB06F500F958A8 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 434AB0921CBA0DF600422F4A /* PumpOps.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpOps.swift; sourceTree = ""; }; - 434AB0931CBA0DF600422F4A /* PumpOpsSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpOpsSession.swift; sourceTree = ""; }; + 434AB0931CBA0DF600422F4A /* PumpOpsSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PumpOpsSession.swift; path = ../../RileyLinkKit/PumpOpsSession.swift; sourceTree = ""; }; 434AB0941CBA0DF600422F4A /* PumpState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpState.swift; sourceTree = ""; }; 434FF1DD1CF268F3000DB779 /* RileyLinkDeviceTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkDeviceTableViewCell.swift; sourceTree = ""; }; + 4352A72520DEC9B700CAC200 /* MinimedKitUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MinimedKitUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4352A72720DEC9B700CAC200 /* MinimedKitUI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MinimedKitUI.h; sourceTree = ""; }; + 4352A72820DEC9B700CAC200 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 4352A73120DEC9D600CAC200 /* CommandResponseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandResponseViewController.swift; sourceTree = ""; }; + 4352A73820DECBAA00CAC200 /* RileyLinkMinimedDeviceTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RileyLinkMinimedDeviceTableViewController.swift; sourceTree = ""; }; + 4352A73D20DED01700CAC200 /* HKUnit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HKUnit.swift; sourceTree = ""; }; + 4352A74020DED23000CAC200 /* RileyLinkDeviceManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkDeviceManager.swift; sourceTree = ""; }; 435535D51FB6D98400CE5A23 /* UserDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaults.swift; sourceTree = ""; }; 435535D71FB7987000CE5A23 /* PumpOps.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PumpOps.swift; sourceTree = ""; }; - 435535D91FB836CB00CE5A23 /* CommandResponseViewController+RileyLinkDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CommandResponseViewController+RileyLinkDevice.swift"; sourceTree = ""; }; - 435535DB1FB8B37E00CE5A23 /* PumpMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PumpMessage.swift; sourceTree = ""; }; + 435535DB1FB8B37E00CE5A23 /* PumpMessage+PumpOpsSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PumpMessage+PumpOpsSession.swift"; sourceTree = ""; }; + 435D26AF20DA08CE00891C17 /* RileyLinkPumpManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkPumpManager.swift; sourceTree = ""; }; + 435D26B120DA091B00891C17 /* RileyLinkPumpManagerState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkPumpManagerState.swift; sourceTree = ""; }; + 435D26B320DA0AAE00891C17 /* RileyLinkDevicesHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkDevicesHeaderView.swift; sourceTree = ""; }; + 435D26B520DA0BCC00891C17 /* RileyLinkDevicesTableViewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RileyLinkDevicesTableViewDataSource.swift; sourceTree = ""; }; + 435D26B720DC83E400891C17 /* Locked.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Locked.swift; sourceTree = ""; }; 436CCEF11FB953E800A6822B /* CommandSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandSession.swift; sourceTree = ""; }; + 43709ABA20DF1C6400F941B3 /* RileyLinkSetupTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkSetupTableViewController.swift; sourceTree = ""; }; + 43709ABB20DF1C6400F941B3 /* RileyLinkManagerSetupViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkManagerSetupViewController.swift; sourceTree = ""; }; + 43709ABC20DF1C6400F941B3 /* RileyLinkSettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkSettingsViewController.swift; sourceTree = ""; }; + 43709AC020DF1C8B00F941B3 /* PumpModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpModel.swift; sourceTree = ""; }; + 43709AC120DF1C8B00F941B3 /* RadioSelectionTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioSelectionTableViewController.swift; sourceTree = ""; }; + 43709AC220DF1C8B00F941B3 /* MinimedPumpSettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MinimedPumpSettingsViewController.swift; sourceTree = ""; }; + 43709AC320DF1C8B00F941B3 /* MinimedPumpManager+UI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MinimedPumpManager+UI.swift"; sourceTree = ""; }; + 43709AC820DF1C9A00F941B3 /* MinimedKitUI.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = MinimedKitUI.xcassets; sourceTree = ""; }; + 43709ACD20DF1CF700F941B3 /* MinimedPumpClockSetupViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MinimedPumpClockSetupViewController.swift; sourceTree = ""; }; + 43709ACE20DF1CF700F941B3 /* MinimedPumpIDSetupViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MinimedPumpIDSetupViewController.swift; sourceTree = ""; }; + 43709ACF20DF1CF700F941B3 /* MinimedPumpManagerSetupViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MinimedPumpManagerSetupViewController.swift; sourceTree = ""; }; + 43709AD020DF1CF700F941B3 /* MinimedPumpSentrySetupViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MinimedPumpSentrySetupViewController.swift; sourceTree = ""; }; + 43709AD120DF1CF700F941B3 /* MinimedPumpSetupCompleteViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MinimedPumpSetupCompleteViewController.swift; sourceTree = ""; }; + 43709AD220DF1CF800F941B3 /* MinimedPumpSettingsSetupViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MinimedPumpSettingsSetupViewController.swift; sourceTree = ""; }; + 43709ADF20DF1D5400F941B3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MinimedPumpManager.storyboard; sourceTree = ""; }; + 43709AEB20E0056F00F941B3 /* RileyLinkKitUI.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = RileyLinkKitUI.xcassets; sourceTree = ""; }; + 43709AED20E008F300F941B3 /* SetupImageTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetupImageTableViewCell.swift; sourceTree = ""; }; + 43709AEF20E0120F00F941B3 /* SetupImageTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SetupImageTableViewCell.xib; sourceTree = ""; }; 4370A3791FAF8A7400EC666A /* CoreBluetooth.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreBluetooth.framework; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS4.1.sdk/System/Library/Frameworks/CoreBluetooth.framework; sourceTree = DEVELOPER_DIR; }; 43722FAE1CB9F7630038B7F2 /* RileyLinkKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RileyLinkKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 43722FB01CB9F7640038B7F2 /* RileyLinkKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RileyLinkKit.h; sourceTree = ""; }; @@ -566,8 +729,7 @@ 43722FC01CB9F7640038B7F2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 437462381FA9287A00643383 /* RileyLinkDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RileyLinkDevice.swift; sourceTree = ""; }; 437F54061FBD52120070FF2C /* DeviceState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceState.swift; sourceTree = ""; }; - 437F54081FBF9E0A0070FF2C /* RileyLinkDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RileyLinkDevice.swift; sourceTree = ""; }; - 4384C8C51FB92F8100D916E6 /* HistoryPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryPage.swift; sourceTree = ""; }; + 4384C8C51FB92F8100D916E6 /* HistoryPage+PumpOpsSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HistoryPage+PumpOpsSession.swift"; sourceTree = ""; }; 4384C8C71FB937E500D916E6 /* PumpSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PumpSettings.swift; sourceTree = ""; }; 438D39211D19011700D40CA4 /* PlaceholderPumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlaceholderPumpEvent.swift; sourceTree = ""; }; 439731261CF21C3C00F474E5 /* RileyLinkDeviceTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkDeviceTableViewCell.swift; sourceTree = ""; }; @@ -600,6 +762,17 @@ 43D5E78E1FAF7BFB004ACDB7 /* RileyLinkKitUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RileyLinkKitUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 43D5E7901FAF7BFB004ACDB7 /* RileyLinkKitUI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RileyLinkKitUI.h; sourceTree = ""; }; 43D5E7911FAF7BFB004ACDB7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 43D8708A20DE1BC9006B549E /* PumpColor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PumpColor.swift; sourceTree = ""; }; + 43D8708C20DE1C05006B549E /* DoseStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoseStore.swift; sourceTree = ""; }; + 43D8708E20DE1C23006B549E /* EnliteSensorDisplayable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnliteSensorDisplayable.swift; sourceTree = ""; }; + 43D8709020DE1C3B006B549E /* MySentryPumpStatusMessageBody+CGMManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MySentryPumpStatusMessageBody+CGMManager.swift"; sourceTree = ""; }; + 43D8709220DE1C80006B549E /* PumpOpsSession+LoopKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PumpOpsSession+LoopKit.swift"; sourceTree = ""; }; + 43D8709420DE1C91006B549E /* RileyLinkDevice.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkDevice.swift; sourceTree = ""; }; + 43D8709620DE1CA1006B549E /* SensorValueGlucoseEvent+CGMManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SensorValueGlucoseEvent+CGMManager.swift"; sourceTree = ""; }; + 43D8709820DE1CB6006B549E /* MinimedPumpManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MinimedPumpManager.swift; sourceTree = ""; }; + 43D8709920DE1CB6006B549E /* MinimedPumpManagerError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MinimedPumpManagerError.swift; sourceTree = ""; }; + 43D8709A20DE1CB6006B549E /* MinimedPumpManagerState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MinimedPumpManagerState.swift; sourceTree = ""; }; + 43D870A120DE1DCF006B549E /* InsulinDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InsulinDataSource.swift; sourceTree = ""; }; 43DAD00120A6A470000F8529 /* ReadOtherDevicesStatusMessageBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadOtherDevicesStatusMessageBody.swift; sourceTree = ""; }; 43DAD00320A6A677000F8529 /* ReadOtherDevicesIDsMessageBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadOtherDevicesIDsMessageBody.swift; sourceTree = ""; }; 43DAD00520A6B10A000F8529 /* ReadOtherDevicesIDsMessageBodyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadOtherDevicesIDsMessageBodyTests.swift; sourceTree = ""; }; @@ -612,6 +785,8 @@ 43EBE4501EAD238C0073A0B5 /* TimeInterval.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeInterval.swift; sourceTree = ""; }; 43EC9DCA1B786C6200DB0D18 /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LaunchScreen.xib; sourceTree = ""; }; 43F348051D596270009933DC /* HKUnit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HKUnit.swift; sourceTree = ""; }; + 43FB610A20DDF55E002B996B /* LoopKitUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LoopKitUI.framework; path = Carthage/Build/iOS/LoopKitUI.framework; sourceTree = ""; }; + 43FB610B20DDF55F002B996B /* LoopKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LoopKit.framework; path = Carthage/Build/iOS/LoopKit.framework; sourceTree = ""; }; 43FF221B1CB9B9DE00024F30 /* NSDateComponents.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSDateComponents.swift; sourceTree = ""; }; 492526701E4521FB00ACBA5F /* NoteNightscoutTreatment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NoteNightscoutTreatment.swift; sourceTree = ""; }; 541688DA1DB820BF005B1891 /* ReadCurrentGlucosePageMessageBodyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReadCurrentGlucosePageMessageBodyTests.swift; sourceTree = ""; }; @@ -841,12 +1016,9 @@ C1B383141CD0665D00CE7782 /* NightscoutUploadKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NightscoutUploadKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; C1B3831D1CD0665D00CE7782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; C1B383351CD1BA8100CE7782 /* DeviceDataManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeviceDataManager.swift; sourceTree = ""; }; - C1B4A9521D1E613A003B8985 /* TextFieldTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldTableViewCell.swift; sourceTree = ""; }; - C1B4A9531D1E613A003B8985 /* TextFieldTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TextFieldTableViewCell.xib; sourceTree = ""; }; - C1B4A9541D1E613A003B8985 /* TextFieldTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldTableViewController.swift; sourceTree = ""; }; C1B4A9581D1E6357003B8985 /* UITableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITableViewCell.swift; sourceTree = ""; }; C1BAD1171E63984C009BA1C6 /* RadioAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioAdapter.swift; sourceTree = ""; }; - C1C3578E1C927303009BDD4F /* MeterMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MeterMessage.swift; path = Messages/MeterMessage.swift; sourceTree = ""; }; + C1C3578E1C927303009BDD4F /* MeterMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MeterMessage.swift; sourceTree = ""; }; C1C357901C92733A009BDD4F /* MeterMessageTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MeterMessageTests.swift; path = Messages/MeterMessageTests.swift; sourceTree = ""; }; C1C659181E16BA9D0025CC58 /* CaseCountable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaseCountable.swift; sourceTree = ""; }; C1C73F1C1DE6306A0022FC89 /* BatteryChemistryType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BatteryChemistryType.swift; sourceTree = ""; }; @@ -855,7 +1027,7 @@ C1E535E81991E36700C2AC49 /* NSData+Conversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+Conversion.h"; sourceTree = ""; }; C1E535E91991E36700C2AC49 /* NSData+Conversion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+Conversion.m"; sourceTree = ""; }; C1E5BEAC1D5E26F200BD4390 /* RileyLinkStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkStatus.swift; sourceTree = ""; }; - C1EAD6AE1C826B6D006DBA60 /* AlertType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlertType.swift; sourceTree = ""; }; + C1EAD6AE1C826B6D006DBA60 /* MySentryAlertType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MySentryAlertType.swift; sourceTree = ""; }; C1EAD6AF1C826B6D006DBA60 /* MessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageBody.swift; sourceTree = ""; }; C1EAD6B01C826B6D006DBA60 /* MessageType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = MessageType.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; C1EAD6B11C826B6D006DBA60 /* PacketType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PacketType.swift; sourceTree = ""; }; @@ -908,12 +1080,23 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4352A72120DEC9B700CAC200 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4352A73A20DECDB300CAC200 /* MinimedKit.framework in Frameworks */, + 4352A73320DEC9FC00CAC200 /* RileyLinkKitUI.framework in Frameworks */, + 4352A73420DECAE000CAC200 /* LoopKitUI.framework in Frameworks */, + 4352A75120DEDE9B00CAC200 /* LoopKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 43722FAA1CB9F7630038B7F2 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 432847C11FA1737400CDE69C /* RileyLinkBLEKit.framework in Frameworks */, - 43722FCB1CB9F7DB0038B7F2 /* MinimedKit.framework in Frameworks */, + 43D8708820DE1A63006B549E /* LoopKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -922,6 +1105,7 @@ buildActionMask = 2147483647; files = ( 43722FB81CB9F7640038B7F2 /* RileyLinkKit.framework in Frameworks */, + 4352A74D20DED8FC00CAC200 /* LoopKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -937,6 +1121,8 @@ buildActionMask = 2147483647; files = ( 432CF9061FF74CCB003AB446 /* RileyLinkKit.framework in Frameworks */, + 4352A75020DEDE8700CAC200 /* LoopKit.framework in Frameworks */, + 4352A74F20DEDE8400CAC200 /* LoopKitUI.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -944,6 +1130,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 4352A71220DEC68100CAC200 /* RileyLinkKit.framework in Frameworks */, + 43D8709F20DE1D1C006B549E /* RileyLinkBLEKit.framework in Frameworks */, + 43D870A020DE1D28006B549E /* LoopKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -952,6 +1141,7 @@ buildActionMask = 2147483647; files = ( C10D9BCB1C8269D500378342 /* MinimedKit.framework in Frameworks */, + 4352A74C20DED8C200CAC200 /* LoopKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -968,6 +1158,9 @@ C12EA23B198B436800309FA4 /* Foundation.framework in Frameworks */, 431CE7841F98564200255374 /* RileyLinkBLEKit.framework in Frameworks */, C10D9BD61C8269D500378342 /* MinimedKit.framework in Frameworks */, + 4352A72C20DEC9B700CAC200 /* MinimedKitUI.framework in Frameworks */, + 4352A74720DED4AF00CAC200 /* LoopKit.framework in Frameworks */, + 4352A74620DED4AB00CAC200 /* LoopKitUI.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -998,6 +1191,7 @@ files = ( 43C9071B1D863772002BAD29 /* MinimedKit.framework in Frameworks */, C1B383151CD0665D00CE7782 /* NightscoutUploadKit.framework in Frameworks */, + 4352A74B20DED87F00CAC200 /* LoopKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1048,21 +1242,88 @@ path = RileyLinkBLEKitTests; sourceTree = ""; }; + 4352A70C20DEC3A900CAC200 /* Models */ = { + isa = PBXGroup; + children = ( + C1C73F1C1DE6306A0022FC89 /* BatteryChemistryType.swift */, + 43D8708A20DE1BC9006B549E /* PumpColor.swift */, + C1842BBA1C8E184300DB42AC /* PumpModel.swift */, + C1274F851D8242BE0002912B /* PumpRegion.swift */, + ); + path = Models; + sourceTree = ""; + }; + 4352A70D20DEC42800CAC200 /* Radio */ = { + isa = PBXGroup; + children = ( + C1EAD6DD1C82B78C006DBA60 /* CRC8.swift */, + C1F6EB881F89C3E200CFE393 /* FourByteSixByteEncoding.swift */, + C1F6EB8A1F89C41200CFE393 /* MinimedPacket.swift */, + ); + path = Radio; + sourceTree = ""; + }; + 4352A70E20DEC47800CAC200 /* Models */ = { + isa = PBXGroup; + children = ( + C1F000511EBE73F400F65163 /* BasalSchedule.swift */, + C1EAD6E11C82BA7A006DBA60 /* CRC16.swift */, + 54BC447B1DB4742F00340EED /* GlucoseEventType.swift */, + 54BC44741DB46B0A00340EED /* GlucosePage.swift */, + C1EB955C1C887FE5002517DF /* HistoryPage.swift */, + C1EAD6AE1C826B6D006DBA60 /* MySentryAlertType.swift */, + C1A721651EC4BCE30080FAD7 /* PartialDecode.swift */, + C1842BBE1C8E855A00DB42AC /* PumpEventType.swift */, + 541688DE1DB82E72005B1891 /* TimestampedGlucoseEvent.swift */, + 43B0ADC11D12454700AAD278 /* TimestampedHistoryEvent.swift */, + ); + path = Models; + sourceTree = ""; + }; + 4352A72620DEC9B700CAC200 /* MinimedKitUI */ = { + isa = PBXGroup; + children = ( + 4352A72720DEC9B700CAC200 /* MinimedKitUI.h */, + 4352A72820DEC9B700CAC200 /* Info.plist */, + 43709AC820DF1C9A00F941B3 /* MinimedKitUI.xcassets */, + 43709AE020DF1D5400F941B3 /* MinimedPumpManager.storyboard */, + 43709ACC20DF1CC900F941B3 /* Setup */, + 4352A73120DEC9D600CAC200 /* CommandResponseViewController.swift */, + 435535D71FB7987000CE5A23 /* PumpOps.swift */, + 4352A73820DECBAA00CAC200 /* RileyLinkMinimedDeviceTableViewController.swift */, + 43709AC320DF1C8B00F941B3 /* MinimedPumpManager+UI.swift */, + 43709AC220DF1C8B00F941B3 /* MinimedPumpSettingsViewController.swift */, + 43709AC020DF1C8B00F941B3 /* PumpModel.swift */, + 43709AC120DF1C8B00F941B3 /* RadioSelectionTableViewController.swift */, + ); + path = MinimedKitUI; + sourceTree = ""; + }; + 43709ACC20DF1CC900F941B3 /* Setup */ = { + isa = PBXGroup; + children = ( + 43709ACF20DF1CF700F941B3 /* MinimedPumpManagerSetupViewController.swift */, + 43709ACE20DF1CF700F941B3 /* MinimedPumpIDSetupViewController.swift */, + 43709AD020DF1CF700F941B3 /* MinimedPumpSentrySetupViewController.swift */, + 43709ACD20DF1CF700F941B3 /* MinimedPumpClockSetupViewController.swift */, + 43709AD220DF1CF800F941B3 /* MinimedPumpSettingsSetupViewController.swift */, + 43709AD120DF1CF700F941B3 /* MinimedPumpSetupCompleteViewController.swift */, + ); + path = Setup; + sourceTree = ""; + }; 43722FAF1CB9F7630038B7F2 /* RileyLinkKit */ = { isa = PBXGroup; children = ( 7D7076831FE092D7004AC8EA /* InfoPlist.strings */, 7D7076741FE092D5004AC8EA /* Localizable.strings */, - C170C98C1CECD6CE00F3D8E5 /* Extensions */, 43722FB01CB9F7640038B7F2 /* RileyLinkKit.h */, 43722FB21CB9F7640038B7F2 /* Info.plist */, 437F54061FBD52120070FF2C /* DeviceState.swift */, - 2F962EC21E6873A10070EFBD /* PumpMessageSender.swift */, - 434AB0921CBA0DF600422F4A /* PumpOps.swift */, - C1A7215F1EC29C0B0080FAD7 /* PumpOpsError.swift */, - 434AB0931CBA0DF600422F4A /* PumpOpsSession.swift */, - 4384C8C71FB937E500D916E6 /* PumpSettings.swift */, - 434AB0941CBA0DF600422F4A /* PumpState.swift */, + 43323EA91FA81C1B003FB0FA /* RileyLinkDevice.swift */, + 4352A74020DED23000CAC200 /* RileyLinkDeviceManager.swift */, + 435D26AF20DA08CE00891C17 /* RileyLinkPumpManager.swift */, + 435D26B120DA091B00891C17 /* RileyLinkPumpManagerState.swift */, ); path = RileyLinkKit; sourceTree = ""; @@ -1070,8 +1331,6 @@ 43722FBD1CB9F7640038B7F2 /* RileyLinkKitTests */ = { isa = PBXGroup; children = ( - 2F962EC41E705C6D0070EFBD /* PumpOpsSynchronousBuildFromFramesTests.swift */, - 2F962EBE1E678BAA0070EFBD /* PumpOpsSynchronousTests.swift */, 43722FC01CB9F7640038B7F2 /* Info.plist */, ); path = RileyLinkKitTests; @@ -1093,31 +1352,71 @@ children = ( 43D5E7901FAF7BFB004ACDB7 /* RileyLinkKitUI.h */, 43D5E7911FAF7BFB004ACDB7 /* Info.plist */, + 43709AEB20E0056F00F941B3 /* RileyLinkKitUI.xcassets */, C170C98D1CECD6F300F3D8E5 /* CBPeripheralState.swift */, - C1C659181E16BA9D0025CC58 /* CaseCountable.swift */, C170C9961CECD80000F3D8E5 /* CommandResponseViewController.swift */, - 435535D91FB836CB00CE5A23 /* CommandResponseViewController+RileyLinkDevice.swift */, - 435535D71FB7987000CE5A23 /* PumpOps.swift */, - 437F54081FBF9E0A0070FF2C /* RileyLinkDevice.swift */, 439731261CF21C3C00F474E5 /* RileyLinkDeviceTableViewCell.swift */, C170C9981CECD80000F3D8E5 /* RileyLinkDeviceTableViewController.swift */, - C1B4A9521D1E613A003B8985 /* TextFieldTableViewCell.swift */, - C1B4A9531D1E613A003B8985 /* TextFieldTableViewCell.xib */, - C1B4A9541D1E613A003B8985 /* TextFieldTableViewController.swift */, + 435D26B320DA0AAE00891C17 /* RileyLinkDevicesHeaderView.swift */, + 435D26B520DA0BCC00891C17 /* RileyLinkDevicesTableViewDataSource.swift */, + 43709ABB20DF1C6400F941B3 /* RileyLinkManagerSetupViewController.swift */, + 43709ABC20DF1C6400F941B3 /* RileyLinkSettingsViewController.swift */, + 43709ABA20DF1C6400F941B3 /* RileyLinkSetupTableViewController.swift */, + 43709AED20E008F300F941B3 /* SetupImageTableViewCell.swift */, + 43709AEF20E0120F00F941B3 /* SetupImageTableViewCell.xib */, C1B4A9581D1E6357003B8985 /* UITableViewCell.swift */, ); path = RileyLinkKitUI; sourceTree = ""; }; + 43D8708920DE1B99006B549E /* PumpManager */ = { + isa = PBXGroup; + children = ( + 43BF58B11FF5A22200499C46 /* BasalProfile.swift */, + 436CCEF11FB953E800A6822B /* CommandSession.swift */, + 43D8708C20DE1C05006B549E /* DoseStore.swift */, + 43D8708E20DE1C23006B549E /* EnliteSensorDisplayable.swift */, + 4384C8C51FB92F8100D916E6 /* HistoryPage+PumpOpsSession.swift */, + 43D870A120DE1DCF006B549E /* InsulinDataSource.swift */, + 43D8709820DE1CB6006B549E /* MinimedPumpManager.swift */, + 43D8709920DE1CB6006B549E /* MinimedPumpManagerError.swift */, + 43D8709A20DE1CB6006B549E /* MinimedPumpManagerState.swift */, + 2F962EC21E6873A10070EFBD /* PumpMessageSender.swift */, + 435535DB1FB8B37E00CE5A23 /* PumpMessage+PumpOpsSession.swift */, + 434AB0921CBA0DF600422F4A /* PumpOps.swift */, + C1A7215F1EC29C0B0080FAD7 /* PumpOpsError.swift */, + 434AB0931CBA0DF600422F4A /* PumpOpsSession.swift */, + 43D8709220DE1C80006B549E /* PumpOpsSession+LoopKit.swift */, + 4384C8C71FB937E500D916E6 /* PumpSettings.swift */, + 434AB0941CBA0DF600422F4A /* PumpState.swift */, + 43D8709420DE1C91006B549E /* RileyLinkDevice.swift */, + ); + path = PumpManager; + sourceTree = ""; + }; + 43D8709E20DE1CF5006B549E /* CGMManager */ = { + isa = PBXGroup; + children = ( + 43D8709020DE1C3B006B549E /* MySentryPumpStatusMessageBody+CGMManager.swift */, + 43D8709620DE1CA1006B549E /* SensorValueGlucoseEvent+CGMManager.swift */, + ); + path = CGMManager; + sourceTree = ""; + }; 43EBE44F1EAD234F0073A0B5 /* Common */ = { isa = PBXGroup; children = ( + C1C659181E16BA9D0025CC58 /* CaseCountable.swift */, C1EAD6BA1C826B92006DBA60 /* Data.swift */, + 4352A73D20DED01700CAC200 /* HKUnit.swift */, 431185AE1CF25A590059ED98 /* IdentifiableClass.swift */, + 435D26B720DC83E400891C17 /* Locked.swift */, + C14FFC5A1D3D74F90049CF85 /* NibLoadable.swift */, 43323EA61FA81A0F003FB0FA /* NumberFormatter.swift */, 431CE7941F9B0DAE00255374 /* OSLog.swift */, 43EBE4501EAD238C0073A0B5 /* TimeInterval.swift */, 4345D1CD1DA16AF300BAAD22 /* TimeZone.swift */, + C14FFC601D3D75470049CF85 /* UIColor.swift */, ); path = Common; sourceTree = ""; @@ -1176,33 +1475,16 @@ children = ( 7D70768D1FE09310004AC8EA /* Localizable.strings */, 7D70767E1FE092D6004AC8EA /* InfoPlist.strings */, + 43D8709E20DE1CF5006B549E /* CGMManager */, C1EAD6B81C826B92006DBA60 /* Extensions */, - C1EAD6BC1C826B92006DBA60 /* Messages */, 54BC44761DB46C3100340EED /* GlucoseEvents */, + C1EAD6BC1C826B92006DBA60 /* Messages */, + 4352A70C20DEC3A900CAC200 /* Models */, C1842BB91C8E15C600DB42AC /* PumpEvents */, - C1EAD6AE1C826B6D006DBA60 /* AlertType.swift */, - C1F000511EBE73F400F65163 /* BasalSchedule.swift */, - C1C73F1C1DE6306A0022FC89 /* BatteryChemistryType.swift */, - C1EAD6DD1C82B78C006DBA60 /* CRC8.swift */, - C1EAD6E11C82BA7A006DBA60 /* CRC16.swift */, - C1F6EB881F89C3E200CFE393 /* FourByteSixByteEncoding.swift */, - 54BC447B1DB4742F00340EED /* GlucoseEventType.swift */, - 54BC44741DB46B0A00340EED /* GlucosePage.swift */, - C1EB955C1C887FE5002517DF /* HistoryPage.swift */, + 43D8708920DE1B99006B549E /* PumpManager */, + 4352A70D20DEC42800CAC200 /* Radio */, C10D9BC51C8269D500378342 /* Info.plist */, - C1EAD6AF1C826B6D006DBA60 /* MessageBody.swift */, - C1EAD6B01C826B6D006DBA60 /* MessageType.swift */, - C1C3578E1C927303009BDD4F /* MeterMessage.swift */, C10D9BC31C8269D500378342 /* MinimedKit.h */, - C1F6EB8A1F89C41200CFE393 /* MinimedPacket.swift */, - C1EAD6B11C826B6D006DBA60 /* PacketType.swift */, - C1842BBE1C8E855A00DB42AC /* PumpEventType.swift */, - C1EAD6B21C826B6D006DBA60 /* PumpMessage.swift */, - C1842BBA1C8E184300DB42AC /* PumpModel.swift */, - C1274F851D8242BE0002912B /* PumpRegion.swift */, - 43B0ADC11D12454700AAD278 /* TimestampedHistoryEvent.swift */, - 541688DE1DB82E72005B1891 /* TimestampedGlucoseEvent.swift */, - C1A721651EC4BCE30080FAD7 /* PartialDecode.swift */, ); path = MinimedKit; sourceTree = ""; @@ -1225,6 +1507,8 @@ 43FF221B1CB9B9DE00024F30 /* NSDateComponents.swift */, 43B0ADBF1D0FC03200AAD278 /* NSDateComponentsTests.swift */, 2F962EC91E70831F0070EFBD /* PumpModelTests.swift */, + 2F962EC41E705C6D0070EFBD /* PumpOpsSynchronousBuildFromFramesTests.swift */, + 2F962EBE1E678BAA0070EFBD /* PumpOpsSynchronousTests.swift */, 54BC44B41DB7184D00340EED /* NSStringExtensions.swift */, 2F962EC01E6872170070EFBD /* TimestampedHistoryEventTests.swift */, ); @@ -1307,6 +1591,7 @@ 431CE7701F98564100255374 /* RileyLinkBLEKit */, 431CE77D1F98564200255374 /* RileyLinkBLEKitTests */, 43D5E78F1FAF7BFB004ACDB7 /* RileyLinkKitUI */, + 4352A72620DEC9B700CAC200 /* MinimedKitUI */, C12EA239198B436800309FA4 /* Frameworks */, C12EA238198B436800309FA4 /* Products */, ); @@ -1327,6 +1612,7 @@ 431CE76F1F98564100255374 /* RileyLinkBLEKit.framework */, 431CE7771F98564200255374 /* RileyLinkBLEKitTests.xctest */, 43D5E78E1FAF7BFB004ACDB7 /* RileyLinkKitUI.framework */, + 4352A72520DEC9B700CAC200 /* MinimedKitUI.framework */, ); name = Products; sourceTree = ""; @@ -1334,6 +1620,8 @@ C12EA239198B436800309FA4 /* Frameworks */ = { isa = PBXGroup; children = ( + 43FB610B20DDF55F002B996B /* LoopKit.framework */, + 43FB610A20DDF55E002B996B /* LoopKitUI.framework */, 43CA93241CB8BB33000026B5 /* CoreBluetooth.framework */, 4370A3791FAF8A7400EC666A /* CoreBluetooth.framework */, C12616431B685F0A001FAD87 /* CoreData.framework */, @@ -1407,18 +1695,6 @@ path = Models; sourceTree = ""; }; - C170C98C1CECD6CE00F3D8E5 /* Extensions */ = { - isa = PBXGroup; - children = ( - 43BF58B11FF5A22200499C46 /* BasalProfile.swift */, - 436CCEF11FB953E800A6822B /* CommandSession.swift */, - 4384C8C51FB92F8100D916E6 /* HistoryPage.swift */, - 435535DB1FB8B37E00CE5A23 /* PumpMessage.swift */, - 43323EA91FA81C1B003FB0FA /* RileyLinkDevice.swift */, - ); - path = Extensions; - sourceTree = ""; - }; C1842BB91C8E15C600DB42AC /* PumpEvents */ = { isa = PBXGroup; children = ( @@ -1498,11 +1774,9 @@ isa = PBXGroup; children = ( C17884601D519F1E00405663 /* BatteryIndicator.swift */, - C14FFC5A1D3D74F90049CF85 /* NibLoadable.swift */, C1E535E81991E36700C2AC49 /* NSData+Conversion.h */, C1E535E91991E36700C2AC49 /* NSData+Conversion.m */, 437462381FA9287A00643383 /* RileyLinkDevice.swift */, - C14FFC601D3D75470049CF85 /* UIColor.swift */, C14FFC541D3D72A50049CF85 /* UIViewController.swift */, 435535D51FB6D98400CE5A23 /* UserDefaults.swift */, ); @@ -1597,6 +1871,10 @@ C1EAD6BC1C826B92006DBA60 /* Messages */ = { isa = PBXGroup; children = ( + C1EAD6B21C826B6D006DBA60 /* PumpMessage.swift */, + C1EAD6B11C826B6D006DBA60 /* PacketType.swift */, + C1EAD6B01C826B6D006DBA60 /* MessageType.swift */, + 4352A70E20DEC47800CAC200 /* Models */, C121989E1C8DFC2200BC374C /* BolusCarelinkMessageBody.swift */, C1711A551C94F13400CB25BD /* ButtonPressCarelinkMessageBody.swift */, C1EAD6BD1C826B92006DBA60 /* CarelinkMessageBody.swift */, @@ -1612,6 +1890,8 @@ 54BC44B81DB81D6100340EED /* GetGlucosePageMessageBody.swift */, C1711A5D1C977BD000CB25BD /* GetHistoryPageCarelinkMessageBody.swift */, C1711A591C952D2900CB25BD /* GetPumpModelCarelinkMessageBody.swift */, + C1EAD6AF1C826B6D006DBA60 /* MessageBody.swift */, + C1C3578E1C927303009BDD4F /* MeterMessage.swift */, C1EAD6BE1C826B92006DBA60 /* MySentryAckMessageBody.swift */, C1EAD6BF1C826B92006DBA60 /* MySentryAlertClearedMessageBody.swift */, C1EAD6C01C826B92006DBA60 /* MySentryAlertMessageBody.swift */, @@ -1647,6 +1927,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4352A72220DEC9B700CAC200 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4352A72920DEC9B700CAC200 /* MinimedKitUI.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 43722FAB1CB9F7630038B7F2 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -1727,6 +2015,25 @@ productReference = 431CE7771F98564200255374 /* RileyLinkBLEKitTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 4352A72420DEC9B700CAC200 /* MinimedKitUI */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4352A72E20DEC9B700CAC200 /* Build configuration list for PBXNativeTarget "MinimedKitUI" */; + buildPhases = ( + 4352A72020DEC9B700CAC200 /* Sources */, + 4352A72120DEC9B700CAC200 /* Frameworks */, + 4352A72220DEC9B700CAC200 /* Headers */, + 4352A72320DEC9B700CAC200 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 4352A73620DECAE900CAC200 /* PBXTargetDependency */, + ); + name = MinimedKitUI; + productName = MinimedKitUI; + productReference = 4352A72520DEC9B700CAC200 /* MinimedKitUI.framework */; + productType = "com.apple.product-type.framework"; + }; 43722FAD1CB9F7630038B7F2 /* RileyLinkKit */ = { isa = PBXNativeTarget; buildConfigurationList = 43722FC91CB9F7640038B7F2 /* Build configuration list for PBXNativeTarget "RileyLinkKit" */; @@ -1739,6 +2046,7 @@ buildRules = ( ); dependencies = ( + 4352A71120DEC67300CAC200 /* PBXTargetDependency */, ); name = RileyLinkKit; productName = RileyLinkKit; @@ -1757,6 +2065,7 @@ ); dependencies = ( 43722FBA1CB9F7640038B7F2 /* PBXTargetDependency */, + 4327EEBB20E1E562002598CB /* PBXTargetDependency */, ); name = RileyLinkKitTests; productName = RileyLinkKitTests; @@ -1793,6 +2102,7 @@ buildRules = ( ); dependencies = ( + 43FB610920DDF509002B996B /* PBXTargetDependency */, ); name = RileyLinkKitUI; productName = RileyLinkKitUI; @@ -1811,6 +2121,7 @@ buildRules = ( ); dependencies = ( + 4352A71420DEC68700CAC200 /* PBXTargetDependency */, ); name = MinimedKit; productName = MinimedKit; @@ -1829,6 +2140,7 @@ ); dependencies = ( C10D9BCD1C8269D500378342 /* PBXTargetDependency */, + 4327EEB920E1E55D002598CB /* PBXTargetDependency */, ); name = MinimedKitTests; productName = MinimedKitTests; @@ -1843,16 +2155,19 @@ C12EA234198B436800309FA4 /* Frameworks */, C12EA235198B436800309FA4 /* Resources */, C10D9BB81C82614F00378342 /* Embed Frameworks */, + 4352A74E20DEDD7C00CAC200 /* Copy Frameworks with Carthage */, ); buildRules = ( ); dependencies = ( + 4352A74520DED49C00CAC200 /* PBXTargetDependency */, 43C246A31D891D6C0031F8D1 /* PBXTargetDependency */, C10D9BD51C8269D500378342 /* PBXTargetDependency */, 43722FC21CB9F7640038B7F2 /* PBXTargetDependency */, C1B3831F1CD0665D00CE7782 /* PBXTargetDependency */, 431CE7831F98564200255374 /* PBXTargetDependency */, 43D5E7941FAF7BFB004ACDB7 /* PBXTargetDependency */, + 4352A72B20DEC9B700CAC200 /* PBXTargetDependency */, ); name = RileyLink; productName = RileyLink; @@ -1936,6 +2251,11 @@ ProvisioningStyle = Automatic; TestTargetID = C12EA236198B436800309FA4; }; + 4352A72420DEC9B700CAC200 = { + CreatedOnToolsVersion = 9.4.1; + LastSwiftMigration = 0940; + ProvisioningStyle = Automatic; + }; 43722FAD1CB9F7630038B7F2 = { CreatedOnToolsVersion = 7.3; LastSwiftMigration = 0900; @@ -1943,6 +2263,7 @@ 43722FB61CB9F7640038B7F2 = { CreatedOnToolsVersion = 7.3; LastSwiftMigration = 0900; + TestTargetID = C12EA236198B436800309FA4; }; 43C246921D8918AE0031F8D1 = { CreatedOnToolsVersion = 8.0; @@ -1952,6 +2273,10 @@ CreatedOnToolsVersion = 9.2; ProvisioningStyle = Automatic; }; + 43FB610120DDEF26002B996B = { + CreatedOnToolsVersion = 9.4.1; + ProvisioningStyle = Automatic; + }; C10D9BC01C8269D500378342 = { CreatedOnToolsVersion = 7.2.1; LastSwiftMigration = 0900; @@ -1959,6 +2284,7 @@ C10D9BC91C8269D500378342 = { CreatedOnToolsVersion = 7.2.1; LastSwiftMigration = 0900; + TestTargetID = C12EA236198B436800309FA4; }; C12EA236198B436800309FA4 = { LastSwiftMigration = 0900; @@ -1986,6 +2312,7 @@ en, es, ru, + Base, ); mainGroup = C12EA22E198B436800309FA4; productRefGroup = C12EA238198B436800309FA4 /* Products */; @@ -2004,6 +2331,8 @@ 431CE76E1F98564100255374 /* RileyLinkBLEKit */, 431CE7761F98564200255374 /* RileyLinkBLEKitTests */, 43D5E78D1FAF7BFB004ACDB7 /* RileyLinkKitUI */, + 4352A72420DEC9B700CAC200 /* MinimedKitUI */, + 43FB610120DDEF26002B996B /* Cartfile */, ); }; /* End PBXProject section */ @@ -2023,6 +2352,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4352A72320DEC9B700CAC200 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 43709ADE20DF1D5400F941B3 /* MinimedPumpManager.storyboard in Resources */, + 43709AC920DF1C9A00F941B3 /* MinimedKitUI.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 43722FAC1CB9F7630038B7F2 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -2051,7 +2389,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4370A37E1FAF8EF200EC666A /* TextFieldTableViewCell.xib in Resources */, + 43709AEC20E0056F00F941B3 /* RileyLinkKitUI.xcassets in Resources */, + 43709AF020E0120F00F941B3 /* SetupImageTableViewCell.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2111,6 +2450,41 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + 4352A74E20DEDD7C00CAC200 /* Copy Frameworks with Carthage */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "$(SRCROOT)/Carthage/Build/iOS/LoopKit.framework", + "$(SRCROOT)/Carthage/Build/iOS/LoopKitUI.framework", + ); + name = "Copy Frameworks with Carthage"; + outputPaths = ( + "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/LoopKit.framework", + "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/LoopKitUI.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/usr/local/bin/carthage copy-frameworks"; + }; + 43FB610520DDEF32002B996B /* Build Carthage Dependencies */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Build Carthage Dependencies"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if [ -f $PROJECT_DIR/.gitmodules ]; then\n echo \"Skipping checkout due to presence of .gitmodules file\"\n if [ $ACTION = \"install\" ]; then\n echo \"You're installing: Make sure to keep all submodules up-to-date and run carthage build after changes.\"\n fi\nelse\n echo \"Bootstrapping carthage dependencies\"\n /usr/local/bin/carthage bootstrap --project-directory \"$SRCROOT\" --cache-builds\nfi"; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 431CE76A1F98564100255374 /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -2148,26 +2522,45 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4352A72020DEC9B700CAC200 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4352A73720DECB7300CAC200 /* PumpOps.swift in Sources */, + 43709AD420DF1CF800F941B3 /* MinimedPumpIDSetupViewController.swift in Sources */, + 43709AD520DF1CF800F941B3 /* MinimedPumpManagerSetupViewController.swift in Sources */, + 43709AD320DF1CF800F941B3 /* MinimedPumpClockSetupViewController.swift in Sources */, + 43709AC420DF1C8B00F941B3 /* PumpModel.swift in Sources */, + 43709AD820DF1CF800F941B3 /* MinimedPumpSettingsSetupViewController.swift in Sources */, + 43709AD720DF1CF800F941B3 /* MinimedPumpSetupCompleteViewController.swift in Sources */, + 43709AD620DF1CF800F941B3 /* MinimedPumpSentrySetupViewController.swift in Sources */, + 43709AE720DF22E400F941B3 /* UIColor.swift in Sources */, + 43709AE320DF20D400F941B3 /* OSLog.swift in Sources */, + 43709AE120DF1F0D00F941B3 /* IdentifiableClass.swift in Sources */, + 4352A74320DED3F200CAC200 /* NumberFormatter.swift in Sources */, + 4352A73220DEC9D600CAC200 /* CommandResponseViewController.swift in Sources */, + 43709AC520DF1C8B00F941B3 /* RadioSelectionTableViewController.swift in Sources */, + 4352A73920DECBAA00CAC200 /* RileyLinkMinimedDeviceTableViewController.swift in Sources */, + 4352A74220DED3D200CAC200 /* CaseCountable.swift in Sources */, + 43709AC620DF1C8B00F941B3 /* MinimedPumpSettingsViewController.swift in Sources */, + 43709AC720DF1C8B00F941B3 /* MinimedPumpManager+UI.swift in Sources */, + 43709AE220DF1FDD00F941B3 /* UITableViewCell.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 43722FA91CB9F7630038B7F2 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4384C8C81FB937E500D916E6 /* PumpSettings.swift in Sources */, - 434AB0961CBA0DF600422F4A /* PumpOps.swift in Sources */, 43323EAA1FA81C1B003FB0FA /* RileyLinkDevice.swift in Sources */, 43EBE4531EAD23CE0073A0B5 /* TimeInterval.swift in Sources */, - 436CCEF21FB953E800A6822B /* CommandSession.swift in Sources */, - C1A721601EC29C0B0080FAD7 /* PumpOpsError.swift in Sources */, 434AB0C71CBCB76400422F4A /* Data.swift in Sources */, - 4384C8C61FB92F8100D916E6 /* HistoryPage.swift in Sources */, - 434AB0981CBA0DF600422F4A /* PumpState.swift in Sources */, + 4352A74120DED23100CAC200 /* RileyLinkDeviceManager.swift in Sources */, + 435D26B220DA091C00891C17 /* RileyLinkPumpManagerState.swift in Sources */, 431CE7961F9B0F0200255374 /* OSLog.swift in Sources */, 437F54071FBD52120070FF2C /* DeviceState.swift in Sources */, - 435535DC1FB8B37E00CE5A23 /* PumpMessage.swift in Sources */, - 434AB0971CBA0DF600422F4A /* PumpOpsSession.swift in Sources */, - 2F962EC31E6873A10070EFBD /* PumpMessageSender.swift in Sources */, - 43BF58B21FF5A22200499C46 /* BasalProfile.swift in Sources */, - 4345D1CE1DA16AF300BAAD22 /* TimeZone.swift in Sources */, + 435D26B020DA08CE00891C17 /* RileyLinkPumpManager.swift in Sources */, + 435D26B920DC83F300891C17 /* Locked.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2175,10 +2568,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 2F962EBF1E678BAA0070EFBD /* PumpOpsSynchronousTests.swift in Sources */, 4384C8C91FB941FB00D916E6 /* TimeInterval.swift in Sources */, 43A9E50E1F6B865000307931 /* Data.swift in Sources */, - 2F962EC51E705C6E0070EFBD /* PumpOpsSynchronousBuildFromFramesTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2195,21 +2586,24 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 43D5E79E1FAF7C47004ACDB7 /* TextFieldTableViewController.swift in Sources */, 43BF58B31FF6079600499C46 /* TimeInterval.swift in Sources */, - 437F54091FBF9E0A0070FF2C /* RileyLinkDevice.swift in Sources */, - 435535DA1FB836CB00CE5A23 /* CommandResponseViewController+RileyLinkDevice.swift in Sources */, 43D5E7A11FAF7CE0004ACDB7 /* UITableViewCell.swift in Sources */, + 43709AEE20E008F300F941B3 /* SetupImageTableViewCell.swift in Sources */, + 43709AF120E0127000F941B3 /* NibLoadable.swift in Sources */, 43D5E7A31FAF7D05004ACDB7 /* CBPeripheralState.swift in Sources */, 43D5E7A21FAF7CF2004ACDB7 /* CaseCountable.swift in Sources */, - 43D5E7A41FAF7D4D004ACDB7 /* TimeZone.swift in Sources */, + 435D26B620DA0BCC00891C17 /* RileyLinkDevicesTableViewDataSource.swift in Sources */, + 43709AE820DF22E700F941B3 /* UIColor.swift in Sources */, 43D5E79A1FAF7C47004ACDB7 /* RileyLinkDeviceTableViewCell.swift in Sources */, 43D5E79F1FAF7C98004ACDB7 /* IdentifiableClass.swift in Sources */, + 435D26B420DA0AAE00891C17 /* RileyLinkDevicesHeaderView.swift in Sources */, 43D5E79B1FAF7C47004ACDB7 /* CommandResponseViewController.swift in Sources */, - 435535D81FB7987000CE5A23 /* PumpOps.swift in Sources */, + 43709ABF20DF1C6400F941B3 /* RileyLinkSettingsViewController.swift in Sources */, + 43709ABD20DF1C6400F941B3 /* RileyLinkSetupTableViewController.swift in Sources */, 43D5E79C1FAF7C47004ACDB7 /* RileyLinkDeviceTableViewController.swift in Sources */, + 43709ABE20DF1C6400F941B3 /* RileyLinkManagerSetupViewController.swift in Sources */, 43D5E7A01FAF7CCA004ACDB7 /* NumberFormatter.swift in Sources */, - 43D5E79D1FAF7C47004ACDB7 /* TextFieldTableViewCell.swift in Sources */, + 43709AE420DF20D500F941B3 /* OSLog.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2217,6 +2611,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 4352A71520DEC72500CAC200 /* PumpMessageSender.swift in Sources */, C1842C1C1C8FA45100DB42AC /* ChangeBGReminderOffsetPumpEvent.swift in Sources */, C1842BD11C8FA3D200DB42AC /* AlarmClockReminderPumpEvent.swift in Sources */, 43DAD00220A6A470000F8529 /* ReadOtherDevicesStatusMessageBody.swift in Sources */, @@ -2230,6 +2625,7 @@ C1842BFF1C8FA45100DB42AC /* DailyTotal522PumpEvent.swift in Sources */, C1842C1A1C8FA45100DB42AC /* ChangeBolusReminderTimePumpEvent.swift in Sources */, C12198B31C8F730700BC374C /* BolusWizardEstimatePumpEvent.swift in Sources */, + 4352A73F20DED02C00CAC200 /* HKUnit.swift in Sources */, C1842BBF1C8E855A00DB42AC /* PumpEventType.swift in Sources */, C1842BC11C8E8B2500DB42AC /* UnabsorbedInsulinPumpEvent.swift in Sources */, C1EAD6B51C826B6D006DBA60 /* MessageType.swift in Sources */, @@ -2248,6 +2644,7 @@ C1274F771D8232580002912B /* DailyTotal515PumpEvent.swift in Sources */, C1842C0B1C8FA45100DB42AC /* ChangeTimePumpEvent.swift in Sources */, C1842C0D1C8FA45100DB42AC /* TempBasalPumpEvent.swift in Sources */, + 43D870A220DE1DCF006B549E /* InsulinDataSource.swift in Sources */, C178845D1D4EF3D800405663 /* ReadPumpStatusMessageBody.swift in Sources */, 54BC447C1DB4742F00340EED /* GlucoseEventType.swift in Sources */, 43B0ADCB1D126B1100AAD278 /* SelectBasalProfilePumpEvent.swift in Sources */, @@ -2263,7 +2660,7 @@ C1842C181C8FA45100DB42AC /* BolusWizardSetupPumpEvent.swift in Sources */, C1274F791D823A550002912B /* ChangeMeterIDPumpEvent.swift in Sources */, C1842C201C8FA45100DB42AC /* ChangeAudioBolusPumpEvent.swift in Sources */, - C1EAD6B31C826B6D006DBA60 /* AlertType.swift in Sources */, + C1EAD6B31C826B6D006DBA60 /* MySentryAlertType.swift in Sources */, C1842C051C8FA45100DB42AC /* DeleteBolusReminderTimePumpEvent.swift in Sources */, C1711A5C1C953F3000CB25BD /* GetBatteryCarelinkMessageBody.swift in Sources */, C1842C1D1C8FA45100DB42AC /* ChangeBGReminderEnablePumpEvent.swift in Sources */, @@ -2275,6 +2672,7 @@ C1F6EB871F89C3B100CFE393 /* CRC8.swift in Sources */, 43DAD00420A6A677000F8529 /* ReadOtherDevicesIDsMessageBody.swift in Sources */, 546A85D81DF7C83A00733213 /* SensorDataHighGlucoseEvent.swift in Sources */, + 43D8709D20DE1CB6006B549E /* MinimedPumpManagerState.swift in Sources */, C1842C091C8FA45100DB42AC /* ChangeWatchdogEnablePumpEvent.swift in Sources */, C1842BC91C8F968B00DB42AC /* BGReceivedPumpEvent.swift in Sources */, C1842C0F1C8FA45100DB42AC /* ChangeSensorRateOfChangeAlertSetupPumpEvent.swift in Sources */, @@ -2283,6 +2681,7 @@ 43CA93291CB8CF22000026B5 /* ChangeTempBasalCarelinkMessageBody.swift in Sources */, C1EAD6CD1C826B92006DBA60 /* PowerOnCarelinkMessageBody.swift in Sources */, 43CEC07620D099B400F1BC19 /* SetRemoteControlEnabledMessageBody.swift in Sources */, + 43D8709C20DE1CB6006B549E /* MinimedPumpManagerError.swift in Sources */, C1EAD6C81C826B92006DBA60 /* CarelinkMessageBody.swift in Sources */, C1A721621EC3E0500080FAD7 /* PumpErrorMessageBody.swift in Sources */, 546A85D41DF7BE1400733213 /* SensorErrorGlucoseEvent.swift in Sources */, @@ -2290,8 +2689,10 @@ 433568761CF67FA800FD9D54 /* ReadRemainingInsulinMessageBody.swift in Sources */, 54BC44941DB47CFB00340EED /* SensorStatusGlucoseEvent.swift in Sources */, C1842C231C8FA45100DB42AC /* ChangeAlarmClockEnablePumpEvent.swift in Sources */, + 4352A71720DEC78B00CAC200 /* PumpState.swift in Sources */, 54BC44821DB476BB00340EED /* CalBGForGHGlucoseEvent.swift in Sources */, C1EAD6CF1C826B92006DBA60 /* UnknownMessageBody.swift in Sources */, + 43D8708B20DE1BCA006B549E /* PumpColor.swift in Sources */, C1842C161C8FA45100DB42AC /* ChangeCarbUnitsPumpEvent.swift in Sources */, C1842C241C8FA45100DB42AC /* BatteryPumpEvent.swift in Sources */, C1842C1F1C8FA45100DB42AC /* ChangeBasalProfilePatternPumpEvent.swift in Sources */, @@ -2300,9 +2701,13 @@ 54BC447E1DB4753A00340EED /* GlucoseSensorDataGlucoseEvent.swift in Sources */, C1842BBD1C8E7C6E00DB42AC /* PumpEvent.swift in Sources */, 54DA4E851DFDC0A70007F489 /* SensorValueGlucoseEvent.swift in Sources */, + 4352A71C20DEC8C100CAC200 /* TimeZone.swift in Sources */, C1F6EB8B1F89C41200CFE393 /* MinimedPacket.swift in Sources */, C1842BCB1C8F9A7200DB42AC /* RewindPumpEvent.swift in Sources */, C1842BCD1C8F9BBD00DB42AC /* PrimePumpEvent.swift in Sources */, + 43D8709720DE1CA1006B549E /* SensorValueGlucoseEvent+CGMManager.swift in Sources */, + 43D8709520DE1C91006B549E /* RileyLinkDevice.swift in Sources */, + 4352A71820DEC7B900CAC200 /* PumpMessage+PumpOpsSession.swift in Sources */, C1842C071C8FA45100DB42AC /* ClearAlarmPumpEvent.swift in Sources */, C1A721661EC4BCE30080FAD7 /* PartialDecode.swift in Sources */, 43B0ADC21D12454700AAD278 /* TimestampedHistoryEvent.swift in Sources */, @@ -2315,6 +2720,7 @@ 54BC44751DB46B0A00340EED /* GlucosePage.swift in Sources */, C1EAD6C51C826B92006DBA60 /* Int.swift in Sources */, C1842C021C8FA45100DB42AC /* JournalEntryExerciseMarkerPumpEvent.swift in Sources */, + 43D870A520DE1E88006B549E /* PumpOpsError.swift in Sources */, 541688DF1DB82E72005B1891 /* TimestampedGlucoseEvent.swift in Sources */, 43BF58B01FF594CB00499C46 /* SelectBasalProfileMessageBody.swift in Sources */, C1EAD6CB1C826B92006DBA60 /* MySentryAlertMessageBody.swift in Sources */, @@ -2323,26 +2729,34 @@ 54BC44801DB4762200340EED /* TenSomethingGlucoseEvent.swift in Sources */, C1842BC71C8F8DC200DB42AC /* CalBGForPHPumpEvent.swift in Sources */, C1842C251C8FA45100DB42AC /* AlarmSensorPumpEvent.swift in Sources */, + 43D8709320DE1C80006B549E /* PumpOpsSession+LoopKit.swift in Sources */, C1842BBB1C8E184300DB42AC /* PumpModel.swift in Sources */, C14D2B091C9F5EDA00C98E4C /* ChangeTempBasalTypePumpEvent.swift in Sources */, C1842C1E1C8FA45100DB42AC /* ChangeBasalProfilePumpEvent.swift in Sources */, C14D2B051C9F5D5800C98E4C /* TempBasalDurationPumpEvent.swift in Sources */, C1842C151C8FA45100DB42AC /* ChangeChildBlockEnablePumpEvent.swift in Sources */, 438D39221D19011700D40CA4 /* PlaceholderPumpEvent.swift in Sources */, + 4352A71B20DEC7DC00CAC200 /* HistoryPage+PumpOpsSession.swift in Sources */, C1EAD6B41C826B6D006DBA60 /* MessageBody.swift in Sources */, + 4352A71620DEC78B00CAC200 /* PumpSettings.swift in Sources */, C1842C001C8FA45100DB42AC /* JournalEntryPumpLowReservoirPumpEvent.swift in Sources */, 54A840D11DB85D0600B1F202 /* UnknownGlucoseEvent.swift in Sources */, + 4352A71A20DEC7CB00CAC200 /* CommandSession.swift in Sources */, C1842BCF1C8F9E5100DB42AC /* PumpAlarmPumpEvent.swift in Sources */, + 43D8708F20DE1C23006B549E /* EnliteSensorDisplayable.swift in Sources */, C1EAD6C61C826B92006DBA60 /* Data.swift in Sources */, C1842C211C8FA45100DB42AC /* ChangeAlarmNotifyModePumpEvent.swift in Sources */, C1842BC31C8E931E00DB42AC /* BolusNormalPumpEvent.swift in Sources */, 541688DD1DB82213005B1891 /* ReadCurrentGlucosePageMessageBody.swift in Sources */, 43CA932F1CB8CFA1000026B5 /* ReadTimeCarelinkMessageBody.swift in Sources */, 43CEC07420D0949B00F1BC19 /* ReadRemoteControlIDsMessageBody.swift in Sources */, + 43D8708D20DE1C05006B549E /* DoseStore.swift in Sources */, 431CE7971F9B0F0200255374 /* OSLog.swift in Sources */, + 43D870A420DE1E88006B549E /* PumpOps.swift in Sources */, 2FDE1A071E57B12D00B56A27 /* ReadCurrentPageNumberMessageBody.swift in Sources */, 43EBE4521EAD23C40073A0B5 /* TimeInterval.swift in Sources */, 54BC44781DB46C7D00340EED /* GlucoseEvent.swift in Sources */, + 4352A71920DEC7C100CAC200 /* BasalProfile.swift in Sources */, 546A85D01DF7BB8B00733213 /* SensorPacketGlucoseEvent.swift in Sources */, C1842BFD1C8FA45100DB42AC /* ResumePumpEvent.swift in Sources */, C1EAD6CC1C826B92006DBA60 /* MySentryPumpStatusMessageBody.swift in Sources */, @@ -2353,13 +2767,16 @@ C1EAD6E21C82BA7A006DBA60 /* CRC16.swift in Sources */, C1711A5E1C977BD000CB25BD /* GetHistoryPageCarelinkMessageBody.swift in Sources */, C14303161C97C98000A40450 /* PumpAckMessageBody.swift in Sources */, + 43D870A320DE1E1E006B549E /* PumpOpsSession.swift in Sources */, C1EAD6C71C826B92006DBA60 /* NSDateComponents.swift in Sources */, C1842C0E1C8FA45100DB42AC /* ChangeSensorSetup2PumpEvent.swift in Sources */, C1842C0A1C8FA45100DB42AC /* ChangeVariableBolusPumpEvent.swift in Sources */, C1C73F1D1DE6306A0022FC89 /* BatteryChemistryType.swift in Sources */, + 43D8709120DE1C3B006B549E /* MySentryPumpStatusMessageBody+CGMManager.swift in Sources */, C1842C191C8FA45100DB42AC /* ChangeBolusScrollStepSizePumpEvent.swift in Sources */, C1842C171C8FA45100DB42AC /* ChangeCaptureEventEnablePumpEvent.swift in Sources */, 54BC44B91DB81D6100340EED /* GetGlucosePageMessageBody.swift in Sources */, + 43D8709B20DE1CB6006B549E /* MinimedPumpManager.swift in Sources */, 43B0ADC41D12506A00AAD278 /* NSDateFormatter.swift in Sources */, 43CA932B1CB8CF76000026B5 /* ChangeTimeCarelinkMessageBody.swift in Sources */, 54B3F9021DFB984800B0ABFA /* DataEndGlucoseEvent.swift in Sources */, @@ -2386,7 +2803,9 @@ 43DFB61320D37800008A7BAE /* ChangeMaxBasalRateMessageBodyTests.swift in Sources */, C1EAD6D61C826C43006DBA60 /* MySentryPumpStatusMessageBodyTests.swift in Sources */, 43DAD00620A6B10A000F8529 /* ReadOtherDevicesIDsMessageBodyTests.swift in Sources */, + 4352A71F20DEC93300CAC200 /* PumpOpsSynchronousBuildFromFramesTests.swift in Sources */, C1EAD6D81C826C43006DBA60 /* ReadSettingsCarelinkMessageBodyTests.swift in Sources */, + 4352A74920DED81D00CAC200 /* Data.swift in Sources */, 43B0ADC01D0FC03200AAD278 /* NSDateComponentsTests.swift in Sources */, 546A85D21DF7BD5F00733213 /* SensorErrorGlucoseEventTests.swift in Sources */, C1C357911C92733A009BDD4F /* MeterMessageTests.swift in Sources */, @@ -2401,6 +2820,7 @@ 54BC44A91DB704A600340EED /* CalBGForGHGlucoseEventTests.swift in Sources */, C1F000501EBE727C00F65163 /* BasalScheduleTests.swift in Sources */, 43CEC07820D0CF7200F1BC19 /* ReadRemoteControlIDsMessageBodyTests.swift in Sources */, + 4352A71E20DEC93300CAC200 /* PumpOpsSynchronousTests.swift in Sources */, 43FF221C1CB9B9DE00024F30 /* NSDateComponents.swift in Sources */, C12198A31C8DFC3600BC374C /* BolusCarelinkMessageBodyTests.swift in Sources */, C121985F1C8DE77D00BC374C /* FindDeviceMessageBodyTests.swift in Sources */, @@ -2414,6 +2834,8 @@ 43CA93351CB9727F000026B5 /* ChangeTempBasalCarelinkMessageBodyTests.swift in Sources */, 54BC44B71DB81B5100340EED /* GetGlucosePageMessageBodyTests.swift in Sources */, 43DFB60D20D22CCB008A7BAE /* ChangeRemoteControlIDMessageBodyTests.swift in Sources */, + 4352A74820DED80300CAC200 /* TimeInterval.swift in Sources */, + 4352A71D20DEC8CC00CAC200 /* TimeZone.swift in Sources */, C1EAD6E01C82B910006DBA60 /* CRC8Tests.swift in Sources */, 2F962EC11E6872170070EFBD /* TimestampedHistoryEventTests.swift in Sources */, 54BC44B51DB7184D00340EED /* NSStringExtensions.swift in Sources */, @@ -2534,6 +2956,41 @@ target = 431CE76E1F98564100255374 /* RileyLinkBLEKit */; targetProxy = 431CE7821F98564200255374 /* PBXContainerItemProxy */; }; + 4327EEB920E1E55D002598CB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C12EA236198B436800309FA4 /* RileyLink */; + targetProxy = 4327EEB820E1E55D002598CB /* PBXContainerItemProxy */; + }; + 4327EEBB20E1E562002598CB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C12EA236198B436800309FA4 /* RileyLink */; + targetProxy = 4327EEBA20E1E562002598CB /* PBXContainerItemProxy */; + }; + 4352A71120DEC67300CAC200 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 43FB610120DDEF26002B996B /* Cartfile */; + targetProxy = 4352A71020DEC67300CAC200 /* PBXContainerItemProxy */; + }; + 4352A71420DEC68700CAC200 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 43FB610120DDEF26002B996B /* Cartfile */; + targetProxy = 4352A71320DEC68700CAC200 /* PBXContainerItemProxy */; + }; + 4352A72B20DEC9B700CAC200 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4352A72420DEC9B700CAC200 /* MinimedKitUI */; + targetProxy = 4352A72A20DEC9B700CAC200 /* PBXContainerItemProxy */; + }; + 4352A73620DECAE900CAC200 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 43FB610120DDEF26002B996B /* Cartfile */; + targetProxy = 4352A73520DECAE900CAC200 /* PBXContainerItemProxy */; + }; + 4352A74520DED49C00CAC200 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 43FB610120DDEF26002B996B /* Cartfile */; + targetProxy = 4352A74420DED49C00CAC200 /* PBXContainerItemProxy */; + }; 43722FBA1CB9F7640038B7F2 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 43722FAD1CB9F7630038B7F2 /* RileyLinkKit */; @@ -2559,6 +3016,11 @@ target = 43D5E78D1FAF7BFB004ACDB7 /* RileyLinkKitUI */; targetProxy = 43D5E7931FAF7BFB004ACDB7 /* PBXContainerItemProxy */; }; + 43FB610920DDF509002B996B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 43FB610120DDEF26002B996B /* Cartfile */; + targetProxy = 43FB610820DDF509002B996B /* PBXContainerItemProxy */; + }; C10D9BCD1C8269D500378342 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = C10D9BC01C8269D500378342 /* MinimedKit */; @@ -2592,6 +3054,14 @@ /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ + 43709AE020DF1D5400F941B3 /* MinimedPumpManager.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 43709ADF20DF1D5400F941B3 /* Base */, + ); + name = MinimedPumpManager.storyboard; + sourceTree = ""; + }; 7D70766F1FE092D4004AC8EA /* LoopKit.strings */ = { isa = PBXVariantGroup; children = ( @@ -2816,6 +3286,81 @@ }; name = Release; }; + 4352A72F20DEC9B700CAC200 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = MinimedKitUI/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.ps2.MinimedKitUI; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 4352A73020DEC9B700CAC200 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = MinimedKitUI/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = com.ps2.MinimedKitUI; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; 43722FC51CB9F7640038B7F2 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2832,6 +3377,10 @@ DYLIB_CURRENT_VERSION = 38; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = RileyLinkKit/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -2863,6 +3412,10 @@ DYLIB_CURRENT_VERSION = 38; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = RileyLinkKit/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -2885,6 +3438,10 @@ DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = ""; ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = RileyLinkKitTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -2892,6 +3449,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.RileyLinkKitTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RileyLink.app/RileyLink"; }; name = Debug; }; @@ -2905,12 +3463,17 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ""; ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = RileyLinkKitTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.RileyLinkKitTests; PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RileyLink.app/RileyLink"; }; name = Release; }; @@ -2981,13 +3544,16 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 38; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 38; DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = RileyLinkKitUI/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -2998,7 +3564,6 @@ SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSION_INFO_PREFIX = ""; }; @@ -3017,13 +3582,16 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 38; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 38; DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = RileyLinkKitUI/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -3032,12 +3600,27 @@ PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.RileyLinkKitUI; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; - SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSION_INFO_PREFIX = ""; }; name = Release; }; + 43FB610220DDEF26002B996B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 43FB610320DDEF26002B996B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; C10D9BD91C8269D600378342 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3054,6 +3637,10 @@ DYLIB_CURRENT_VERSION = 38; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = MinimedKit/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -3084,6 +3671,10 @@ DYLIB_CURRENT_VERSION = 38; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = MinimedKit/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -3106,6 +3697,10 @@ DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = ""; ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = MinimedKitTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -3113,6 +3708,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.MinimedKitTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RileyLink.app/RileyLink"; }; name = Debug; }; @@ -3126,12 +3722,17 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ""; ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = MinimedKitTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.MinimedKitTests; PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RileyLink.app/RileyLink"; }; name = Release; }; @@ -3182,7 +3783,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.1; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OBJC_BRIDGING_HEADER = ""; @@ -3234,7 +3835,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.1; SDKROOT = iphoneos; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; @@ -3256,6 +3857,10 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEVELOPMENT_TEAM = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); INFOPLIST_FILE = "RileyLink/RileyLink-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.rlapp; @@ -3277,6 +3882,10 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEVELOPMENT_TEAM = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); INFOPLIST_FILE = "RileyLink/RileyLink-Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.rlapp; @@ -3393,6 +4002,10 @@ DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = ""; ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = NightscoutUploadKitTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -3413,6 +4026,10 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = ""; ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = NightscoutUploadKitTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -3443,6 +4060,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 4352A72E20DEC9B700CAC200 /* Build configuration list for PBXNativeTarget "MinimedKitUI" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4352A72F20DEC9B700CAC200 /* Debug */, + 4352A73020DEC9B700CAC200 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 43722FC91CB9F7640038B7F2 /* Build configuration list for PBXNativeTarget "RileyLinkKit" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -3479,6 +4105,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 43FB610420DDEF26002B996B /* Build configuration list for PBXAggregateTarget "Cartfile" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 43FB610220DDEF26002B996B /* Debug */, + 43FB610320DDEF26002B996B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; C10D9BD81C8269D600378342 /* Build configuration list for PBXNativeTarget "MinimedKit" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/RileyLink.xcodeproj/xcshareddata/xcschemes/MinimedKitUI.xcscheme b/RileyLink.xcodeproj/xcshareddata/xcschemes/MinimedKitUI.xcscheme new file mode 100644 index 000000000..7aeb23d6e --- /dev/null +++ b/RileyLink.xcodeproj/xcshareddata/xcschemes/MinimedKitUI.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RileyLink/DeviceDataManager.swift b/RileyLink/DeviceDataManager.swift index 5b6d3b457..ca78dcd90 100644 --- a/RileyLink/DeviceDataManager.swift +++ b/RileyLink/DeviceDataManager.swift @@ -11,6 +11,7 @@ import RileyLinkKit import RileyLinkKitUI import RileyLinkBLEKit import MinimedKit +import MinimedKitUI import NightscoutUploadKit class DeviceDataManager { @@ -94,7 +95,7 @@ class DeviceDataManager { } - var latestPolledPumpStatus: RileyLinkKit.PumpStatus? { + var latestPolledPumpStatus: MinimedKit.PumpStatus? { didSet { if let update = latestPolledPumpStatus { latestPumpStatusDate = update.clock.date diff --git a/RileyLink/Extensions/UserDefaults.swift b/RileyLink/Extensions/UserDefaults.swift index c1b07c565..844793675 100644 --- a/RileyLink/Extensions/UserDefaults.swift +++ b/RileyLink/Extensions/UserDefaults.swift @@ -6,7 +6,7 @@ // import Foundation -import RileyLinkKit +import MinimedKit extension UserDefaults { diff --git a/RileyLink/View Controllers/RileyLinkListTableViewController.swift b/RileyLink/View Controllers/RileyLinkListTableViewController.swift index 3b50abac2..c32651c36 100644 --- a/RileyLink/View Controllers/RileyLinkListTableViewController.swift +++ b/RileyLink/View Controllers/RileyLinkListTableViewController.swift @@ -7,6 +7,7 @@ // import UIKit +import MinimedKitUI import RileyLinkBLEKit import RileyLinkKit import RileyLinkKitUI @@ -159,7 +160,7 @@ class RileyLinkListTableViewController: UITableViewController { override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let device = devices[indexPath.row] - let vc = RileyLinkDeviceTableViewController( + let vc = RileyLinkMinimedDeviceTableViewController( device: device, deviceState: dataManager.deviceStates[device.peripheralIdentifier, default: DeviceState()], pumpSettings: dataManager.pumpSettings, diff --git a/RileyLink/View Controllers/SettingsTableViewController.swift b/RileyLink/View Controllers/SettingsTableViewController.swift index a584e31c0..8e2f38ecf 100644 --- a/RileyLink/View Controllers/SettingsTableViewController.swift +++ b/RileyLink/View Controllers/SettingsTableViewController.swift @@ -7,6 +7,7 @@ // import UIKit +import LoopKitUI import MinimedKit import RileyLinkKit import RileyLinkKitUI diff --git a/RileyLinkKit/PumpOpsSession.swift b/RileyLinkKit/PumpOpsSession.swift index d264c3246..d6b3134db 100644 --- a/RileyLinkKit/PumpOpsSession.swift +++ b/RileyLinkKit/PumpOpsSession.swift @@ -7,7 +7,6 @@ // import Foundation -import MinimedKit import RileyLinkBLEKit @@ -401,7 +400,7 @@ extension PumpOpsSession { /// - Throws: PumpCommandError public func setMaxBolus(units: Double) throws { - guard let body = ChangeMaxBolusMessageBody(maxBolusUnits: units) else { + guard let body = ChangeMaxBolusMessageBody(pumpModel: try getPumpModel(), maxBolusUnits: units) else { throw PumpCommandError.command(PumpOpsError.pumpError(PumpErrorCode.maxSettingExceeded)) } @@ -475,14 +474,25 @@ extension PumpOpsSession { } do { - let message = PumpMessage(settings: settings, type: .changeTime, body: ChangeTimeCarelinkMessageBody(dateComponents: generator())!) + let components = generator() + let message = PumpMessage(settings: settings, type: .changeTime, body: ChangeTimeCarelinkMessageBody(dateComponents: components)!) let _: PumpAckMessageBody = try session.getResponse(to: message) - self.pump.timeZone = .currentFixed + self.pump.timeZone = components.timeZone?.fixed ?? .currentFixed } catch let error as PumpOpsError { throw PumpCommandError.arguments(error) } } + public func setTimeToNow(in timeZone: TimeZone? = nil) throws { + let timeZone = timeZone ?? pump.timeZone + + try setTime { () -> DateComponents in + var calendar = Calendar(identifier: .gregorian) + calendar.timeZone = timeZone + return calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: Date()) + } + } + /// Sets a bolus /// /// *Note: Use at your own risk!* diff --git a/RileyLinkKit/Extensions/RileyLinkDevice.swift b/RileyLinkKit/RileyLinkDevice.swift similarity index 54% rename from RileyLinkKit/Extensions/RileyLinkDevice.swift rename to RileyLinkKit/RileyLinkDevice.swift index c5d643de1..e118d33e8 100644 --- a/RileyLinkKit/Extensions/RileyLinkDevice.swift +++ b/RileyLinkKit/RileyLinkDevice.swift @@ -7,6 +7,13 @@ import RileyLinkBLEKit + +/// Provide a notification contract that clients can use to inform RileyLink UI of changes to DeviceState +extension RileyLinkDevice { + public static let notificationDeviceStateKey = "com.rileylink.RileyLinkKit.RileyLinkDevice.DeviceState" +} + + extension RileyLinkDevice.Status { public var firmwareDescription: String { let versions = [radioFirmwareVersion, bleFirmwareVersion].compactMap { (version: CustomStringConvertible?) -> String? in @@ -23,5 +30,7 @@ extension RileyLinkDevice.Status { extension Notification.Name { - static let DeviceRadioConfigDidChange = Notification.Name(rawValue: "com.rileylink.RileyLinkKit.DeviceRadioConfigDidChange") + public static let DeviceRadioConfigDidChange = Notification.Name(rawValue: "com.rileylink.RileyLinkKit.DeviceRadioConfigDidChange") + + public static let DeviceStateDidChange = Notification.Name(rawValue: "com.rileylink.RileyLinkKit.DeviceStateDidChange") } diff --git a/RileyLinkKit/RileyLinkDeviceManager.swift b/RileyLinkKit/RileyLinkDeviceManager.swift new file mode 100644 index 000000000..c1de5fa5c --- /dev/null +++ b/RileyLinkKit/RileyLinkDeviceManager.swift @@ -0,0 +1,16 @@ +// +// RileyLinkDeviceManager.swift +// Loop +// +// Copyright © 2017 LoopKit Authors. All rights reserved. +// + +import RileyLinkBLEKit + +extension RileyLinkDeviceManager { + public func firstConnectedDevice(_ completion: @escaping (_ device: RileyLinkDevice?) -> Void) { + getDevices { (devices) in + completion(devices.firstConnected) + } + } +} diff --git a/RileyLinkKit/RileyLinkPumpManager.swift b/RileyLinkKit/RileyLinkPumpManager.swift new file mode 100644 index 000000000..2ba354c46 --- /dev/null +++ b/RileyLinkKit/RileyLinkPumpManager.swift @@ -0,0 +1,127 @@ +// +// RileyLinkPumpManager.swift +// Loop +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + +import RileyLinkBLEKit + + +open class RileyLinkPumpManager { + public init(rileyLinkPumpManagerState: RileyLinkPumpManagerState, rileyLinkManager: RileyLinkDeviceManager? = nil) { + lockedRileyLinkPumpManagerState = Locked(rileyLinkPumpManagerState) + + self.rileyLinkManager = rileyLinkManager ?? RileyLinkDeviceManager(autoConnectIDs: rileyLinkPumpManagerState.connectedPeripheralIDs) + + // Listen for device notifications + NotificationCenter.default.addObserver(self, selector: #selector(receivedRileyLinkPacketNotification(_:)), name: .DevicePacketReceived, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(receivedRileyLinkTimerTickNotification(_:)), name: .DeviceTimerDidTick, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(deviceStateDidChange(_:)), name: .DeviceStateDidChange, object: nil) + } + + /// Manages all the RileyLinks + open let rileyLinkManager: RileyLinkDeviceManager + + open var rileyLinkPumpManagerState: RileyLinkPumpManagerState { + get { + return lockedRileyLinkPumpManagerState.value + } + set { + lockedRileyLinkPumpManagerState.value = newValue + } + } + private let lockedRileyLinkPumpManagerState: Locked + + // TODO: Eveluate if this is necessary + open let queue = DispatchQueue(label: "com.loopkit.RileyLinkPumpManager", qos: .utility) + + /// Isolated to queue + // TODO: Put this on each RileyLinkDevice? + private var lastTimerTick: Date = .distantPast + + // TODO: Isolate to queue + open var deviceStates: [UUID: DeviceState] = [:] + + /// Called when one of the connected devices receives a packet outside of a session + /// + /// - Parameters: + /// - device: The device + /// - packet: The received packet + open func device(_ device: RileyLinkDevice, didReceivePacket packet: RFPacket) { } + + open func deviceTimerDidTick(_ device: RileyLinkDevice) { } + + // MARK: - CustomDebugStringConvertible + + open var debugDescription: String { + return [ + "## RileyLinkPumpManager", + "rileyLinkPumpManagerState: \(String(reflecting: rileyLinkPumpManagerState))", + "lastTimerTick: \(String(describing: lastTimerTick))", + "deviceStates: \(String(reflecting: deviceStates))", + "", + String(reflecting: rileyLinkManager), + ].joined(separator: "\n") + } +} + + +// MARK: - RileyLink Updates +extension RileyLinkPumpManager { + @objc private func deviceStateDidChange(_ note: Notification) { + guard + let device = note.object as? RileyLinkDevice, + let deviceState = note.userInfo?[RileyLinkDevice.notificationDeviceStateKey] as? RileyLinkKit.DeviceState + else { + return + } + + queue.async { + self.deviceStates[device.peripheralIdentifier] = deviceState + } + } + + /** + Called when a new idle message is received by the RileyLink. + + Only MySentryPumpStatus messages are handled. + + - parameter note: The notification object + */ + @objc private func receivedRileyLinkPacketNotification(_ note: Notification) { + guard let device = note.object as? RileyLinkDevice, + let packet = note.userInfo?[RileyLinkDevice.notificationPacketKey] as? RFPacket + else { + return + } + + self.device(device, didReceivePacket: packet) + } + + @objc private func receivedRileyLinkTimerTickNotification(_ note: Notification) { + guard let device = note.object as? RileyLinkDevice else { + return + } + + // TODO: Do we need a queue? + queue.async { + self.lastTimerTick = Date() + + self.deviceTimerDidTick(device) + } + } + + open func connectToRileyLink(_ device: RileyLinkDevice) { + rileyLinkPumpManagerState.connectedPeripheralIDs.insert(device.peripheralIdentifier.uuidString) + rileyLinkManager.connect(device) + } + + open func disconnectFromRileyLink(_ device: RileyLinkDevice) { + _ = lockedRileyLinkPumpManagerState.mutate { (state) in + state.connectedPeripheralIDs.remove(device.peripheralIdentifier.uuidString) + } + + rileyLinkManager.disconnect(device) + } +} diff --git a/RileyLinkKit/RileyLinkPumpManagerState.swift b/RileyLinkKit/RileyLinkPumpManagerState.swift new file mode 100644 index 000000000..95de3b7c5 --- /dev/null +++ b/RileyLinkKit/RileyLinkPumpManagerState.swift @@ -0,0 +1,44 @@ +// +// RileyLinkPumpManagerState.swift +// Loop +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + +import Foundation +import LoopKit + + +public struct RileyLinkPumpManagerState: RawRepresentable, Equatable { + public typealias RawValue = PumpManager.RawStateValue + + public var connectedPeripheralIDs: Set + + public init(connectedPeripheralIDs: Set) { + self.connectedPeripheralIDs = connectedPeripheralIDs + } + + public init?(rawValue: RawValue) { + guard let connectedPeripheralIDs = rawValue["connectedPeripheralIDs"] as? [String] else { + return nil + } + + self.init(connectedPeripheralIDs: Set(connectedPeripheralIDs)) + } + + public var rawValue: RawValue { + return [ + "connectedPeripheralIDs": Array(connectedPeripheralIDs) + ] + } +} + + +extension RileyLinkPumpManagerState: CustomDebugStringConvertible { + public var debugDescription: String { + return [ + "## RileyLinkPumpManagerState", + "connectedPeripheralIDs: \(connectedPeripheralIDs)", + ].joined(separator: "\n") + } +} diff --git a/RileyLinkKitUI/CBPeripheralState.swift b/RileyLinkKitUI/CBPeripheralState.swift index 930fc8d5b..2279d414b 100644 --- a/RileyLinkKitUI/CBPeripheralState.swift +++ b/RileyLinkKitUI/CBPeripheralState.swift @@ -13,7 +13,7 @@ extension CBPeripheralState { // MARK: - CustomStringConvertible - var description: String { + public var description: String { switch self { case .connected: return NSLocalizedString("Connected", comment: "The connected state") diff --git a/RileyLinkKitUI/RileyLinkDevice.swift b/RileyLinkKitUI/RileyLinkDevice.swift deleted file mode 100644 index d0efa6f29..000000000 --- a/RileyLinkKitUI/RileyLinkDevice.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// RileyLinkDevice.swift -// RileyLinkKitUI -// -// Copyright © 2017 Pete Schwamb. All rights reserved. -// - -import RileyLinkBLEKit - - -/// Provide a notification contract that clients can use to inform RileyLink UI of changes to DeviceState -extension RileyLinkDevice { - public static let notificationDeviceStateKey = "com.rileylink.RileyLinkKit.RileyLinkDevice.DeviceState" -} - -extension Notification.Name { - public static let DeviceStateDidChange = Notification.Name(rawValue: "com.rileylink.RileyLinkKit.DeviceStateDidChange") -} diff --git a/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift b/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift index c6a40d357..2c1ec5213 100644 --- a/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift +++ b/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift @@ -7,7 +7,7 @@ // import UIKit -import MinimedKit +import LoopKitUI import RileyLinkBLEKit import RileyLinkKit @@ -19,34 +19,6 @@ public class RileyLinkDeviceTableViewController: UITableViewController { private var deviceState: DeviceState - private let ops: PumpOps? - - private var pumpState: PumpState? { - didSet { - // Update the UI if its visible - guard rssiFetchTimer != nil else { return } - - switch (oldValue, pumpState) { - case (.none, .some): - tableView.insertSections(IndexSet(integer: Section.commands.rawValue), with: .automatic) - case (.some, .none): - tableView.deleteSections(IndexSet(integer: Section.commands.rawValue), with: .automatic) - case (_, let state?): - if let cell = cellForRow(.awake) { - cell.setAwakeUntil(state.awakeUntil, formatter: dateFormatter) - } - - if let cell = cellForRow(.model) { - cell.setPumpModel(state.pumpModel) - } - default: - break - } - } - } - - private let pumpSettings: PumpSettings? - private var bleRSSI: Int? private var firmwareVersion: String? { @@ -77,12 +49,9 @@ public class RileyLinkDeviceTableViewController: UITableViewController { private var appeared = false - public init(device: RileyLinkDevice, deviceState: DeviceState, pumpSettings: PumpSettings?, pumpState: PumpState?, pumpOps: PumpOps?) { + public init(device: RileyLinkDevice) { self.device = device - self.deviceState = deviceState - self.pumpSettings = pumpSettings - self.pumpState = pumpState - self.ops = pumpOps + self.deviceState = DeviceState(lastTuned: nil, lastValidFrequency: nil) super.init(style: .grouped) @@ -150,11 +119,6 @@ public class RileyLinkDeviceTableViewController: UITableViewController { center.addObserver(forName: .DeviceDidStartIdle, object: device, queue: mainQueue) { [weak self] (note) in self?.updateDeviceStatus() }, - center.addObserver(forName: .PumpOpsStateDidChange, object: ops, queue: mainQueue) { [weak self] (note) in - if let state = note.userInfo?[PumpOps.notificationPumpStateKey] as? PumpState { - self?.pumpState = state - } - } ] } @@ -212,7 +176,6 @@ public class RileyLinkDeviceTableViewController: UITableViewController { private enum Section: Int, CaseCountable { case device - case pump case commands } @@ -224,51 +187,20 @@ public class RileyLinkDeviceTableViewController: UITableViewController { case idleStatus } - private enum PumpRow: Int, CaseCountable { - case id - case model - case awake - } - - private enum CommandRow: Int, CaseCountable { - case tune - case changeTime - case mySentryPair - case dumpHistory - case fetchGlucose - case getPumpModel - case pressDownButton - case readPumpStatus - case readBasalSchedule - case enableLED - case discoverCommands - case getStatistics - } - private func cellForRow(_ row: DeviceRow) -> UITableViewCell? { return tableView.cellForRow(at: IndexPath(row: row.rawValue, section: Section.device.rawValue)) } - private func cellForRow(_ row: PumpRow) -> UITableViewCell? { - return tableView.cellForRow(at: IndexPath(row: row.rawValue, section: Section.pump.rawValue)) - } - public override func numberOfSections(in tableView: UITableView) -> Int { - if pumpState == nil { - return Section.count - 1 - } else { - return Section.count - } + return Section.count } public override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { switch Section(rawValue: section)! { case .device: return DeviceRow.count - case .pump: - return PumpRow.count case .commands: - return CommandRow.count + return 0 } } @@ -304,82 +236,9 @@ public class RileyLinkDeviceTableViewController: UITableViewController { cell.textLabel?.text = NSLocalizedString("On Idle", comment: "The title of the cell showing the last idle") cell.setDetailDate(lastIdle, formatter: dateFormatter) } - case .pump: - switch PumpRow(rawValue: indexPath.row)! { - case .id: - cell.textLabel?.text = NSLocalizedString("Pump ID", comment: "The title of the cell showing pump ID") - if let pumpID = pumpSettings?.pumpID { - cell.detailTextLabel?.text = pumpID - } else { - cell.detailTextLabel?.text = "–" - } - case .model: - cell.textLabel?.text = NSLocalizedString("Pump Model", comment: "The title of the cell showing the pump model number") - cell.setPumpModel(pumpState?.pumpModel) - case .awake: - cell.setAwakeUntil(pumpState?.awakeUntil, formatter: dateFormatter) - } case .commands: cell.accessoryType = .disclosureIndicator cell.detailTextLabel?.text = nil - - switch CommandRow(rawValue: indexPath.row)! { - case .tune: - switch (deviceState.lastValidFrequency, deviceState.lastTuned) { - case (let frequency?, let date?): - cell.textLabel?.text = measurementFormatter.string(from: frequency) - cell.setDetailDate(date, formatter: dateFormatter) - default: - cell.textLabel?.text = NSLocalizedString("Tune Radio Frequency", comment: "The title of the command to re-tune the radio") - } - - case .changeTime: - cell.textLabel?.text = NSLocalizedString("Change Time", comment: "The title of the command to change pump time") - - let localTimeZone = TimeZone.current - let localTimeZoneName = localTimeZone.abbreviation() ?? localTimeZone.identifier - - if let pumpTimeZone = pumpState?.timeZone { - let timeZoneDiff = TimeInterval(pumpTimeZone.secondsFromGMT() - localTimeZone.secondsFromGMT()) - let formatter = DateComponentsFormatter() - formatter.allowedUnits = [.hour, .minute] - let diffString = timeZoneDiff != 0 ? formatter.string(from: abs(timeZoneDiff)) ?? String(abs(timeZoneDiff)) : "" - - cell.detailTextLabel?.text = String(format: NSLocalizedString("%1$@%2$@%3$@", comment: "The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00)"), localTimeZoneName, timeZoneDiff != 0 ? (timeZoneDiff < 0 ? "-" : "+") : "", diffString) - } else { - cell.detailTextLabel?.text = localTimeZoneName - } - case .mySentryPair: - cell.textLabel?.text = NSLocalizedString("MySentry Pair", comment: "The title of the command to pair with mysentry") - - case .dumpHistory: - cell.textLabel?.text = NSLocalizedString("Fetch Recent History", comment: "The title of the command to fetch recent history") - - case .fetchGlucose: - cell.textLabel?.text = NSLocalizedString("Fetch Enlite Glucose", comment: "The title of the command to fetch recent glucose") - - case .getPumpModel: - cell.textLabel?.text = NSLocalizedString("Get Pump Model", comment: "The title of the command to get pump model") - - case .pressDownButton: - cell.textLabel?.text = NSLocalizedString("Send Button Press", comment: "The title of the command to send a button press") - - case .readPumpStatus: - cell.textLabel?.text = NSLocalizedString("Read Pump Status", comment: "The title of the command to read pump status") - - case .readBasalSchedule: - cell.textLabel?.text = NSLocalizedString("Read Basal Schedule", comment: "The title of the command to read basal schedule") - - case .enableLED: - cell.textLabel?.text = NSLocalizedString("Enable Diagnostic LEDs", comment: "The title of the command to enable diagnostic LEDs") - - case .discoverCommands: - cell.textLabel?.text = NSLocalizedString("Discover Commands", comment: "The title of the command to discover commands") - - case .getStatistics: - cell.textLabel?.text = NSLocalizedString("Get Statistics", comment: "The title of the command to get statistics") - - } } return cell @@ -389,8 +248,6 @@ public class RileyLinkDeviceTableViewController: UITableViewController { switch Section(rawValue: section)! { case .device: return NSLocalizedString("Device", comment: "The title of the section describing the device") - case .pump: - return NSLocalizedString("Pump", comment: "The title of the section describing the pump") case .commands: return NSLocalizedString("Commands", comment: "The title of the section describing commands") } @@ -407,8 +264,6 @@ public class RileyLinkDeviceTableViewController: UITableViewController { default: return false } - case .pump: - return false case .commands: return device.peripheralState == .connected } @@ -432,41 +287,6 @@ public class RileyLinkDeviceTableViewController: UITableViewController { break } case .commands: - let vc: CommandResponseViewController - - switch CommandRow(rawValue: indexPath.row)! { - case .tune: - vc = .tuneRadio(ops: ops, device: device, current: deviceState.lastValidFrequency, measurementFormatter: measurementFormatter) - case .changeTime: - vc = .changeTime(ops: ops, device: device) - case .mySentryPair: - vc = .mySentryPair(ops: ops, device: device) - case .dumpHistory: - vc = .dumpHistory(ops: ops, device: device) - case .fetchGlucose: - vc = .fetchGlucose(ops: ops, device: device) - case .getPumpModel: - vc = .getPumpModel(ops: ops, device: device) - case .pressDownButton: - vc = .pressDownButton(ops: ops, device: device) - case .readPumpStatus: - vc = .readPumpStatus(ops: ops, device: device, measurementFormatter: measurementFormatter) - case .readBasalSchedule: - vc = .readBasalSchedule(ops: ops, device: device, integerFormatter: integerFormatter) - case .enableLED: - vc = .enableLEDs(ops: ops, device: device) - case .discoverCommands: - vc = .discoverCommands(ops: ops, device: device) - case .getStatistics: - vc = .getStatistics(ops: ops, device: device) - } - - if let cell = tableView.cellForRow(at: indexPath) { - vc.title = cell.textLabel?.text - } - - show(vc, sender: indexPath) - case .pump: break } } @@ -490,7 +310,6 @@ extension RileyLinkDeviceTableViewController: TextFieldTableViewControllerDelega } default: break - } } } @@ -523,12 +342,4 @@ private extension UITableViewCell { detailTextLabel?.text = nil } } - - func setPumpModel(_ pumpModel: PumpModel?) { - if let pumpModel = pumpModel { - detailTextLabel?.text = String(describing: pumpModel) - } else { - detailTextLabel?.text = NSLocalizedString("Unknown", comment: "The detail text for an unknown pump model") - } - } } diff --git a/RileyLinkKitUI/RileyLinkDevicesHeaderView.swift b/RileyLinkKitUI/RileyLinkDevicesHeaderView.swift new file mode 100644 index 000000000..b7b68e792 --- /dev/null +++ b/RileyLinkKitUI/RileyLinkDevicesHeaderView.swift @@ -0,0 +1,37 @@ +// +// RileyLinkDevicesHeaderView.swift +// Loop +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + +import UIKit + +public class RileyLinkDevicesHeaderView: UITableViewHeaderFooterView, IdentifiableClass { + + override public init(reuseIdentifier: String?) { + super.init(reuseIdentifier: reuseIdentifier) + + setup() + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + + setup() + } + + public let spinner = UIActivityIndicatorView(activityIndicatorStyle: .gray) + + private func setup() { + contentView.addSubview(spinner) + spinner.startAnimating() + } + + override public func layoutSubviews() { + super.layoutSubviews() + + spinner.center.y = textLabel?.center.y ?? 0 + spinner.frame.origin.x = contentView.bounds.size.width - contentView.directionalLayoutMargins.trailing - spinner.frame.size.width + } +} diff --git a/RileyLinkKitUI/RileyLinkDevicesTableViewDataSource.swift b/RileyLinkKitUI/RileyLinkDevicesTableViewDataSource.swift new file mode 100644 index 000000000..ebbb2b50a --- /dev/null +++ b/RileyLinkKitUI/RileyLinkDevicesTableViewDataSource.swift @@ -0,0 +1,209 @@ +// +// RileyLinkDevicesTableViewDataSource.swift +// RileyLinkKitUI +// +// Copyright © 2018 Pete Schwamb. All rights reserved. +// + +import UIKit +import CoreBluetooth +import RileyLinkBLEKit +import RileyLinkKit + + +public class RileyLinkDevicesTableViewDataSource: NSObject { + public let rileyLinkPumpManager: RileyLinkPumpManager + + public let devicesSectionIndex: Int + + public var tableView: UITableView! { + didSet { + tableView.register(RileyLinkDeviceTableViewCell.self, forCellReuseIdentifier: RileyLinkDeviceTableViewCell.className) + + tableView.register(RileyLinkDevicesHeaderView.self, forHeaderFooterViewReuseIdentifier: RileyLinkDevicesHeaderView.className) + + // Register for manager notifications + NotificationCenter.default.addObserver(self, selector: #selector(reloadDevices), name: .ManagerDevicesDidChange, object: rileyLinkPumpManager.rileyLinkManager) + + // Register for device notifications + for name in [.DeviceConnectionStateDidChange, .DeviceRSSIDidChange, .DeviceNameDidChange] as [Notification.Name] { + NotificationCenter.default.addObserver(self, selector: #selector(deviceDidUpdate(_:)), name: name, object: nil) + } + + reloadDevices() + } + } + + public init(rileyLinkPumpManager: RileyLinkPumpManager, devicesSectionIndex: Int) { + self.rileyLinkPumpManager = rileyLinkPumpManager + self.devicesSectionIndex = devicesSectionIndex + super.init() + } + + // MARK: - + + lazy var decimalFormatter: NumberFormatter = { + let formatter = NumberFormatter() + + formatter.numberStyle = .decimal + formatter.minimumFractionDigits = 0 + formatter.maximumFractionDigits = 2 + + return formatter + }() + + public var isScanningEnabled: Bool = false { + didSet { + rileyLinkPumpManager.rileyLinkManager.setScanningEnabled(isScanningEnabled) + + if isScanningEnabled { + rssiFetchTimer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(updateRSSI), userInfo: nil, repeats: true) + updateRSSI() + } else { + rssiFetchTimer = nil + } + } + } + + private(set) public var devices: [RileyLinkDevice] = [] { + didSet { + // Assume only appends are possible when count changes for algorithmic simplicity + guard oldValue.count < devices.count else { + tableView.reloadSections(IndexSet(integer: devicesSectionIndex), with: .fade) + return + } + + tableView.beginUpdates() + + let insertedPaths = (oldValue.count.. IndexPath in + return IndexPath(row: index, section: devicesSectionIndex) + } + tableView.insertRows(at: insertedPaths, with: .automatic) + + tableView.endUpdates() + } + } + + /// Returns an adjusted peripheral state reflecting the user's auto-connect preference. + /// Peripherals connected to the system will show as disconnected if the user hasn't designated them + /// + /// - Parameter device: The peripheral + /// - Returns: The adjusted connection state + private func preferenceStateForDevice(_ device: RileyLinkDevice) -> CBPeripheralState { + let isAutoConnectDevice = self.rileyLinkPumpManager.rileyLinkPumpManagerState.connectedPeripheralIDs.contains(device.peripheralIdentifier.uuidString) + var state = device.peripheralState + + switch state { + case .disconnected, .disconnecting: + break + case .connecting, .connected: + if !isAutoConnectDevice { + state = .disconnected + } + } + + return state + } + + private var deviceRSSI: [UUID: Int] = [:] + + private var rssiFetchTimer: Timer? { + willSet { + rssiFetchTimer?.invalidate() + } + } + + @objc private func reloadDevices() { + rileyLinkPumpManager.rileyLinkManager.getDevices { (devices) in + DispatchQueue.main.async { + self.devices = devices + } + } + } + + @objc private func deviceDidUpdate(_ note: Notification) { + DispatchQueue.main.async { + if let device = note.object as? RileyLinkDevice, let index = self.devices.index(where: { $0 === device }) { + if let rssi = note.userInfo?[RileyLinkDevice.notificationRSSIKey] as? Int { + self.deviceRSSI[device.peripheralIdentifier] = rssi + } + + if let cell = self.tableView.cellForRow(at: IndexPath(row: index, section: self.devicesSectionIndex)) as? RileyLinkDeviceTableViewCell { + cell.configureCellWithName( + device.name, + signal: self.decimalFormatter.decibleString(from: self.deviceRSSI[device.peripheralIdentifier]), + peripheralState: self.preferenceStateForDevice(device) + ) + } + } + } + } + + @objc public func updateRSSI() { + for device in devices { + device.readRSSI() + } + } + + @objc private func deviceConnectionChanged(_ connectSwitch: UISwitch) { + let switchOrigin = connectSwitch.convert(CGPoint.zero, to: tableView) + + if let indexPath = tableView.indexPathForRow(at: switchOrigin), indexPath.section == devicesSectionIndex + { + let device = devices[indexPath.row] + + if connectSwitch.isOn { + rileyLinkPumpManager.connectToRileyLink(device) + } else { + rileyLinkPumpManager.disconnectFromRileyLink(device) + } + } + } +} + +extension RileyLinkDevicesTableViewDataSource: UITableViewDataSource { + public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return devices.count + } + + public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let deviceCell = tableView.dequeueReusableCell(withIdentifier: RileyLinkDeviceTableViewCell.className) as! RileyLinkDeviceTableViewCell + let device = devices[indexPath.row] + + deviceCell.configureCellWithName( + device.name, + signal: decimalFormatter.decibleString(from: deviceRSSI[device.peripheralIdentifier]), + peripheralState: self.preferenceStateForDevice(device) + ) + + deviceCell.connectSwitch?.addTarget(self, action: #selector(deviceConnectionChanged(_:)), for: .valueChanged) + + return deviceCell + } + + public func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + return NSLocalizedString("Devices", comment: "The title of the devices table section in RileyLink settings") + } +} + +extension RileyLinkDevicesTableViewDataSource: UITableViewDelegate { + public func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + return tableView.dequeueReusableHeaderFooterView(withIdentifier: RileyLinkDevicesHeaderView.className) + } + + public func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { + return 44 + } + + public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return UITableViewAutomaticDimension + } + + public func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat { + return 55 + } + + public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + return UITableViewAutomaticDimension + } +} diff --git a/RileyLinkKitUI/RileyLinkKitUI.xcassets/Contents.json b/RileyLinkKitUI/RileyLinkKitUI.xcassets/Contents.json new file mode 100644 index 000000000..da4a164c9 --- /dev/null +++ b/RileyLinkKitUI/RileyLinkKitUI.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/RileyLinkKitUI/RileyLinkKitUI.xcassets/RileyLink Tint.colorset/Contents.json b/RileyLinkKitUI/RileyLinkKitUI.xcassets/RileyLink Tint.colorset/Contents.json new file mode 100644 index 000000000..bb0dcbefa --- /dev/null +++ b/RileyLinkKitUI/RileyLinkKitUI.xcassets/RileyLink Tint.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "0.345", + "alpha" : "1.000", + "blue" : "0.839", + "green" : "0.337" + } + } + } + ] +} \ No newline at end of file diff --git a/RileyLinkKitUI/RileyLinkKitUI.xcassets/RileyLink.imageset/Contents.json b/RileyLinkKitUI/RileyLinkKitUI.xcassets/RileyLink.imageset/Contents.json new file mode 100644 index 000000000..cfe31b855 --- /dev/null +++ b/RileyLinkKitUI/RileyLinkKitUI.xcassets/RileyLink.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "RileyLink.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/RileyLinkKitUI/RileyLinkKitUI.xcassets/RileyLink.imageset/RileyLink.pdf b/RileyLinkKitUI/RileyLinkKitUI.xcassets/RileyLink.imageset/RileyLink.pdf new file mode 100644 index 0000000000000000000000000000000000000000..69cc898de70bba240e44f9783405ec539d4c4ce8 GIT binary patch literal 36519 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 F{{YJ|5<~z1 literal 0 HcmV?d00001 diff --git a/RileyLinkKitUI/RileyLinkManagerSetupViewController.swift b/RileyLinkKitUI/RileyLinkManagerSetupViewController.swift new file mode 100644 index 000000000..fe2529eb1 --- /dev/null +++ b/RileyLinkKitUI/RileyLinkManagerSetupViewController.swift @@ -0,0 +1,40 @@ +// +// RileyLinkManagerSetupViewController.swift +// Loop +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + +import UIKit +import LoopKit +import LoopKitUI +import RileyLinkKit + + +open class RileyLinkManagerSetupViewController: UINavigationController, PumpManagerSetupViewController, UINavigationControllerDelegate { + + open var maxBasalRateUnitsPerHour: Double? + + open var maxBolusUnits: Double? + + open var basalSchedule: BasalRateSchedule? + + open weak var setupDelegate: PumpManagerSetupViewControllerDelegate? + + open private(set) var rileyLinkPumpManager: RileyLinkPumpManager? + + open override func viewDidLoad() { + super.viewDidLoad() + + delegate = self + } + + open func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) { + let viewControllers = navigationController.viewControllers + let count = navigationController.viewControllers.count + + if count >= 2, let setupViewController = viewControllers[count - 2] as? RileyLinkSetupTableViewController { + rileyLinkPumpManager = setupViewController.rileyLinkPumpManager + } + } +} diff --git a/RileyLinkKitUI/RileyLinkSettingsViewController.swift b/RileyLinkKitUI/RileyLinkSettingsViewController.swift new file mode 100644 index 000000000..5d21a60dc --- /dev/null +++ b/RileyLinkKitUI/RileyLinkSettingsViewController.swift @@ -0,0 +1,64 @@ +// +// RileyLinkSettingsViewController.swift +// Loop +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + +import UIKit +import CoreBluetooth +import RileyLinkBLEKit +import RileyLinkKit + + +open class RileyLinkSettingsViewController: UITableViewController { + + open let devicesDataSource: RileyLinkDevicesTableViewDataSource + + public init(rileyLinkPumpManager: RileyLinkPumpManager, devicesSectionIndex: Int, style: UITableViewStyle) { + devicesDataSource = RileyLinkDevicesTableViewDataSource(rileyLinkPumpManager: rileyLinkPumpManager, devicesSectionIndex: devicesSectionIndex) + super.init(style: style) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override open func viewDidLoad() { + super.viewDidLoad() + + devicesDataSource.tableView = tableView + } + + override open func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + devicesDataSource.isScanningEnabled = true + } + + override open func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + + devicesDataSource.isScanningEnabled = false + } + + // MARK: - UITableViewDataSource + + override open func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return devicesDataSource.tableView(tableView, numberOfRowsInSection: section) + } + + override open func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + return devicesDataSource.tableView(tableView, cellForRowAt: indexPath) + } + + override open func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + return devicesDataSource.tableView(tableView, titleForHeaderInSection: section) + } + + // MARK: - UITableViewDelegate + + override open func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + return devicesDataSource.tableView(tableView, viewForHeaderInSection: section) + } +} diff --git a/RileyLinkKitUI/RileyLinkSetupTableViewController.swift b/RileyLinkKitUI/RileyLinkSetupTableViewController.swift new file mode 100644 index 000000000..318078c56 --- /dev/null +++ b/RileyLinkKitUI/RileyLinkSetupTableViewController.swift @@ -0,0 +1,150 @@ +// +// RileyLinkSetupTableViewController.swift +// Loop +// +// Copyright © 2018 LoopKit Authors. All rights reserved. +// + +import UIKit +import LoopKit +import LoopKitUI +import RileyLinkKit + + +public class RileyLinkSetupTableViewController: SetupTableViewController { + + let rileyLinkPumpManager = RileyLinkPumpManager(rileyLinkPumpManagerState: RileyLinkPumpManagerState(connectedPeripheralIDs: [])) + + private lazy var devicesDataSource: RileyLinkDevicesTableViewDataSource = { + return RileyLinkDevicesTableViewDataSource( + rileyLinkPumpManager: rileyLinkPumpManager, + devicesSectionIndex: Section.devices.rawValue + ) + }() + + public override func viewDidLoad() { + super.viewDidLoad() + + devicesDataSource.tableView = tableView + + tableView.register(SetupImageTableViewCell.nib(), forCellReuseIdentifier: SetupImageTableViewCell.className) + + NotificationCenter.default.addObserver(self, selector: #selector(deviceConnectionStateDidChange), name: .DeviceConnectionStateDidChange, object: nil) + + updateContinueButtonState() + } + + public override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + devicesDataSource.isScanningEnabled = true + } + + public override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + + devicesDataSource.isScanningEnabled = false + } + + // MARK: - Table view data source + + private enum Section: Int { + case info + case devices + + static let count = 2 + } + + private enum InfoRow: Int { + case image + case description + + static let count = 2 + } + + public override func numberOfSections(in tableView: UITableView) -> Int { + return Section.count + } + + public override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + switch Section(rawValue: section)! { + case .info: + return InfoRow.count + case .devices: + return devicesDataSource.tableView(tableView, numberOfRowsInSection: section) + } + } + + public override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + switch Section(rawValue: indexPath.section)! { + case .info: + switch InfoRow(rawValue: indexPath.row)! { + case .image: + let cell = tableView.dequeueReusableCell(withIdentifier: SetupImageTableViewCell.className, for: indexPath) as! SetupImageTableViewCell + let bundle = Bundle(for: type(of: self)) + cell.mainImageView?.image = UIImage(named: "RileyLink", in: bundle, compatibleWith: cell.traitCollection) + cell.mainImageView?.tintColor = UIColor(named: "RileyLink Tint", in: bundle, compatibleWith: cell.traitCollection) + + return cell + case .description: + var cell = tableView.dequeueReusableCell(withIdentifier: "DescriptionCell") + if cell == nil { + cell = UITableViewCell(style: .default, reuseIdentifier: "DescriptionCell") + cell?.selectionStyle = .none + cell?.textLabel?.text = NSLocalizedString("RileyLink allows for communication with the pump over Bluetooth Low Energy.", comment: "RileyLink setup description") + cell?.textLabel?.numberOfLines = 0 + } + return cell! + } + case .devices: + return devicesDataSource.tableView(tableView, cellForRowAt: indexPath) + } + } + + public override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + switch Section(rawValue: section)! { + case .info: + return nil + case .devices: + return devicesDataSource.tableView(tableView, titleForHeaderInSection: section) + } + } + + public override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + switch Section(rawValue: section)! { + case .info: + return nil + case .devices: + return devicesDataSource.tableView(tableView, viewForHeaderInSection: section) + } + } + + public override func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat { + return devicesDataSource.tableView(tableView, estimatedHeightForHeaderInSection: section) + } + + public override func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool { + return false + } + + // MARK: - Navigation + + private var shouldContinue: Bool { + return devicesDataSource.rileyLinkPumpManager.rileyLinkPumpManagerState.connectedPeripheralIDs.count > 0 + } + + @objc private func deviceConnectionStateDidChange() { + DispatchQueue.main.async { + self.updateContinueButtonState() + } + } + + private func updateContinueButtonState() { + footerView.primaryButton.isEnabled = shouldContinue + } + + public override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool { + return shouldContinue + } + +} diff --git a/RileyLinkKitUI/SetupImageTableViewCell.swift b/RileyLinkKitUI/SetupImageTableViewCell.swift new file mode 100644 index 000000000..33c20ad09 --- /dev/null +++ b/RileyLinkKitUI/SetupImageTableViewCell.swift @@ -0,0 +1,14 @@ +// +// SetupImageTableViewCell.swift +// RileyLinkKitUI +// +// Copyright © 2018 Pete Schwamb. All rights reserved. +// + +import UIKit + +public class SetupImageTableViewCell: UITableViewCell, NibLoadable { + + @IBOutlet public var mainImageView: UIImageView? + +} diff --git a/RileyLinkKitUI/SetupImageTableViewCell.xib b/RileyLinkKitUI/SetupImageTableViewCell.xib new file mode 100644 index 000000000..85621a7c4 --- /dev/null +++ b/RileyLinkKitUI/SetupImageTableViewCell.xib @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RileyLinkKitUI/TextFieldTableViewCell.swift b/RileyLinkKitUI/TextFieldTableViewCell.swift deleted file mode 100644 index f66fba2a2..000000000 --- a/RileyLinkKitUI/TextFieldTableViewCell.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// TextFieldTableViewCell.swift -// Naterade -// -// Created by Nathan Racklyeft on 5/22/16. -// Copyright © 2016 Nathan Racklyeft. All rights reserved. -// - -import UIKit - -class TextFieldTableViewCell: UITableViewCell { - - @IBOutlet var textField: UITextField! - - static func nib() -> UINib { - return UINib(nibName: className, bundle: Bundle(for: self)) - } - - override func prepareForReuse() { - super.prepareForReuse() - - textField.delegate = nil - } -} diff --git a/RileyLinkKitUI/TextFieldTableViewCell.xib b/RileyLinkKitUI/TextFieldTableViewCell.xib deleted file mode 100644 index 07c8aab24..000000000 --- a/RileyLinkKitUI/TextFieldTableViewCell.xib +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/RileyLinkKitUI/TextFieldTableViewController.swift b/RileyLinkKitUI/TextFieldTableViewController.swift deleted file mode 100644 index d8639e53a..000000000 --- a/RileyLinkKitUI/TextFieldTableViewController.swift +++ /dev/null @@ -1,101 +0,0 @@ -// -// TextFieldTableViewController.swift -// Naterade -// -// Created by Nathan Racklyeft on 8/30/15. -// Copyright © 2015 Nathan Racklyeft. All rights reserved. -// - -import UIKit - - -public protocol TextFieldTableViewControllerDelegate: class { - func textFieldTableViewControllerDidEndEditing(_ controller: TextFieldTableViewController) - - func textFieldTableViewControllerDidReturn(_ controller: TextFieldTableViewController) -} - - -public class TextFieldTableViewController: UITableViewController, UITextFieldDelegate { - - private weak var textField: UITextField? - - public var indexPath: IndexPath? - - public var placeholder: String? - - internal var unit: String? - - public var value: String? { - didSet { - delegate?.textFieldTableViewControllerDidEndEditing(self) - } - } - - internal var contextHelp: String? - - internal var keyboardType = UIKeyboardType.default - - internal var autocapitalizationType = UITextAutocapitalizationType.words - - public weak var delegate: TextFieldTableViewControllerDelegate? - - internal convenience init() { - self.init(style: .grouped) - } - - public override func viewDidLoad() { - super.viewDidLoad() - - tableView.cellLayoutMarginsFollowReadableWidth = true - - tableView.register(TextFieldTableViewCell.nib(), forCellReuseIdentifier: TextFieldTableViewCell.className) - } - - public override func viewDidAppear(_ animated: Bool) { - super.viewDidAppear(animated) - - textField?.becomeFirstResponder() - } - - // MARK: - UITableViewDataSource - - public override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return 1 - } - - public override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: TextFieldTableViewCell.className, for: indexPath) as! TextFieldTableViewCell - - textField = cell.textField - - cell.textField?.delegate = self - cell.textField?.text = value - cell.textField?.keyboardType = keyboardType - cell.textField?.placeholder = placeholder - cell.textField?.autocapitalizationType = autocapitalizationType - - return cell - } - - override public func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? { - return contextHelp - } - - // MARK: - UITextFieldDelegate - - public func textFieldShouldEndEditing(_ textField: UITextField) -> Bool { - value = textField.text - - return true - } - - public func textFieldShouldReturn(_ textField: UITextField) -> Bool { - value = textField.text - - textField.delegate = nil - delegate?.textFieldTableViewControllerDidReturn(self) - - return false - } -} From 3b257bdfa5f01ebaa343c9e6e1c2140ffd2569a1 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 4 Jul 2018 23:59:26 -0500 Subject: [PATCH 03/22] Point to LoopKit dev --- Cartfile | 2 +- Cartfile.resolved | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cartfile b/Cartfile index 52d9d4af0..05195c51b 100644 --- a/Cartfile +++ b/Cartfile @@ -1 +1 @@ -github "LoopKit/LoopKit" "pump-manager" +github "LoopKit/LoopKit" "dev" diff --git a/Cartfile.resolved b/Cartfile.resolved index 756402713..182da45dc 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1 +1 @@ -github "LoopKit/LoopKit" "8afd78fac3cc20d2b99a022c01ce4f8f2853cb53" +github "LoopKit/LoopKit" "f2f82d9bd67cd329b4021b365b7ebdec4b39f0af" From 3dd0ad52bbc1df5d2dcf51cd422efd17455784c5 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Thu, 5 Jul 2018 01:34:38 -0500 Subject: [PATCH 04/22] Fix bug in serialization for forecastError upload to ns (#416) --- NightscoutUploadKit/DeviceStatus/LoopStatus.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NightscoutUploadKit/DeviceStatus/LoopStatus.swift b/NightscoutUploadKit/DeviceStatus/LoopStatus.swift index 73a414edb..df5fffa7a 100644 --- a/NightscoutUploadKit/DeviceStatus/LoopStatus.swift +++ b/NightscoutUploadKit/DeviceStatus/LoopStatus.swift @@ -87,7 +87,7 @@ public struct LoopStatus { } if let forecastError = forecastError { - rval["forecastError"] = forecastError + rval["forecastError"] = forecastError.dictionaryRepresentation } if let testingDetails = testingDetails { From 4a714a59d399aeb2984cbbe0434f02e6b59cfec5 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 9 Jul 2018 19:59:43 -0500 Subject: [PATCH 05/22] Fix time and add logging (#418) * Fix time and add logging * Fixes an issue where a time zone change was never persisted * Increases log level for more critical BLE events * Get LoopKit updates * Fix non-PumpManager based launch of RileyLinkMinimedDeviceTableViewController --- Cartfile.resolved | 2 +- Common/OSLog.swift | 6 + .../Messages/PumpErrorMessageBody.swift | 2 +- .../PumpManager/MinimedPumpManager.swift | 116 ++++++++---------- .../PumpManager/MinimedPumpManagerError.swift | 16 +++ MinimedKit/PumpManager/PumpOps.swift | 48 ++++++-- MinimedKit/PumpManager/RileyLinkDevice.swift | 6 +- .../CommandResponseViewController.swift | 2 +- MinimedKitUI/MinimedPumpManager+UI.swift | 4 +- .../MinimedPumpSettingsViewController.swift | 37 +++++- MinimedKitUI/PumpOps.swift | 18 --- ...LinkMinimedDeviceTableViewController.swift | 48 +++----- .../MinimedPumpIDSetupViewController.swift | 4 +- ...MinimedPumpSentrySetupViewController.swift | 4 +- RileyLink.xcodeproj/project.pbxproj | 4 - RileyLink/DeviceDataManager.swift | 12 +- .../RileyLinkListTableViewController.swift | 9 +- .../PeripheralManager+RileyLink.swift | 4 +- RileyLinkBLEKit/PeripheralManager.swift | 8 +- RileyLinkBLEKit/RileyLinkDevice.swift | 2 +- RileyLinkBLEKit/RileyLinkDeviceManager.swift | 8 +- RileyLinkKit/PumpOpsSession.swift | 4 +- 22 files changed, 195 insertions(+), 169 deletions(-) delete mode 100644 MinimedKitUI/PumpOps.swift diff --git a/Cartfile.resolved b/Cartfile.resolved index 182da45dc..4bc265a80 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1 +1 @@ -github "LoopKit/LoopKit" "f2f82d9bd67cd329b4021b365b7ebdec4b39f0af" +github "LoopKit/LoopKit" "7082c64333113ad83238e483e83029c161ac35bb" diff --git a/Common/OSLog.swift b/Common/OSLog.swift index e49507632..9b7a7c900 100644 --- a/Common/OSLog.swift +++ b/Common/OSLog.swift @@ -21,6 +21,10 @@ extension OSLog { log(message, type: .info, args) } + func `default`(_ message: StaticString, _ args: CVarArg...) { + log(message, type: .default, args) + } + func error(_ message: StaticString, _ args: CVarArg...) { log(message, type: .error, args) } @@ -37,6 +41,8 @@ extension OSLog { os_log(message, log: self, type: type, args[0], args[1], args[2]) case 4: os_log(message, log: self, type: type, args[0], args[1], args[2], args[3]) + case 5: + os_log(message, log: self, type: type, args[0], args[1], args[2], args[3], args[4]) default: os_log(message, log: self, type: type, args) } diff --git a/MinimedKit/Messages/PumpErrorMessageBody.swift b/MinimedKit/Messages/PumpErrorMessageBody.swift index 9d52bfae6..99e0cdbf2 100644 --- a/MinimedKit/Messages/PumpErrorMessageBody.swift +++ b/MinimedKit/Messages/PumpErrorMessageBody.swift @@ -28,7 +28,7 @@ public enum PumpErrorCode: UInt8, CustomStringConvertible { public var recoverySuggestion: String? { switch self { case .commandRefused: - return NSLocalizedString("Pump may be suspended, priming, or have an incorrect temp basal type", comment: "Suggestions for diagnosing a command refused pump error") + return NSLocalizedString("Check that the pump is not suspended or priming, or has a percent temp basal type", comment: "Suggestions for diagnosing a command refused pump error") default: return nil } diff --git a/MinimedKit/PumpManager/MinimedPumpManager.swift b/MinimedKit/PumpManager/MinimedPumpManager.swift index abaddddf5..c5287e8b0 100644 --- a/MinimedKit/PumpManager/MinimedPumpManager.swift +++ b/MinimedKit/PumpManager/MinimedPumpManager.swift @@ -62,12 +62,32 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { public private(set) var sensorState: SensorDisplayable? + // MARK: - Pump data + + /// TODO: Isolate to queue + fileprivate var latestPumpStatusFromMySentry: MySentryPumpStatusMessageBody? { + didSet { + if let sensorState = latestPumpStatusFromMySentry { + self.sensorState = sensorState + } + } + } + // TODO: Isolate to queue private var latestPumpStatus: PumpStatus? // TODO: Isolate to queue private var lastAddedPumpEvents: Date = .distantPast + // Battery monitor + private func observeBatteryDuring(_ block: () -> Void) { + let oldVal = pumpBatteryChargeRemaining + block() + pumpManagerDelegate?.pumpManagerDidUpdatePumpBatteryChargeRemaining(self, oldValue: oldVal) + } + + // MARK: - PumpManager + // TODO: Isolate to queue // Returns a value in the range 0 - 1 public var pumpBatteryChargeRemaining: Double? { @@ -80,37 +100,30 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { } } - // Battery monitor - private func observeBatteryDuring(_ block: () -> Void) { - let oldVal = pumpBatteryChargeRemaining - block() - pumpManagerDelegate?.pumpManagerDidUpdatePumpBatteryChargeRemaining(self, oldValue: oldVal) - } - public func updateBLEHeartbeatPreference() { queue.async { /// Controls the management of the RileyLink timer tick, which is a reliably-changing BLE /// characteristic which can cause the app to wake. For most users, the G5 Transmitter and /// G4 Receiver are reliable as hearbeats, but users who find their resources extremely constrained /// due to greedy apps or older devices may choose to always enable the timer by always setting `true` - self.rileyLinkManager.timerTickEnabled = self.isPumpDataStale() || (self.pumpManagerDelegate?.pumpManagerShouldProvideBLEHeartbeat(self) == true) + self.rileyLinkManager.timerTickEnabled = self.isPumpDataStale || (self.pumpManagerDelegate?.pumpManagerShouldProvideBLEHeartbeat(self) == true) } } - public var pumpRecordsBasalProfileStartEvents: Bool? { - return pumpState?.pumpModel?.recordsBasalProfileStartEvents + public var pumpRecordsBasalProfileStartEvents: Bool { + return state.pumpModel.recordsBasalProfileStartEvents } - public var pumpReservoirCapacity: Double? { - guard let capacity = pumpState?.pumpModel?.reservoirCapacity else { - return nil - } + public var pumpReservoirCapacity: Double { + return Double(state.pumpModel.reservoirCapacity) + } - return Double(capacity) + public var pumpTimeZone: TimeZone { + return state.timeZone } - public var pumpTimeZone: TimeZone? { - return pumpState?.timeZone + public var localizedTitle: String { + return String(format: NSLocalizedString("Minimed %@", comment: "Pump title (1: model number)"), state.pumpModel.rawValue) } // MARK: - RileyLink Updates @@ -146,22 +159,20 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { override public var debugDescription: String { return [ "## MinimedPumpManager", + "isPumpDataStale: \(isPumpDataStale)", "latestPumpStatus: \(String(describing: latestPumpStatus))", "latestPumpStatusFromMySentry: \(String(describing: latestPumpStatusFromMySentry))", + "lastAddedPumpEvents: \(lastAddedPumpEvents)", "pumpBatteryChargeRemaining: \(String(reflecting: pumpBatteryChargeRemaining))", - "pumpSettings: \(String(reflecting: pumpSettings))", - "pumpState: \(String(reflecting: pumpState))", - "preferredInsulinDataSource: \(preferredInsulinDataSource)", + "state: \(String(reflecting: state))", "sensorState: \(String(describing: sensorState))", "", + "pumpOps: \(String(reflecting: pumpOps))", + "", super.debugDescription, ].joined(separator: "\n") } - public var localizedTitle: String { - return String(format: NSLocalizedString("Minimed %@", comment: "Pump title (1: model number)"), pumpState?.pumpModel?.rawValue ?? "") - } - /** Attempts to fix an extended communication failure between a RileyLink device and the pump @@ -202,17 +213,6 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { } } - // MARK: Pump data - - /// TODO: Isolate to queue - fileprivate var latestPumpStatusFromMySentry: MySentryPumpStatusMessageBody? { - didSet { - if let sensorState = latestPumpStatusFromMySentry { - self.sensorState = sensorState - } - } - } - /** Handles receiving a MySentry status message, which are only posted by MM x23 pumps. @@ -229,10 +229,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { var pumpDateComponents = status.pumpDateComponents var glucoseDateComponents = status.glucoseDateComponents - guard let timeZone = pumpState?.timeZone else { - return - } - + let timeZone = state.timeZone pumpDateComponents.timeZone = timeZone glucoseDateComponents?.timeZone = timeZone @@ -259,7 +256,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { let pumpManagerStatus = PumpManagerStatus( date: pumpDate, timeZone: timeZone, - device: deviceStatus.device(settings: self.pumpSettings, pumpState: self.pumpState), + device: deviceStatus.device(pumpID: self.state.pumpID, pumpModel: self.state.pumpModel), lastValidFrequency: deviceState?.lastValidFrequency, lastTuned: deviceState?.lastTuned, battery: PumpManagerStatus.BatteryStatus(percent: Double(status.batteryRemainingPercent) / 100), @@ -279,7 +276,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { quantity: HKQuantity(unit: .milligramsPerDeciliter, doubleValue: Double(glucose)), isDisplayOnly: false, syncIdentifier: status.glucoseSyncIdentifier ?? UUID().uuidString, - device: deviceStatus.device(settings: self.pumpSettings, pumpState: self.pumpState) + device: deviceStatus.device(pumpID: self.state.pumpID, pumpModel: self.state.pumpModel) ) self.cgmManagerDelegate?.cgmManager(self, didUpdateWith: .newData([sample])) @@ -317,7 +314,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { break case .success(let (_, _, areStoredValuesContinuous)): // Run a loop as long as we have fresh, reliable pump data. - if self.preferredInsulinDataSource == .pumpHistory || !areStoredValuesContinuous { + if self.state.preferredInsulinDataSource == .pumpHistory || !areStoredValuesContinuous { self.fetchPumpHistory { (error) in if let error = error as? PumpManagerError { self.pumpManagerDelegate?.pumpManager(self, didError: error) @@ -346,7 +343,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { private func fetchPumpHistory(_ completion: @escaping (_ error: Error?) -> Void) { rileyLinkManager.getDevices { (devices) in guard let device = devices.firstConnected else { - completion(PumpManagerError.connection(nil)) + completion(PumpManagerError.connection(MinimedPumpManagerError.noRileyLink)) return } @@ -376,7 +373,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { } /// TODO: Isolate to queue - private func isPumpDataStale() -> Bool { + private var isPumpDataStale: Bool { // How long should we wait before we poll for new pump data? let pumpStatusAgeTolerance = rileyLinkManager.idleListeningEnabled ? TimeInterval(minutes: 6) : TimeInterval(minutes: 4) @@ -387,9 +384,9 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { var lastReservoirDate = pumpManagerDelegate?.startDateToFilterNewReservoirEvents(for: self) ?? .distantPast // Look for reservoir data from MySentry that hasn't yet been written (due to 11-second imposed delay) - if let sentryStatus = latestPumpStatusFromMySentry, let timeZone = pumpState?.timeZone { + if let sentryStatus = latestPumpStatusFromMySentry { var components = sentryStatus.pumpDateComponents - components.timeZone = timeZone + components.timeZone = state.timeZone lastReservoirDate = max(components.date ?? .distantPast, lastReservoirDate) } @@ -404,7 +401,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { public func assertCurrentPumpData() { rileyLinkManager.assertIdleListening(forcingRestart: true) - guard isPumpDataStale() else { + guard isPumpDataStale else { return } @@ -412,7 +409,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { rileyLinkManager.getDevices { (devices) in guard let device = devices.firstConnected else { - let error = PumpManagerError.connection(nil) + let error = PumpManagerError.connection(MinimedPumpManagerError.noRileyLink) self.log.error("No devices found while fetching pump data") self.pumpManagerDelegate?.pumpManager(self, didError: error) return @@ -451,7 +448,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { let pumpManagerStatus = PumpManagerStatus( date: date, timeZone: session.pump.timeZone, - device: deviceStatus.device(settings: self.pumpSettings, pumpState: self.pumpState), + device: deviceStatus.device(pumpID: self.state.pumpID, pumpModel: self.state.pumpModel), lastValidFrequency: deviceState?.lastValidFrequency, lastTuned: deviceState?.lastTuned, battery: PumpManagerStatus.BatteryStatus( @@ -496,7 +493,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { pumpOps.runSession(withName: "Bolus", using: rileyLinkManager.firstConnectedDevice) { (session) in guard let session = session else { - completion(PumpManagerError.connection(nil)) + completion(PumpManagerError.connection(MinimedPumpManagerError.noRileyLink)) return } @@ -540,7 +537,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { public func enactTempBasal(unitsPerHour: Double, for duration: TimeInterval, completion: @escaping (PumpManagerResult) -> Void) { pumpOps.runSession(withName: "Set Temp Basal", using: rileyLinkManager.firstConnectedDevice) { (session) in guard let session = session else { - completion(.failure(PumpManagerError.connection(nil))) + completion(.failure(PumpManagerError.connection(MinimedPumpManagerError.noRileyLink))) return } @@ -592,22 +589,15 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { // MARK: Pump - public func getStateForDevice(_ device: RileyLinkDevice, completion: @escaping (_ deviceState: DeviceState, _ pumpState: PumpState?, _ pumpSettings: PumpSettings?, _ pumpOps: PumpOps) -> Void) { + // TODO + public func getStateForDevice(_ device: RileyLinkDevice, completion: @escaping (_ deviceState: DeviceState, _ pumpOps: PumpOps) -> Void) { queue.async { - completion(self.deviceStates[device.peripheralIdentifier, default: DeviceState()], self.pumpState, self.pumpSettings, self.pumpOps) + completion(self.deviceStates[device.peripheralIdentifier, default: DeviceState()], self.pumpOps) } } public private(set) var pumpOps: PumpOps! - private var pumpSettings: PumpSettings { - return state.pumpSettings - } - - private var pumpState: PumpState? { - return state.pumpState - } - /// The user's preferred method of fetching insulin data from the pump public var preferredInsulinDataSource: InsulinDataSource { get { @@ -632,7 +622,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { extension MinimedPumpManager: PumpOpsDelegate { public func pumpOps(_ pumpOps: PumpOps, didChange state: PumpState) { - // We don't care + self.state.pumpState = state } } @@ -657,7 +647,7 @@ extension MinimedPumpManager: CGMManager { public func fetchNewDataIfNeeded(_ completion: @escaping (CGMResult) -> Void) { rileyLinkManager.getDevices { (devices) in guard let device = devices.firstConnected else { - completion(.error(PumpManagerError.connection(nil))) + completion(.error(PumpManagerError.connection(MinimedPumpManagerError.noRileyLink))) return } diff --git a/MinimedKit/PumpManager/MinimedPumpManagerError.swift b/MinimedKit/PumpManager/MinimedPumpManagerError.swift index ae1311507..970bd178b 100644 --- a/MinimedKit/PumpManager/MinimedPumpManagerError.swift +++ b/MinimedKit/PumpManager/MinimedPumpManagerError.swift @@ -8,6 +8,7 @@ import Foundation public enum MinimedPumpManagerError: Error { + case noRileyLink case noDate case noDelegate case tuneFailed(LocalizedError) @@ -17,6 +18,8 @@ public enum MinimedPumpManagerError: Error { extension MinimedPumpManagerError: LocalizedError { public var errorDescription: String? { switch self { + case .noRileyLink: + return nil case .noDate: return nil case .noDelegate: @@ -25,4 +28,17 @@ extension MinimedPumpManagerError: LocalizedError { return [NSLocalizedString("RileyLink radio tune failed", comment: "Error description"), error.errorDescription].compactMap({ $0 }).joined(separator: ". ") } } + + public var recoverySuggestion: String? { + switch self { + case .noRileyLink: + return NSLocalizedString("Make sure your RileyLink is nearby and powered on", comment: "Recovery suggestion") + case .noDate: + return nil + case .noDelegate: + return nil + case .tuneFailed(_): + return nil + } + } } diff --git a/MinimedKit/PumpManager/PumpOps.swift b/MinimedKit/PumpManager/PumpOps.swift index 409e7f6aa..abef91cc7 100644 --- a/MinimedKit/PumpManager/PumpOps.swift +++ b/MinimedKit/PumpManager/PumpOps.swift @@ -18,11 +18,17 @@ public protocol PumpOpsDelegate: class { public class PumpOps { - private var pumpSettings: PumpSettings + public let pumpSettings: PumpSettings private var pumpState: PumpState { didSet { delegate?.pumpOps(self, didChange: pumpState) + + NotificationCenter.default.post( + name: .PumpOpsStateDidChange, + object: self, + userInfo: [PumpOps.notificationPumpStateKey: pumpState] + ) } } @@ -44,17 +50,6 @@ public class PumpOps { } } - public func updateSettings(_ settings: PumpSettings) { - sessionQueue.async { - let oldSettings = self.pumpSettings - self.pumpSettings = settings - - if oldSettings.pumpID != settings.pumpID { - self.pumpState = PumpState() - } - } - } - public func runSession(withName name: String, using deviceSelector: @escaping (_ completion: @escaping (_ device: RileyLinkDevice?) -> Void) -> Void, _ block: @escaping (_ session: PumpOpsSession?) -> Void) { sessionQueue.async { deviceSelector { (device) in @@ -111,6 +106,12 @@ public class PumpOps { NotificationCenter.default.removeObserver(self, name: .DeviceConnectionStateDidChange, object: device) configuredDevices.remove(device) } + + public func getPumpState(_ completion: @escaping (_ state: PumpState) -> Void) { + sessionQueue.async { + completion(self.pumpState) + } + } } @@ -119,3 +120,26 @@ extension PumpOps: PumpOpsSessionDelegate { self.pumpState = state } } + + +extension PumpOps: CustomDebugStringConvertible { + public var debugDescription: String { + return [ + "### PumpOps", + "pumpSettings: \(String(reflecting: pumpSettings))", + "pumpState: \(String(reflecting: pumpState))", + "configuredDevices: \(configuredDevices.map({ $0.peripheralIdentifier.uuidString }))", + ].joined(separator: "\n") + } +} + + +/// Provide a notification contract that clients can use to inform RileyLink UI of changes to PumpOps.PumpState +extension PumpOps { + public static let notificationPumpStateKey = "com.rileylink.RileyLinkKit.PumpOps.PumpState" +} + + +extension Notification.Name { + public static let PumpOpsStateDidChange = Notification.Name(rawValue: "com.rileylink.RileyLinkKit.PumpOpsStateDidChange") +} diff --git a/MinimedKit/PumpManager/RileyLinkDevice.swift b/MinimedKit/PumpManager/RileyLinkDevice.swift index 72d1e926c..b92cdd82a 100644 --- a/MinimedKit/PumpManager/RileyLinkDevice.swift +++ b/MinimedKit/PumpManager/RileyLinkDevice.swift @@ -10,15 +10,15 @@ import RileyLinkBLEKit extension RileyLinkDevice.Status { - func device(settings: PumpSettings?, pumpState: PumpState?) -> HKDevice { + func device(pumpID: String, pumpModel: PumpModel) -> HKDevice { return HKDevice( name: name, manufacturer: "Medtronic", - model: pumpState?.pumpModel?.rawValue, + model: pumpModel.rawValue, hardwareVersion: nil, firmwareVersion: radioFirmwareVersion?.description, softwareVersion: String(MinimedKitVersionNumber), - localIdentifier: settings?.pumpID, + localIdentifier: pumpID, udiDeviceIdentifier: nil ) } diff --git a/MinimedKitUI/CommandResponseViewController.swift b/MinimedKitUI/CommandResponseViewController.swift index 35b8dfa22..979e96957 100644 --- a/MinimedKitUI/CommandResponseViewController.swift +++ b/MinimedKitUI/CommandResponseViewController.swift @@ -44,7 +44,7 @@ extension CommandResponseViewController { let response: String do { guard let session = session else { - throw PumpManagerError.connection(nil) + throw PumpManagerError.connection(MinimedPumpManagerError.noRileyLink) } try session.setTimeToNow(in: .current) diff --git a/MinimedKitUI/MinimedPumpManager+UI.swift b/MinimedKitUI/MinimedPumpManager+UI.swift index 44d372280..071ef41ed 100644 --- a/MinimedKitUI/MinimedPumpManager+UI.swift +++ b/MinimedKitUI/MinimedPumpManager+UI.swift @@ -31,7 +31,7 @@ extension MinimedPumpManager { public func syncDeliveryLimitSettings(for viewController: DeliveryLimitSettingsTableViewController, completion: @escaping (DeliveryLimitSettingsResult) -> Void) { pumpOps.runSession(withName: "Save Settings", using: rileyLinkManager.firstConnectedDevice) { (session) in guard let session = session else { - completion(.failure(PumpManagerError.connection(nil))) + completion(.failure(PumpManagerError.connection(MinimedPumpManagerError.noRileyLink))) return } @@ -72,7 +72,7 @@ extension MinimedPumpManager { public func syncScheduleValues(for viewController: SingleValueScheduleTableViewController, completion: @escaping (RepeatingScheduleValueResult) -> Void) { pumpOps.runSession(withName: "Save Basal Profile", using: rileyLinkManager.firstConnectedDevice) { (session) in guard let session = session else { - completion(.failure(PumpManagerError.connection(nil))) + completion(.failure(PumpManagerError.connection(MinimedPumpManagerError.noRileyLink))) return } diff --git a/MinimedKitUI/MinimedPumpSettingsViewController.swift b/MinimedKitUI/MinimedPumpSettingsViewController.swift index 95996d93a..b8f8474a0 100644 --- a/MinimedKitUI/MinimedPumpSettingsViewController.swift +++ b/MinimedKitUI/MinimedPumpSettingsViewController.swift @@ -44,6 +44,17 @@ class MinimedPumpSettingsViewController: RileyLinkSettingsViewController { tableView.tableHeaderView = imageView } + override func viewWillAppear(_ animated: Bool) { + if clearsSelectionOnViewWillAppear { + // Manually invoke the delegate for rows deselecting on appear + for indexPath in tableView.indexPathsForSelectedRows ?? [] { + _ = tableView(tableView, willDeselectRowAt: indexPath) + } + } + + super.viewWillAppear(animated) + } + // MARK: - Data Source private enum Section: Int { @@ -203,13 +214,11 @@ class MinimedPumpSettingsViewController: RileyLinkSettingsViewController { case .rileyLinks: let device = devicesDataSource.devices[indexPath.row] - pumpManager.getStateForDevice(device) { (deviceState, pumpState, pumpSettings, pumpOps) in + pumpManager.getStateForDevice(device) { (deviceState, pumpOps) in DispatchQueue.main.async { let vc = RileyLinkMinimedDeviceTableViewController( device: device, deviceState: deviceState, - pumpSettings: pumpSettings, - pumpState: pumpState, pumpOps: pumpOps ) @@ -227,6 +236,28 @@ class MinimedPumpSettingsViewController: RileyLinkSettingsViewController { } } } + + override func tableView(_ tableView: UITableView, willDeselectRowAt indexPath: IndexPath) -> IndexPath? { + switch Section(rawValue: indexPath.section)! { + case .info: + break + case .settings: + switch SettingsRow(rawValue: indexPath.row)! { + case .timeZoneOffset: + tableView.reloadRows(at: [indexPath], with: .fade) + case .batteryChemistry: + break + case .preferredInsulinDataSource: + break + } + case .rileyLinks: + break + case .delete: + break + } + + return indexPath + } } diff --git a/MinimedKitUI/PumpOps.swift b/MinimedKitUI/PumpOps.swift deleted file mode 100644 index a1b054472..000000000 --- a/MinimedKitUI/PumpOps.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// PumpOps.swift -// RileyLinkKitUI -// -// Copyright © 2017 Pete Schwamb. All rights reserved. -// - -import MinimedKit - - -/// Provide a notification contract that clients can use to inform RileyLink UI of changes to PumpOps.PumpState -extension PumpOps { - public static let notificationPumpStateKey = "com.rileylink.RileyLinkKit.PumpOps.PumpState" -} - -extension Notification.Name { - public static let PumpOpsStateDidChange = Notification.Name(rawValue: "com.rileylink.RileyLinkKit.PumpOpsStateDidChange") -} diff --git a/MinimedKitUI/RileyLinkMinimedDeviceTableViewController.swift b/MinimedKitUI/RileyLinkMinimedDeviceTableViewController.swift index c207d6afe..ff0325be3 100644 --- a/MinimedKitUI/RileyLinkMinimedDeviceTableViewController.swift +++ b/MinimedKitUI/RileyLinkMinimedDeviceTableViewController.swift @@ -22,34 +22,23 @@ public class RileyLinkMinimedDeviceTableViewController: UITableViewController { private var deviceState: DeviceState - private let ops: PumpOps? + private let ops: PumpOps private var pumpState: PumpState? { didSet { // Update the UI if its visible guard rssiFetchTimer != nil else { return } - switch (oldValue, pumpState) { - case (.none, .some): - tableView.insertSections(IndexSet(integer: Section.commands.rawValue), with: .automatic) - case (.some, .none): - tableView.deleteSections(IndexSet(integer: Section.commands.rawValue), with: .automatic) - case (_, let state?): - if let cell = cellForRow(.awake) { - cell.setAwakeUntil(state.awakeUntil, formatter: dateFormatter) - } + if let cell = cellForRow(.awake) { + cell.setAwakeUntil(pumpState?.awakeUntil, formatter: dateFormatter) + } - if let cell = cellForRow(.model) { - cell.setPumpModel(state.pumpModel) - } - default: - break + if let cell = cellForRow(.model) { + cell.setPumpModel(pumpState?.pumpModel) } } } - private let pumpSettings: PumpSettings? - private var bleRSSI: Int? private var firmwareVersion: String? { @@ -72,7 +61,7 @@ public class RileyLinkMinimedDeviceTableViewController: UITableViewController { } } - var rssiFetchTimer: Timer? { + private var rssiFetchTimer: Timer? { willSet { rssiFetchTimer?.invalidate() } @@ -80,16 +69,19 @@ public class RileyLinkMinimedDeviceTableViewController: UITableViewController { private var appeared = false - public init(device: RileyLinkDevice, deviceState: DeviceState, pumpSettings: PumpSettings?, pumpState: PumpState?, pumpOps: PumpOps?) { + public init(device: RileyLinkDevice, deviceState: DeviceState, pumpOps: PumpOps) { self.device = device self.deviceState = deviceState - self.pumpSettings = pumpSettings - self.pumpState = pumpState self.ops = pumpOps super.init(style: .grouped) updateDeviceStatus() + pumpOps.getPumpState { (state) in + DispatchQueue.main.async { + self.pumpState = state + } + } } required public init?(coder aDecoder: NSCoder) { @@ -108,7 +100,7 @@ public class RileyLinkMinimedDeviceTableViewController: UITableViewController { device.readRSSI() } - func updateDeviceStatus() { + private func updateDeviceStatus() { device.getStatus { (status) in DispatchQueue.main.async { self.lastIdle = status.lastIdle @@ -257,11 +249,7 @@ public class RileyLinkMinimedDeviceTableViewController: UITableViewController { } public override func numberOfSections(in tableView: UITableView) -> Int { - if pumpState == nil { - return Section.count - 1 - } else { - return Section.count - } + return Section.count } public override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { @@ -311,11 +299,7 @@ public class RileyLinkMinimedDeviceTableViewController: UITableViewController { switch PumpRow(rawValue: indexPath.row)! { case .id: cell.textLabel?.text = NSLocalizedString("Pump ID", comment: "The title of the cell showing pump ID") - if let pumpID = pumpSettings?.pumpID { - cell.detailTextLabel?.text = pumpID - } else { - cell.detailTextLabel?.text = "–" - } + cell.detailTextLabel?.text = ops.pumpSettings.pumpID case .model: cell.textLabel?.text = NSLocalizedString("Pump Model", comment: "The title of the cell showing the pump model number") cell.setPumpModel(pumpState?.pumpModel) diff --git a/MinimedKitUI/Setup/MinimedPumpIDSetupViewController.swift b/MinimedKitUI/Setup/MinimedPumpIDSetupViewController.swift index 6208aa148..f29034ee5 100644 --- a/MinimedKitUI/Setup/MinimedPumpIDSetupViewController.swift +++ b/MinimedKitUI/Setup/MinimedPumpIDSetupViewController.swift @@ -236,7 +236,7 @@ class MinimedPumpIDSetupViewController: SetupTableViewController { pumpOps.runSession(withName: "Pump ID Setup", using: rileyLinkPumpManager.rileyLinkManager.firstConnectedDevice, { (session) in guard let session = session else { DispatchQueue.main.async { - self.lastError = PumpManagerError.connection(nil) + self.lastError = PumpManagerError.connection(MinimedPumpManagerError.noRileyLink) } return } @@ -283,7 +283,7 @@ class MinimedPumpIDSetupViewController: SetupTableViewController { if self.pumpState != nil { self.continueState = .completed } else { - self.lastError = PumpManagerError.connection(nil) + self.lastError = PumpManagerError.connection(MinimedPumpManagerError.noRileyLink) } } } catch let error { diff --git a/MinimedKitUI/Setup/MinimedPumpSentrySetupViewController.swift b/MinimedKitUI/Setup/MinimedPumpSentrySetupViewController.swift index acb11ddde..e13a71c95 100644 --- a/MinimedKitUI/Setup/MinimedPumpSentrySetupViewController.swift +++ b/MinimedKitUI/Setup/MinimedPumpSentrySetupViewController.swift @@ -78,7 +78,7 @@ class MinimedPumpSentrySetupViewController: SetupTableViewController { private func listenForPairing() { guard let pumpManager = pumpManager else { continueState = .notStarted - lastError = PumpManagerError.connection(nil) + lastError = PumpManagerError.connection(MinimedPumpManagerError.noRileyLink) return } @@ -88,7 +88,7 @@ class MinimedPumpSentrySetupViewController: SetupTableViewController { guard let session = session else { DispatchQueue.main.async { self.continueState = .notStarted - self.lastError = PumpManagerError.connection(nil) + self.lastError = PumpManagerError.connection(MinimedPumpManagerError.noRileyLink) } return } diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 60b6e74b8..8ed9ea739 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -80,7 +80,6 @@ 4352A73220DEC9D600CAC200 /* CommandResponseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4352A73120DEC9D600CAC200 /* CommandResponseViewController.swift */; }; 4352A73320DEC9FC00CAC200 /* RileyLinkKitUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43D5E78E1FAF7BFB004ACDB7 /* RileyLinkKitUI.framework */; }; 4352A73420DECAE000CAC200 /* LoopKitUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43FB610A20DDF55E002B996B /* LoopKitUI.framework */; }; - 4352A73720DECB7300CAC200 /* PumpOps.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435535D71FB7987000CE5A23 /* PumpOps.swift */; }; 4352A73920DECBAA00CAC200 /* RileyLinkMinimedDeviceTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4352A73820DECBAA00CAC200 /* RileyLinkMinimedDeviceTableViewController.swift */; }; 4352A73A20DECDB300CAC200 /* MinimedKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C10D9BC11C8269D500378342 /* MinimedKit.framework */; }; 4352A73F20DED02C00CAC200 /* HKUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4352A73D20DED01700CAC200 /* HKUnit.swift */; }; @@ -695,7 +694,6 @@ 4352A73D20DED01700CAC200 /* HKUnit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HKUnit.swift; sourceTree = ""; }; 4352A74020DED23000CAC200 /* RileyLinkDeviceManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkDeviceManager.swift; sourceTree = ""; }; 435535D51FB6D98400CE5A23 /* UserDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaults.swift; sourceTree = ""; }; - 435535D71FB7987000CE5A23 /* PumpOps.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PumpOps.swift; sourceTree = ""; }; 435535DB1FB8B37E00CE5A23 /* PumpMessage+PumpOpsSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PumpMessage+PumpOpsSession.swift"; sourceTree = ""; }; 435D26AF20DA08CE00891C17 /* RileyLinkPumpManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkPumpManager.swift; sourceTree = ""; }; 435D26B120DA091B00891C17 /* RileyLinkPumpManagerState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RileyLinkPumpManagerState.swift; sourceTree = ""; }; @@ -1289,7 +1287,6 @@ 43709AE020DF1D5400F941B3 /* MinimedPumpManager.storyboard */, 43709ACC20DF1CC900F941B3 /* Setup */, 4352A73120DEC9D600CAC200 /* CommandResponseViewController.swift */, - 435535D71FB7987000CE5A23 /* PumpOps.swift */, 4352A73820DECBAA00CAC200 /* RileyLinkMinimedDeviceTableViewController.swift */, 43709AC320DF1C8B00F941B3 /* MinimedPumpManager+UI.swift */, 43709AC220DF1C8B00F941B3 /* MinimedPumpSettingsViewController.swift */, @@ -2526,7 +2523,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4352A73720DECB7300CAC200 /* PumpOps.swift in Sources */, 43709AD420DF1CF800F941B3 /* MinimedPumpIDSetupViewController.swift in Sources */, 43709AD520DF1CF800F941B3 /* MinimedPumpManagerSetupViewController.swift in Sources */, 43709AD320DF1CF800F941B3 /* MinimedPumpClockSetupViewController.swift in Sources */, diff --git a/RileyLink/DeviceDataManager.swift b/RileyLink/DeviceDataManager.swift index ca78dcd90..8b7413411 100644 --- a/RileyLink/DeviceDataManager.swift +++ b/RileyLink/DeviceDataManager.swift @@ -43,11 +43,7 @@ class DeviceDataManager { } set { if let settings = newValue { - if let pumpOps = pumpOps { - pumpOps.updateSettings(settings) - } else { - pumpOps = PumpOps(pumpSettings: settings, pumpState: nil, delegate: self) - } + pumpOps = PumpOps(pumpSettings: settings, pumpState: nil, delegate: self) } else { pumpOps = nil } @@ -405,11 +401,5 @@ extension DeviceDataManager: PumpOpsDelegate { } UserDefaults.standard.pumpState = state - - NotificationCenter.default.post( - name: .PumpOpsStateDidChange, - object: pumpOps, - userInfo: [PumpOps.notificationPumpStateKey: state] - ) } } diff --git a/RileyLink/View Controllers/RileyLinkListTableViewController.swift b/RileyLink/View Controllers/RileyLinkListTableViewController.swift index c32651c36..c014ba92f 100644 --- a/RileyLink/View Controllers/RileyLinkListTableViewController.swift +++ b/RileyLink/View Controllers/RileyLinkListTableViewController.swift @@ -159,15 +159,14 @@ class RileyLinkListTableViewController: UITableViewController { // MARK: - UITableViewDelegate override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + guard let pumpOps = dataManager.pumpOps else { + return + } let device = devices[indexPath.row] let vc = RileyLinkMinimedDeviceTableViewController( device: device, deviceState: dataManager.deviceStates[device.peripheralIdentifier, default: DeviceState()], - pumpSettings: dataManager.pumpSettings, - pumpState: dataManager.pumpState, - pumpOps: dataManager.pumpOps - ) - + pumpOps: pumpOps) show(vc, sender: indexPath) } } diff --git a/RileyLinkBLEKit/PeripheralManager+RileyLink.swift b/RileyLinkBLEKit/PeripheralManager+RileyLink.swift index eeaff68ec..4873e1d33 100644 --- a/RileyLinkBLEKit/PeripheralManager+RileyLink.swift +++ b/RileyLinkBLEKit/PeripheralManager+RileyLink.swift @@ -330,7 +330,7 @@ extension PeripheralManager { guard let code = ResponseCode(rawValue: value[0]) else { let unknownCode = value[0..<1].hexadecimalString - log.debug("Unknown response code from RileyLink: %{public}@. Continuing to listen for command response.", unknownCode) + log.error("Unknown response code from RileyLink: %{public}@. Continuing to listen for command response.", unknownCode) return false } @@ -341,7 +341,7 @@ extension PeripheralManager { return false default: guard let response = R(data: value) else { - log.debug("Unable to parse response.") + log.error("Unable to parse response.") // We don't recognize the contents. Keep listening. return false } diff --git a/RileyLinkBLEKit/PeripheralManager.swift b/RileyLinkBLEKit/PeripheralManager.swift index 1fce10461..ad8206768 100644 --- a/RileyLinkBLEKit/PeripheralManager.swift +++ b/RileyLinkBLEKit/PeripheralManager.swift @@ -107,10 +107,16 @@ extension PeripheralManager { if self.needsConfiguration || self.peripheral.services == nil { do { try self.applyConfiguration() + } catch let error { + self.log.error("Error applying peripheral configuration: %@", String(describing: error)) + // Will retry + } + + do { try self.delegate?.completeConfiguration(for: self) self.needsConfiguration = false } catch let error { - self.log.debug("Error applying configuration: %@", String(describing: error)) + self.log.error("Error applying delegate configuration: %@", String(describing: error)) // Will retry } } diff --git a/RileyLinkBLEKit/RileyLinkDevice.swift b/RileyLinkBLEKit/RileyLinkDevice.swift index cbe42f715..e56286c76 100644 --- a/RileyLinkBLEKit/RileyLinkDevice.swift +++ b/RileyLinkBLEKit/RileyLinkDevice.swift @@ -301,7 +301,7 @@ extension RileyLinkDevice: PeripheralManagerDelegate { } } } else { - self.log.debug("Unknown idle response: %@", value.hexadecimalString) + self.log.error("Unknown idle response: %@", value.hexadecimalString) } } diff --git a/RileyLinkBLEKit/RileyLinkDeviceManager.swift b/RileyLinkBLEKit/RileyLinkDeviceManager.swift index 96ef354ba..153eab681 100644 --- a/RileyLinkBLEKit/RileyLinkDeviceManager.swift +++ b/RileyLinkBLEKit/RileyLinkDeviceManager.swift @@ -219,7 +219,7 @@ extension RileyLinkDeviceManager { // MARK: - Delegate methods called on `centralQueue` extension RileyLinkDeviceManager: CBCentralManagerDelegate { public func centralManager(_ central: CBCentralManager, willRestoreState dict: [String : Any]) { - log.info("%@", #function) + log.default("%@", #function) guard let peripherals = dict[CBCentralManagerRestoredStatePeripheralsKey] as? [CBPeripheral] else { return @@ -231,7 +231,7 @@ extension RileyLinkDeviceManager: CBCentralManagerDelegate { } public func centralManagerDidUpdateState(_ central: CBCentralManager) { - log.info("%@: %@", #function, central.state.description) + log.default("%@: %@", #function, central.state.description) if case .poweredOn = central.state { autoConnectDevices() @@ -248,13 +248,13 @@ extension RileyLinkDeviceManager: CBCentralManagerDelegate { } public func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { - log.info("Discovered %@ at %@", peripheral, RSSI) + log.default("Discovered %@ at %@", peripheral, RSSI) addPeripheral(peripheral) // TODO: Should we keep scanning? There's no UI to remove a lost RileyLink, which could result in a battery drain due to indefinite scanning. if !isScanningEnabled && central.isScanning && hasDiscoveredAllAutoConnectDevices { - log.info("All peripherals discovered") + log.default("All peripherals discovered") central.stopScan() } } diff --git a/RileyLinkKit/PumpOpsSession.swift b/RileyLinkKit/PumpOpsSession.swift index d6b3134db..2d90214b5 100644 --- a/RileyLinkKit/PumpOpsSession.swift +++ b/RileyLinkKit/PumpOpsSession.swift @@ -489,7 +489,9 @@ extension PumpOpsSession { try setTime { () -> DateComponents in var calendar = Calendar(identifier: .gregorian) calendar.timeZone = timeZone - return calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: Date()) + var components = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: Date()) + components.timeZone = timeZone + return components } } From 75353286b11665c710868e92036373edae547fa5 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 15 Jul 2018 09:13:38 -0400 Subject: [PATCH 06/22] Fix logic for history event time shifting (#419) * Fix logic for history event time shifting Fixing an issue where an accidental time change of more than +1 hour could cause history fetching to exit early. Also, improving error display. * Fix test --- .../HistoryPage+PumpOpsSession.swift | 8 +- MinimedKit/PumpManager/PumpOpsError.swift | 87 ++++++++++--------- MinimedKitTests/HistoryPageTests.swift | 36 ++++++++ ...mpOpsSynchronousBuildFromFramesTests.swift | 2 +- RileyLinkBLEKit/PeripheralManagerError.swift | 2 +- RileyLinkKit/PumpOpsSession.swift | 2 + 6 files changed, 91 insertions(+), 46 deletions(-) diff --git a/MinimedKit/PumpManager/HistoryPage+PumpOpsSession.swift b/MinimedKit/PumpManager/HistoryPage+PumpOpsSession.swift index 89c192a43..121fbae04 100644 --- a/MinimedKit/PumpManager/HistoryPage+PumpOpsSession.swift +++ b/MinimedKit/PumpManager/HistoryPage+PumpOpsSession.swift @@ -33,6 +33,10 @@ extension HistoryPage { var timestamp = event.timestamp timestamp.timeZone = timeZone + if let changeTimeEvent = event as? ChangeTimePumpEvent, let newTimeEvent = lastEvent as? NewTimePumpEvent { + timeAdjustmentInterval += (newTimeEvent.timestamp.date?.timeIntervalSince(changeTimeEvent.timestamp.date!))! + } + if let date = timestamp.date?.addingTimeInterval(timeAdjustmentInterval) { let shouldCheckDateForCompletion = !event.isDelayedAppend(with: model) @@ -56,10 +60,6 @@ extension HistoryPage { } } - if let changeTimeEvent = event as? ChangeTimePumpEvent, let newTimeEvent = lastEvent as? NewTimePumpEvent { - timeAdjustmentInterval += (newTimeEvent.timestamp.date?.timeIntervalSince(changeTimeEvent.timestamp.date!))! - } - lastEvent = event } diff --git a/MinimedKit/PumpManager/PumpOpsError.swift b/MinimedKit/PumpManager/PumpOpsError.swift index eae6c1560..1852a23d6 100644 --- a/MinimedKit/PumpManager/PumpOpsError.swift +++ b/MinimedKit/PumpManager/PumpOpsError.swift @@ -33,47 +33,34 @@ public enum PumpOpsError: Error { case unknownResponse(rx: Data, during: CustomStringConvertible) } -public enum SetBolusError: Error { - case certain(PumpOpsError) - case uncertain(PumpOpsError) -} - - -extension SetBolusError: LocalizedError { - public func errorDescriptionWithUnits(_ units: Double) -> String { - let format: String - - switch self { - case .certain: - format = NSLocalizedString("%1$@ U bolus failed", comment: "Describes a certain bolus failure (1: size of the bolus in units)") - case .uncertain: - format = NSLocalizedString("%1$@ U bolus may not have succeeded", comment: "Describes an uncertain bolus failure (1: size of the bolus in units)") - } - - return String(format: format, NumberFormatter.localizedString(from: NSNumber(value: units), number: .decimal)) - } - - public var failureReason: String? { - switch self { - case .certain(let error): - return error.failureReason - case .uncertain(let error): - return error.failureReason - } - } - - public var recoverySuggestion: String? { +extension PumpOpsError: LocalizedError { + public var errorDescription: String? { switch self { - case .certain: - return NSLocalizedString("It is safe to retry.", comment: "Recovery instruction for a certain bolus failure") - case .uncertain: - return NSLocalizedString("Check your pump before retrying.", comment: "Recovery instruction for an uncertain bolus failure") + case .bolusInProgress: + return nil + case .crosstalk: + return nil + case .deviceError: + return NSLocalizedString("Device Error", comment: "Error description") + case .noResponse: + return nil + case .pumpError: + return NSLocalizedString("Pump Error", comment: "Error description") + case .pumpSuspended: + return nil + case .rfCommsFailure: + return nil + case .unexpectedResponse: + return nil + case .unknownPumpErrorCode: + return nil + case .unknownPumpModel: + return nil + case .unknownResponse: + return nil } } -} - -extension PumpOpsError: LocalizedError { public var failureReason: String? { switch self { case .bolusInProgress: @@ -93,11 +80,11 @@ extension PumpOpsError: LocalizedError { case .unknownPumpModel(let model): return String(format: NSLocalizedString("Unknown pump model: %@.", comment: ""), model) case .unknownResponse(rx: let data, during: let during): - return String(format: NSLocalizedString("Unknown response during %1$@: %2$@", comment: "Format string for an unknown response. (1: The operation being performed) (2: The response data)"), String(describing: during), String(describing: data)) + return String(format: NSLocalizedString("Unknown response during %1$@: %2$@", comment: "Format string for an unknown response. (1: The operation being performed) (2: The response data)"), String(describing: during), data.hexadecimalString) case .pumpError(let errorCode): - return String(format: NSLocalizedString("Pump error: %1$@.", comment: "The format string description of a Pump Error. (1: The specific error code)"), String(describing: errorCode)) + return String(describing: errorCode) case .deviceError(let error): - return String(format: NSLocalizedString("Device communication failed: %@.", comment: "Pump comms failure reason for an underlying peripheral error"), error.failureReason ?? "") + return [error.errorDescription, error.failureReason].compactMap({ $0 }).joined(separator: ". ") } } @@ -105,6 +92,17 @@ extension PumpOpsError: LocalizedError { switch self { case .pumpError(let errorCode): return errorCode.recoverySuggestion + case .deviceError(let error): + return error.recoverySuggestion + default: + return nil + } + } + + public var helpAnchor: String? { + switch self { + case .deviceError(let error): + return error.helpAnchor default: return nil } @@ -139,4 +137,13 @@ extension PumpCommandError: LocalizedError { return error.recoverySuggestion } } + + public var helpAnchor: String? { + switch self { + case .arguments(let error): + return error.helpAnchor + case .command(let error): + return error.helpAnchor + } + } } diff --git a/MinimedKitTests/HistoryPageTests.swift b/MinimedKitTests/HistoryPageTests.swift index f8f415af6..fd98b9d0a 100644 --- a/MinimedKitTests/HistoryPageTests.swift +++ b/MinimedKitTests/HistoryPageTests.swift @@ -401,4 +401,40 @@ class HistoryPageTests: XCTestCase { XCTAssert(events[23] is PlaceholderPumpEvent) XCTAssert(events[23].rawData[0] == PumpEventType.changeSensorAutoCalEnable.rawValue) } + + func testHistoryTimeShift() throws { + let model = PumpModel.model523 + + let pages = [ + "16004ee2124d127b044fe2120d121d240033004ee7124d120016014ee7124d1233004eec124d120016004eec124d127b044eec120d121d240033004ef1124d120016014ef1124d1233004ec9134d120016014ec9134d1233004ece134d120016004ece134d127b044ece130d121d2400338d4edd134d120016014edd134d1200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fc9d", + "7b014fec040d12062800334c5ff1054d120016015ff1054d1233004ff6054d120016004ff6054d127b014ff6050d1206280001008a008a00000055d1264d1233004fe2064d120016014fe2064d1233004ff6064d120016004ff6064d127b014ff6060d1206280033514ffb064d120016014ffb064d1233004fc4074d120016004fc4074d127b024fc4070d120e240001004a004a006f0077cd274d12336e5ed3074d120016015ed3074d12334e5dd8074d120016015dd8074d1233004fdd074d120016004fdd074d127b024fdd070d120e2400330050fb074d1200160150fb074d1233004fd3084d120016014fd3084d1233004fd8084d120016004fd8084d127b024fd8080d120e240033ba4eec084d120016014eec084d1233ba4fc4094d120016014fc4094d1201007800780030004cd6294d1233004fdd094d120016004fdd094d127b024fdd090d120e240033004ff1094d120016014ff1094d1233004fc90a4d120016014fc90a4d1233004fdd0a4d120016014fdd0a4d1233005bf10a4d120016015bf10a4d1233004fc90b4d120016014fc90b4d1233004fdd0b4d120016014fdd0b4d1233004fec0b4d120016004fec0b4d127b034fec0b0d121720000100660066001d0060c12c4d12336151c90c4d1200160151c90c4d12335c4ece0c4d120016014ece0c4d12334f4fd30c4d120016014fd30c4d1233554ed80c4d120016014ed80c4d12335b4edd0c4d120016014edd0c4d1233004ee20c4d120016004ee20c4d127b034fe20c0d1217200033004ffb0d4d120016014ffb0d4d1233004fd30e4d120016014fd30e4d1233004fd80e4d120016004fd80e4d127b034fd80e0d121720007b0440de0e0d121d240033004fe20e4d120016014fe20e4d12330050e70e4d1200160050e70e4d127b0450e70e0d121d240033594edd0f4d120016014edd0f4d1233464fe20f4d120016014fe20f4d12336c4fe70f4d120016014fe70f4d1233804eec0f4d120016014eec0f4d1233764ff10f4d120016014ff10f4d1233644ff60f4d120016014ff60f4d1233575ffb0f4d120016015ffb0f4d12334b65c4104d1200160165c4104d1233004fc9104d120016004fc9104d127b044fc9100d121d240033004fce104d120016014fce104d1233004fe2104d120016014fe2104d1233004fec104d120016004fec104d127b044fec100d121d240033004ffb104d120016014ffb104d12330050d3114d1200160150d3114d1233004fe2114d120016004fe2114d127b044fe2110d121d240033634ec9124d120016014ec9124d12010078007800000060c9324d1233ba4ece124d120016014ece124d1233b24ed3124d120016014ed3124d1233914ed8124d120016014ed8124d1233774edd124d120016014edd124d1233004ee2124d120000000000362c", + "16014ee2144c1233644fe7144c120016014fe7144c1233634fec144c120016014fec144c12335a4ff1144c120016014ff1144c1233004ef6144c120016004ef6144c127b044ef6140c121d24007b0540c0150c122a300033684ece154c120016014ece154c12336f4ed3154c120016014ed3154c1233605fd8154c120016015fd8154c1233004fdd154c120016004fdd154c127b054fdd150c122a3000334a4fe2154c120016014fe2154c12334b4fe7154c120016014fe7154c12330044f2154c1200160144f2154c12334a4ec4164c120016014ec4164c1233555fc9164c120016015fc9164c121e0171d0160c127b0574ee160c122a30001f2074ee160c12336d4ef1164c120016014ef1164c1233004ef6164c120016004ef6164c127b054ff6160c122a3000334a4ec9174c120016014ec9174c1233564fce174c120016014fce174c1233674fd8174c120016014fd8174c12334d4edd174c120016014edd174c1233554fe2174c120016014fe2174c1233004ee7174c120016004ee7174c127b054fe7170c122a3000334a4ef6174c120016014ef6174c1233474efb174c120016014efb174c1207000007a26c920000006e6c92050000000000000007a204d63f02cc25000000000000000002cc0000000700000000000000000000000000000000000000334c4ec4004d120016014ec4004d1233774ec9004d120016014ec9004d1233894ece004d120016014ece004d12338a4ed3004d120016014ed3004d1233a54ed8004d120016014ed8004d1233ba4edd004d120016014edd004d1233b84eec004d120016014eec004d1233ba4ef1004d120016014ef1004d1233914ef6004d120016014ef6004d1233714efb004d120016014efb004d1233654fc4014d120016014fc4014d12335c4ec9014d120016014ec9014d1233624ece014d120016014ece014d1233664ed3014d120016014ed3014d1233584ed8014d120016014ed8014d1233474edd014d120016014edd014d1233004ee2014d120016004ee2014d127b004fe2010d1200300033074ef6014d120016014ef6014d1233004efb014d120016014efb014d1233004ed3024d120016014ed3024d1233007aea024d120016017aea024d1233004efb024d120016004efb024d127b004efb020d120030007b0140c0030d1206280033584ed8034d120016014ed8034d12336e4edd034d120016014edd034d12337e4fe2034d120016014fe2034d1233604ee7034d120016014ee7034d1233004eec034d120016004eec034d127b014fec030d1206280033534efb034d120016014efb034d1233004fc4044d120016004fc4044d127b014fc4040d1206280033004ed3044d120016014ed3044d1233005ee7044d120016015ee7044d1233004eec044d120016004eec044d1200000000ec9a", + "335762fb0b4c1200160162fb0b4c12336460c40c4c1200160160c40c4c12336960c90c4c1200160160c90c4c12335663ce0c4c1200160163ce0c4c12334661d30c4c1200160161d30c4c12334960d80c4c1200160160d80c4c12335561e20c4c1200160161e20c4c1233005ee70c4c120016005ee70c4c127b035ee70c0c1217200001006c006c00000061f82c4c12330079dd0d4c1200160179dd0d4c1233005df10d4c120016015df10d4c1233005dc90e4c120016015dc90e4c1233005fd80e4c120016005fd80e4c127b035fd80e0c121720007b0440de0e0c121d240033676dec0e4c120016016dec0e4c1233006ef10e4c120016006ef10e4c127b046ef10e0c121d2400335f4ff60e4c120016014ff60e4c1233564efb0e4c120016014efb0e4c1233524fc40f4c120016014fc40f4c12010068006800290064c42f4c12334b4fce0f4c120016014fce0f4c1233005ed30f4c120016005ed30f4c127b045fd30f0c121d2400333e50f60f4c1200160150f60f4c1233005ffb0f4c120016005ffb0f4c127b045ffb0f0c121d2400333660cb104c1200160160cb104c1233374fce104c120016014fce104c1233004fd3104c120016004fd3104c127b044fd3100c121d2400333a4fd8104c120016014fd8104c1233484fdd104c120016014fdd104c1233004ee2104c120016004ee2104c127b044fe2100c121d2400333c4efb104c120016014efb104c12333a4fc4114c120016014fc4114c1233004ec9114c120016004ec9114c127b044ec9110c121d240033374ed3114c120016014ed3114c12333b4ed8114c120016014ed8114c12333e50dd114c1200160150dd114c1233004fe2114c120016004fe2114c127b044fe2110c121d240033054fe7114c120016014fe7114c12330e4fec114c120016014fec114c1233074ff1114c120016014ff1114c12010020002000160063f2314c1233a24ff6114c120016014ff6114c1233994ffb114c120016014ffb114c12338e4ec4124c120016014ec4124c12337c49d4124c1200160149d4124c1201004a004a002a0069d6324c1233874ed8124c120016014ed8124c12337a50e2124c1200160150e2124c12335050e7124c1200160150e7124c1233384fec124c120016014fec124c1233004ef1124c120016014ef1124c1233004ece134c120016014ece134c1233004ed9134c120016014ed9134c12330060d9134c1200160160d9134c1233004ee7134c120016004ee7134c127b044fe7130c121d240001008c008c0041004eee334c1233ba4ff1134c120016014ff1134c1233b54ec9144c120016014ec9144c12339b4ece144c120016014ece144c1233954ed3144c120016014ed3144c1201006e006e00a9005dd6344c1233ba4fdd144c120016014fdd144c1233894ee2144c12000049f0", + "07000007456b920000006e6b920500000000000000074504d943026c210000000000000000026c000000070000000000000000000000000000000000000033496aec004c120016016aec004c12334a5cf1004c120016015cf1004c12334e5cf6004c120016015cf6004c1233535cfb004c120016015cfb004c1233565cc4014c120016015cc4014c1233555cc9014c120016015cc9014c12334d5dce014c120016015dce014c1233005dd3014c120016005dd3014c127b005dd3010c1200300033005ce7014c120016015ce7014c1233005dfb014c120016015dfb014c1233005cc4024c120016005cc4024c127b005cc4020c120030007b0140c0030c1206280033694fd8034c120016014fd8034c1233614edd034c120016014edd034c12334e4ee2034c120016014ee2034c1233004fe7034c120016004fe7034c127b014fe7030c1206280033004ef1034c120016014ef1034c1233004ef6034c120016004ef6034c127b014ff6030c1206280033004ec4044c120016014ec4044c1233004ed8044c120016014ed8044c1233004fdd044c120016004fdd044c127b014fdd040c1206280033004ee7044c120016014ee7044c1233004ef1044c120016004ef1044c127b014ef1040c1206280033004ec4054c120016014ec4054c1233004ed8054c120016004ed8054c127b014ed8050c12062800010094009400000058c9264c12339b4fec064c120016014fec064c12338d4ff1064c120016014ff1064c12337d4ff6064c120016014ff6064c1233744ffb064c120016014ffb064c1233634ec4074c120016014ec4074c1233524fc9074c120016014fc9074c1233004fce074c120016004fce074c127b024fce070c120e240033574ed8074c120016014ed8074c1233004fdd074c120016004fdd074c127b024fdd070c120e240033494ee2074c120016014ee2074c1233004fe7074c120016004fe7074c127b024fe7070c120e2400330050ce084c1200160150ce084c1233004fd8084c120016004fd8084c127b0250d8080c120e2400337960e7094c1200160160e7094c12337171ec094c1200160171ec094c12336c6ef1094c120016016ef1094c12336f6df6094c120016016df6094c1233656efb094c120016016efb094c12335d5ec40a4c120016015ec40a4c12336e6dc90a4c120016016dc90a4c12336f73ce0a4c1200160173ce0a4c12336761d80a4c1200160161d80a4c12334c5ddd0a4c120016015ddd0a4c1233005ce20a4c120016005ce20a4c127b025de20a0c120e240033005dec0a4c120016015dec0a4c12330062c40b4c1200160162c40b4c1233005dd30b4c120016005dd30b4c127b025dd30b0c120e24007b0340de0b0c1217200033635ff10b4c120016015ff10b4c1233625ff60b4c120016015ff60b4c120000b78f", + "330b4fd2114b120016014fd2114b1233004fd7114b120016014fd7114b12331250e1114b1200160150e1114b12330050e6114b1200160050e6114b127b0450e6110b121d240033374ff5114b120016014ff5114b1233004efa114b120016004efa114b127b044ffa110b121d2400333f4fc8124b120016014fc8124b1233004fcd124b120016004fcd124b127b044fcd120b121d2400010052005200000076cf324b12333b4fd2124b120016014fd2124b12336d49d9124b1200160149d9124b12335e4edc124b120016014edc124b12010038003800500046dd324b12335a4fe1124b120016014fe1124b1233554ee6124b120016014ee6124b1233004feb124b120016014feb124b12190040c2130b1233004fc3134b120016014fc3134b1233004fc8134b120016014fc8134b1233004fcd134b120016014fcd134b121a005bd9130b121a0176d9130b12346776d9130b12330051dd134b1200160151dd134b1233005ce7134b120016005ce7134b127b045de7130b121d240033594ef1134b120016014ef1134b12346468f4130b12210050f5130b12030000004540f6330b12030014001464f7130b12334a5cfb134b120016015cfb134b1233505cc4144b120016015cc4144b1233005cc9144b120016005cc9144b127b045cc9140b121d2400335a5cce144b120016015cce144b1233005dd3144b120016005dd3144b127b045dd3140b121d240033555cd8144b120016015cd8144b1201007c007c00330065de344b1233565de2144b120016015de2144b1233005de7144b120016005de7144b127b045de7140b121d2400330c5cec144b120016015cec144b1233005df1144b120016015df1144b1233015dc4154b120016015dc4154b1233005cc9154b120016015cc9154b1233005cdd154b120016015cdd154b1233005ce2154b120016005ce2154b127b055de2150b122a3000334b54ed154b1200160154ed154b12334d5df1154b120016015df1154b1233005df6154b120016015df6154b1233005cc4164b120016005cc4164b127b055cc4160b122a30001e0176c8160b127b054fe6160b122a30001f204fe6160b1201003c003c00330067e6364b1233765df1164b120016015df1164b12337d5df6164b120016015df6164b12337c61fb164b1200160161fb164b1233735ec4174b120016015ec4174b1233825dc9174b120016015dc9174b12337e5dce174b120016015dce174b12336b5fd3174b120016015fd3174b1233555fd8174b120016015fd8174b1233655ddd174b120016015ddd174b12336d5de2174b120016015de2174b1233585fe7174b120016015fe7174b1233505dec174b120016015dec174b1233005df1174b120016005df1174b127b055df1170b122a30007b0040c0000c120030000000000000000000004251", + "337364c2084b1200160164c2084b1233535fc7084b120016015fc7084b1233005ecc084b120016005ecc084b127b025ecc080b120e240033525ec2094b120016015ec2094b12336a5ec7094b120016015ec7094b1233a74fcc094b120016014fcc094b1233ba4fd1094b120016014fd1094b12010078007800140068d4294b1233004fdb094b120016014fdb094b1233004fef094b120016014fef094b12330050c70a4b1200160150c70a4b12330060db0a4b1200160160db0a4b1233004fef0a4b120016014fef0a4b12330060c70b4b1200160160c70b4b12330062d60b4b1200160062d60b4b127b0262d60b0b120e24007b0340de0b0b12172000334a5fe00b4b120016015fe00b4b12335a5fea0b4b120016015fea0b4b1233004fef0b4b120016004fef0b4b127b034fef0b0b1217200033525df90b4b120016015df90b4b12335b5dc20c4b120016015dc20c4b12335d5fc70c4b120016015fc70c4b1233614fcc0c4b120016014fcc0c4b1233974fd10c4b120016014fd10c4b1201002600260015005bd32c4b1233b760d60c4b1200160160d60c4b12339562db0c4b1200160162db0c4b1233704fe00c4b120016014fe00c4b12334c4fe50c4b120016014fe50c4b1233004fea0c4b120016004fea0c4b127b034fea0c0b12172000334a4fef0c4b120016014fef0c4b1233004ff40c4b120016004ff40c4b127b034ff40c0b12172000335d50f90d4b1200160150f90d4b1233855dc20e4b120016015dc20e4b12339f62c70e4b1200160162c70e4b1233944fcc0e4b120016014fcc0e4b12338e4ed10e4b120016014ed10e4b1233944fd60e4b120016014fd60e4b1234c876d90e0b1233974fdc0e4b120016014fdc0e4b1233884fe10e4b120016014fe10e4b12335950e60e4b1200160150e60e4b12334b4feb0e4b120016014feb0e4b1233004ff00e4b120016004ff00e4b127b044ff00e0b121d240033004fc80f4b120016014fc80f4b1233004fdc0f4b120016004fdc0f4b127b044fdc0f0b121d240033434fe60f4b120016014fe60f4b12334f4feb0f4b120016014feb0f4b12335c4ff00f4b120016014ff00f4b1233004ff50f4b120016004ff50f4b127b044ff50f0b121d240033494fc8104b120016014fc8104b12334e4fcd104b120016014fcd104b1233704ed2104b120016014ed2104b12337d4fd7104b120016014fd7104b1233794fdc104b120016014fdc104b1233614fe1104b120016014fe1104b12335f4fe6104b120016014fe6104b12335d4feb104b120016014feb104b1233614ef0104b120016014ef0104b1233524ff5104b120016014ff5104b1233474efa104b120016014efa104b1233004fc3114b120016004fc3114b127b044fc3110b121d2400330e4fcd114b120016014fcd114b120000000029b4", + "33004eef174a120016004eef174a127b054eef170a122a3000335b4ef9174a120016014ef9174a12070000084c6a920000006e6a920500000000000000084c055a4102f223000000000000000002f2000000090000000000000000000000000000000000000033524fc2004b120016014fc2004b1233584ec7004b120016014ec7004b1233004ecc004b120016004ecc004b127b004ecc000b12003000335a4ed6004b120016014ed6004b12337e4edb004b120016014edb004b1233606ff5004b120016016ff5004b1233004ef9004b120016004ef9004b127b004ef9000b1200300033004ace014b120016014ace014b1233634ed6014b120016014ed6014b1233004edb014b120016004edb014b127b004fdb010b1200300033004ee0014b120016014ee0014b1233004ef4014b120016014ef4014b1233004ec2024b120016004ec2024b127b004ec2020b1200300033624ed6024b120016014ed6024b1233824edb024b120016014edb024b1233874ee0024b120016014ee0024b127b014ec2030b1206280033045cd1034b120016015cd1034b1233005cd6034b120016015cd6034b1233005ce5034b120016005ce5034b127b015ce5030b1206280033005cef034b120016015cef034b1233015cc7044b120016015cc7044b1233005ccc044b120016005ccc044b127b015dcc040b12062800334c5cd1044b120016015cd1044b1233695cd6044b120016015cd6044b1233955cdb044b120016015cdb044b12339b5ce0044b120016015ce0044b12337c5ce5044b120016015ce5044b1233585cea044b120016015cea044b12334e5cef044b120016015cef044b12334e5eef044b120016015eef044b1233005cf4044b120016005cf4044b127b015cf4040b1206280033005cd1054b120016015cd1054b1233065bd9054b120016015bd9054b1233005cdb054b120016005cdb054b127b015ddb050b1206280033005ce0054b120016015ce0054b1233006be5054b120016016be5054b1233005cf9054b120016015cf9054b1233545cc7064b120016015cc7064b12335b5dcc064b120016015dcc064b1201008c008c00000043d1264b1233ba5dd6064b120016015dd6064b12640053df060b1217005bdf060b12180040df090b1217005fe2094b12180078e2064b12337a65e3064b1200160165e3064b12337a79e3064b1200160179e3064b1233005fe5064b120016005fe5064b127b015fe5060b12062800330061f4064b1200160161f4064b1233005ec7074b120016005ec7074b127b025ec7070b120e2400334a5dcc074b120016015dcc074b1233495dd1074b120016015dd1074b1233005dd6074b120016005dd6074b127b025dd6070b120e240033475df4074b120016015df4074b12336060f9074b1200160160f9074b120000ada4", + "08066ed8124a120030000628000e24001720001d24002830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009066ed8124a120030000628000e24001720001d24002a3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b046ed8124a121d240033004fe0124a120016014fe0124a1233004fe5124a120016004fe5124a127b044fe5120a121d2400010058005800130076e6324a12339e4ff4124a120016014ff4124a12338c4ff9124a120016014ff9124a1233794fc2134a120016014fc2134a1233604fc7134a120016014fc7134a12334c4ecc134a120016014ecc134a1233004fd1134a120016004fd1134a127b044fd1130a121d24000100740074004d0056d5334a1233a04fdb134a120016014fdb134a1233a350e0134a1200160150e0134a1233a14de8134a120016014de8134a1233994fea134a120016014fea134a1233684fef134a120016014fef134a12336950f4134a1200160150f4134a1233004ec0144a120016014ec0144a1233004fc7144a120016004fc7144a127b044fc7140a121d240033544fe0144a120016014fe0144a12335f4fe5144a120016014fe5144a12334f4fea144a120016014fea144a1233484fef144a120016014fef144a1233004ff4144a120016004ff4144a127b044ff4140a121d24007b0540c0150a122a3000331b4fc7154a120016014fc7154a1233004fcc154a120016004fcc154a127b054fcc150a122a30001e0177df150a127b054ec1160a122a30001f204ec1160a1233004fc2164a120016014fc2164a1233004ecc164a120016004ecc164a127b054ecc160a122a3000336d4ed1164a120016014ed1164a1201003c003c001b0072d3364a12331d4fd6164a120016014fd6164a12334f4fdb164a120016014fdb164a120100200020004d0063df364a1233424ee5164a120016014ee5164a12335d4bed164a120016014bed164a1233154dc5174a120016014dc5174a1233115dc7174a120016015dc7174a1233104fcc174a120016014fcc174a12330a4ed1174a120016014ed1174a1233144ed6174a120016014ed6174a12330d5adf174a120016015adf174a1233154ee5174a120016014ee5174a120000000000000018a8", + "33ba4fea0c4a120016014fea0c4a1233ba4fc20d4a120016014fc20d4a12010040004000000069c62d4a1233004fcc0d4a120016014fcc0d4a1233004fd10d4a120016004fd10d4a127b034fd10d0a1217200033004fd60d4a120016014fd60d4a1233004fea0d4a120016014fea0d4a1233004ec20e4a120016014ec20e4a1233004ed60e4a120016014ed60e4a1233004fea0e4a120016014fea0e4a1233004fef0e4a120016004fef0e4a127b044fef0e0a121d2800339d4ff40e4a120016014ff40e4a12339f4ff90e4a120016014ff90e4a1233a84fc20f4a120016014fc20f4a1233844fc70f4a120016014fc70f4a12336d4fcc0f4a120016014fcc0f4a1233754fd10f4a120016014fd10f4a12010066006600170061d12f4a120100420042007c006ad32f4a12335f4fd60f4a120016014fd60f4a1233004edb0f4a120016004edb0f4a127b044fdb0f0a121d2800333b4fe50f4a120016014fe50f4a1233004eea0f4a120016004eea0f4a127b044fea0f0a121d2800334a4ec7104a120016014ec7104a1233454fcc104a120016014fcc104a12334b4fd1104a120016014fd1104a1233414dd9104a120016014dd9104a12333d4fdb104a120016014fdb104a1233004ee0104a120016004ee0104a127b044fe0100a121d2800333c4ee5104a120016014ee5104a12333a4fea104a120016014fea104a1233414fef104a120016014fef104a1233454ef4104a120016014ef4104a12333f4ff9104a120016014ff9104a1233004ec2114a120016004ec2114a127b044ec2110a121d2800333c4fcc114a120016014fcc114a1233004fd1114a120016004fd1114a127b044fd1110a121d280033164fdb114a120016014fdb114a1233004fe0114a120016014fe0114a1233004fef114a120016004fef114a127b044fef110a121d280033004ff4114a120016014ff4114a1233004ecc124a120016014ecc124a12080661d8124a120030000628000e28001720001d280028300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090661d8124a120030000628000e24001720001d2400283000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b0461d8124a121d240000000000eeca", + + ].compactMap({ + return Data(hexadecimalString: $0) + }).map({ + return try! HistoryPage(pageData: $0, pumpModel: model) + }) + + // Assert that all events are in chronological order, even though there is a +3 and -3 hour time change in pages[7] + var nextDate = Date.distantFuture + + for page in pages { + let (timestampedEvents, _, cancelledEarly) = page.timestampedEvents(after: .distantPast, timeZone: TimeZone(secondsFromGMT: 0)!, model: model) + + XCTAssertFalse(cancelledEarly) + + for event in timestampedEvents.reversed() { + XCTAssertLessThanOrEqual(event.date, nextDate) + nextDate = event.date + } + } + } } diff --git a/MinimedKitTests/PumpOpsSynchronousBuildFromFramesTests.swift b/MinimedKitTests/PumpOpsSynchronousBuildFromFramesTests.swift index 5f94a948f..ad2f32b3e 100644 --- a/MinimedKitTests/PumpOpsSynchronousBuildFromFramesTests.swift +++ b/MinimedKitTests/PumpOpsSynchronousBuildFromFramesTests.swift @@ -84,7 +84,7 @@ class PumpOpsSynchronousBuildFromFramesTests: XCTestCase { do { let (historyEvents, _) = try sut.getHistoryEvents(since: date) - XCTAssertEqual(historyEvents.count, 332) + XCTAssertEqual(historyEvents.count, 334) } catch { XCTFail() } diff --git a/RileyLinkBLEKit/PeripheralManagerError.swift b/RileyLinkBLEKit/PeripheralManagerError.swift index 0c25505c7..0481d354f 100644 --- a/RileyLinkBLEKit/PeripheralManagerError.swift +++ b/RileyLinkBLEKit/PeripheralManagerError.swift @@ -35,7 +35,7 @@ extension PeripheralManagerError: LocalizedError { case .cbPeripheralError(let error as NSError): return error.localizedFailureReason default: - return errorDescription + return nil } } } diff --git a/RileyLinkKit/PumpOpsSession.swift b/RileyLinkKit/PumpOpsSession.swift index 2d90214b5..05f0eb8bb 100644 --- a/RileyLinkKit/PumpOpsSession.swift +++ b/RileyLinkKit/PumpOpsSession.swift @@ -7,6 +7,7 @@ // import Foundation +import LoopKit import RileyLinkBLEKit @@ -857,6 +858,7 @@ extension PumpOpsSession { /// - PumpOpsError.deviceError /// - PumpOpsError.noResponse /// - PumpOpsError.rfCommsFailure + /// - LocalizedError private func scanForPump(in frequencies: [Measurement], current: Measurement?) throws -> FrequencyScanResults { var trials = [FrequencyTrial]() From e45ad0d9abd2282846244d7ea0e5274be36999a2 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 25 Jul 2018 23:49:42 -0500 Subject: [PATCH 07/22] Handle slower pump response to set profile command, and speedup tune (#421) --- MinimedKit/PumpManager/PumpMessageSender.swift | 2 +- RileyLinkKit/PumpOpsSession.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MinimedKit/PumpManager/PumpMessageSender.swift b/MinimedKit/PumpManager/PumpMessageSender.swift index 017f33edc..1cb6dbbea 100644 --- a/MinimedKit/PumpManager/PumpMessageSender.swift +++ b/MinimedKit/PumpManager/PumpMessageSender.swift @@ -10,7 +10,7 @@ import Foundation import RileyLinkBLEKit import os.log -private let standardPumpResponseWindow: TimeInterval = .milliseconds(180) +private let standardPumpResponseWindow: TimeInterval = .milliseconds(200) private let log = OSLog(category: "PumpMessageSender") diff --git a/RileyLinkKit/PumpOpsSession.swift b/RileyLinkKit/PumpOpsSession.swift index 05f0eb8bb..522398ac8 100644 --- a/RileyLinkKit/PumpOpsSession.swift +++ b/RileyLinkKit/PumpOpsSession.swift @@ -881,7 +881,7 @@ extension PumpOpsSession { var sumRSSI = 0 for _ in 1...tries { // Ignore failures here - let rfPacket = try? session.sendAndListenForPacket(PumpMessage(settings: settings, type: .getPumpModel)) + let rfPacket = try? session.sendAndListenForPacket(PumpMessage(settings: settings, type: .getPumpModel), timeout: .milliseconds(130)) if let rfPacket = rfPacket, let pkt = MinimedPacket(encodedData: rfPacket.data), let response = PumpMessage(rxData: pkt.data), response.messageType == .getPumpModel From cb290d3dc3d532b1965c91a559b1dc6c29866251 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Thu, 26 Jul 2018 00:10:35 -0500 Subject: [PATCH 08/22] Better error handling (#422) Fixes a backwards logic check when tracking last history read. This is a low-impact bug; the result is that users with Pump Event as their history source were doing an additional history fetch after every temp basal. Also adds a separate error (and resolves a long-standing TODO) for packet decoding failures. --- .../PumpManager/MinimedPumpManager.swift | 7 +++--- .../PumpManager/MinimedPumpManagerError.swift | 22 ++++++++++++------- .../PumpManager/PumpMessageSender.swift | 5 +++-- MinimedKit/PumpManager/PumpOpsError.swift | 21 +++++++++++------- RileyLinkBLEKit/PeripheralManagerError.swift | 13 +++++++++++ RileyLinkBLEKit/RileyLinkDeviceError.swift | 9 ++++++++ RileyLinkKit/PumpOpsSession.swift | 17 ++++++++++++-- RileyLinkKit/es.lproj/Localizable.strings | 4 ++-- RileyLinkKit/ru.lproj/Localizable.strings | 4 ++-- 9 files changed, 74 insertions(+), 28 deletions(-) diff --git a/MinimedKit/PumpManager/MinimedPumpManager.swift b/MinimedKit/PumpManager/MinimedPumpManager.swift index c5287e8b0..d6d158115 100644 --- a/MinimedKit/PumpManager/MinimedPumpManager.swift +++ b/MinimedKit/PumpManager/MinimedPumpManager.swift @@ -350,14 +350,13 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { self.pumpOps.runSession(withName: "Fetch Pump History", using: device) { (session) in do { guard let startDate = self.pumpManagerDelegate?.startDateToFilterNewPumpEvents(for: self) else { - assertionFailure("pumpManagerDelegate cannot be nil") - throw PumpManagerError.configuration(MinimedPumpManagerError.noDelegate) + preconditionFailure("pumpManagerDelegate cannot be nil") } let (events, model) = try session.getHistoryEvents(since: startDate) self.pumpManagerDelegate?.pumpManager(self, didReadPumpEvents: events.pumpEvents(from: model), completion: { (error) in - if error != nil { + if error == nil { self.lastAddedPumpEvents = Date() } @@ -420,7 +419,7 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { let status = try session.getCurrentPumpStatus() guard var date = status.clock.date else { assertionFailure("Could not interpret a valid date from \(status.clock) in the system calendar") - return + throw PumpManagerError.configuration(MinimedPumpManagerError.noDate) } // Check if the clock should be reset diff --git a/MinimedKit/PumpManager/MinimedPumpManagerError.swift b/MinimedKit/PumpManager/MinimedPumpManagerError.swift index 970bd178b..e6cebd923 100644 --- a/MinimedKit/PumpManager/MinimedPumpManagerError.swift +++ b/MinimedKit/PumpManager/MinimedPumpManagerError.swift @@ -9,8 +9,7 @@ import Foundation public enum MinimedPumpManagerError: Error { case noRileyLink - case noDate - case noDelegate + case noDate // TODO: This is less of an error and more of a precondition/assertion state case tuneFailed(LocalizedError) } @@ -22,10 +21,19 @@ extension MinimedPumpManagerError: LocalizedError { return nil case .noDate: return nil - case .noDelegate: + case .tuneFailed(let error): + return [NSLocalizedString("RileyLink radio tune failed", comment: "Error description"), error.errorDescription].compactMap({ $0 }).joined(separator: ": ") + } + } + + public var failureReason: String? { + switch self { + case .noRileyLink: + return nil + case .noDate: return nil case .tuneFailed(let error): - return [NSLocalizedString("RileyLink radio tune failed", comment: "Error description"), error.errorDescription].compactMap({ $0 }).joined(separator: ". ") + return error.failureReason } } @@ -35,10 +43,8 @@ extension MinimedPumpManagerError: LocalizedError { return NSLocalizedString("Make sure your RileyLink is nearby and powered on", comment: "Recovery suggestion") case .noDate: return nil - case .noDelegate: - return nil - case .tuneFailed(_): - return nil + case .tuneFailed(let error): + return error.recoverySuggestion } } } diff --git a/MinimedKit/PumpManager/PumpMessageSender.swift b/MinimedKit/PumpManager/PumpMessageSender.swift index 1cb6dbbea..8de0f5b6b 100644 --- a/MinimedKit/PumpManager/PumpMessageSender.swift +++ b/MinimedKit/PumpManager/PumpMessageSender.swift @@ -69,6 +69,7 @@ extension PumpMessageSender { /// - retryCount: The number of times to repeat the send & listen sequence /// - Returns: The expected response message body /// - Throws: + /// - PumpOpsError.couldNotDecode /// - PumpOpsError.crosstalk /// - PumpOpsError.deviceError /// - PumpOpsError.noResponse @@ -104,6 +105,7 @@ extension PumpMessageSender { /// - retryCount: The number of times to repeat the send & listen sequence /// - Returns: The message reply /// - Throws: An error describing a failure in the sending or receiving of a message: + /// - PumpOpsError.couldNotDecode /// - PumpOpsError.crosstalk /// - PumpOpsError.deviceError /// - PumpOpsError.noResponse @@ -112,8 +114,7 @@ extension PumpMessageSender { let rfPacket = try sendAndListenForPacket(message, repeatCount: repeatCount, timeout: timeout, retryCount: retryCount) guard let packet = MinimedPacket(encodedData: rfPacket.data) else { - // TODO: Change error to better reflect that this is an encoding or CRC error - throw PumpOpsError.unknownResponse(rx: rfPacket.data, during: message) + throw PumpOpsError.couldNotDecode(rx: rfPacket.data, during: message) } guard let response = PumpMessage(rxData: packet.data) else { diff --git a/MinimedKit/PumpManager/PumpOpsError.swift b/MinimedKit/PumpManager/PumpOpsError.swift index 1852a23d6..459323850 100644 --- a/MinimedKit/PumpManager/PumpOpsError.swift +++ b/MinimedKit/PumpManager/PumpOpsError.swift @@ -21,6 +21,7 @@ public enum PumpCommandError: Error { public enum PumpOpsError: Error { case bolusInProgress + case couldNotDecode(rx: Data, during: CustomStringConvertible) case crosstalk(PumpMessage, during: CustomStringConvertible) case deviceError(LocalizedError) case noResponse(during: CustomStringConvertible) @@ -38,6 +39,8 @@ extension PumpOpsError: LocalizedError { switch self { case .bolusInProgress: return nil + case .couldNotDecode: + return NSLocalizedString("Decoding Error", comment: "Error description") case .crosstalk: return nil case .deviceError: @@ -64,27 +67,29 @@ extension PumpOpsError: LocalizedError { public var failureReason: String? { switch self { case .bolusInProgress: - return NSLocalizedString("A bolus is already in progress.", comment: "Communications error for a bolus currently running") + return NSLocalizedString("A bolus is already in progress", comment: "Communications error for a bolus currently running") + case .couldNotDecode(rx: let data, during: let during): + return String(format: NSLocalizedString("Invalid response during %1$@: %2$@", comment: "Format string for failure reason. (1: The operation being performed) (2: The response data)"), String(describing: during), data.hexadecimalString) case .crosstalk: - return NSLocalizedString("Comms with another pump detected.", comment: "") + return NSLocalizedString("Comms with another pump detected", comment: "") case .noResponse: - return NSLocalizedString("Pump did not respond.", comment: "") + return NSLocalizedString("Pump did not respond", comment: "") case .pumpSuspended: - return NSLocalizedString("Pump is suspended.", comment: "") + return NSLocalizedString("Pump is suspended", comment: "") case .rfCommsFailure(let msg): return msg case .unexpectedResponse: - return NSLocalizedString("Pump responded unexpectedly.", comment: "") + return NSLocalizedString("Pump responded unexpectedly", comment: "") case .unknownPumpErrorCode(let code): - return String(format: NSLocalizedString("Unknown pump error code: %1$@.", comment: "The format string description of an unknown pump error code. (1: The specific error code raw value)"), String(describing: code)) + return String(format: NSLocalizedString("Unknown pump error code: %1$@", comment: "The format string description of an unknown pump error code. (1: The specific error code raw value)"), String(describing: code)) case .unknownPumpModel(let model): - return String(format: NSLocalizedString("Unknown pump model: %@.", comment: ""), model) + return String(format: NSLocalizedString("Unknown pump model: %@", comment: ""), model) case .unknownResponse(rx: let data, during: let during): return String(format: NSLocalizedString("Unknown response during %1$@: %2$@", comment: "Format string for an unknown response. (1: The operation being performed) (2: The response data)"), String(describing: during), data.hexadecimalString) case .pumpError(let errorCode): return String(describing: errorCode) case .deviceError(let error): - return [error.errorDescription, error.failureReason].compactMap({ $0 }).joined(separator: ". ") + return [error.errorDescription, error.failureReason].compactMap({ $0 }).joined(separator: ": ") } } diff --git a/RileyLinkBLEKit/PeripheralManagerError.swift b/RileyLinkBLEKit/PeripheralManagerError.swift index 0481d354f..f6f1f0670 100644 --- a/RileyLinkBLEKit/PeripheralManagerError.swift +++ b/RileyLinkBLEKit/PeripheralManagerError.swift @@ -34,6 +34,19 @@ extension PeripheralManagerError: LocalizedError { switch self { case .cbPeripheralError(let error as NSError): return error.localizedFailureReason + case .unknownCharacteristic: + return NSLocalizedString("The RileyLink was temporarily disconnected", comment: "Failure reason: unknown peripheral characteristic") + default: + return nil + } + } + + var recoverySuggestion: String? { + switch self { + case .cbPeripheralError(let error as NSError): + return error.localizedRecoverySuggestion + case .unknownCharacteristic: + return NSLocalizedString("Make sure the device is nearby, and the issue should resolve automatically", comment: "Recovery suggestion for unknown peripheral characteristic") default: return nil } diff --git a/RileyLinkBLEKit/RileyLinkDeviceError.swift b/RileyLinkBLEKit/RileyLinkDeviceError.swift index b88aad5cc..8cee2d75c 100644 --- a/RileyLinkBLEKit/RileyLinkDeviceError.swift +++ b/RileyLinkBLEKit/RileyLinkDeviceError.swift @@ -42,4 +42,13 @@ extension RileyLinkDeviceError: LocalizedError { return nil } } + + var recoverySuggestion: String? { + switch self { + case .peripheralManagerError(let error): + return error.recoverySuggestion + default: + return nil + } + } } diff --git a/RileyLinkKit/PumpOpsSession.swift b/RileyLinkKit/PumpOpsSession.swift index 522398ac8..6df0e151b 100644 --- a/RileyLinkKit/PumpOpsSession.swift +++ b/RileyLinkKit/PumpOpsSession.swift @@ -47,6 +47,7 @@ extension PumpOpsSession { /// /// - Throws: /// - PumpCommandError.command containing: + /// - PumpOpsError.couldNotDecode /// - PumpOpsError.crosstalk /// - PumpOpsError.deviceError /// - PumpOpsError.noResponse @@ -90,6 +91,7 @@ extension PumpOpsSession { /// - Throws: /// - PumpCommandError.command /// - PumpCommandError.arguments + /// - PumpOpsError.couldNotDecode /// - PumpOpsError.crosstalk /// - PumpOpsError.deviceError /// - PumpOpsError.noResponse @@ -138,6 +140,7 @@ extension PumpOpsSession { /// - Throws: /// - PumpCommandError.command /// - PumpCommandError.arguments + /// - PumpOpsError.couldNotDecode /// - PumpOpsError.crosstalk /// - PumpOpsError.deviceError /// - PumpOpsError.noResponse @@ -163,6 +166,7 @@ extension PumpOpsSession { /// - Throws: /// - PumpCommandError.command /// - PumpCommandError.arguments + /// - PumpOpsError.couldNotDecode /// - PumpOpsError.crosstalk /// - PumpOpsError.deviceError /// - PumpOpsError.noResponse @@ -176,6 +180,7 @@ extension PumpOpsSession { /// - Throws: /// - PumpCommandError.command /// - PumpCommandError.arguments + /// - PumpOpsError.couldNotDecode /// - PumpOpsError.crosstalk /// - PumpOpsError.deviceError /// - PumpOpsError.noResponse @@ -189,6 +194,7 @@ extension PumpOpsSession { /// - Throws: /// - PumpCommandError.command /// - PumpCommandError.arguments + /// - PumpOpsError.couldNotDecode /// - PumpOpsError.crosstalk /// - PumpOpsError.deviceError /// - PumpOpsError.noResponse @@ -205,6 +211,7 @@ extension PumpOpsSession { /// - Throws: /// - PumpCommandError.command /// - PumpCommandError.arguments + /// - PumpOpsError.couldNotDecode /// - PumpOpsError.crosstalk /// - PumpOpsError.deviceError /// - PumpOpsError.noResponse @@ -224,6 +231,7 @@ extension PumpOpsSession { /// - Throws: /// - PumpCommandError.command /// - PumpCommandError.arguments + /// - PumpOpsError.couldNotDecode /// - PumpOpsError.crosstalk /// - PumpOpsError.deviceError /// - PumpOpsError.noResponse @@ -247,6 +255,7 @@ extension PumpOpsSession { } /// - Throws: + /// - PumpOpsError.couldNotDecode /// - PumpOpsError.crosstalk /// - PumpOpsError.deviceError /// - PumpOpsError.noResponse @@ -259,6 +268,7 @@ extension PumpOpsSession { } /// - Throws: + /// - PumpOpsError.couldNotDecode /// - PumpOpsError.crosstalk /// - PumpOpsError.deviceError /// - PumpOpsError.noResponse @@ -272,6 +282,7 @@ extension PumpOpsSession { } /// - Throws: + /// - PumpOpsError.couldNotDecode /// - PumpOpsError.crosstalk /// - PumpOpsError.deviceError /// - PumpOpsError.noResponse @@ -308,6 +319,7 @@ extension PumpOpsSession { /// - Throws: /// - PumpCommandError.command /// - PumpCommandError.arguments + /// - PumpOpsError.couldNotDecode /// - PumpOpsError.crosstalk /// - PumpOpsError.deviceError /// - PumpOpsError.noResponse @@ -692,6 +704,7 @@ extension PumpOpsSession { /// /// - Parameter watchdogID: A 3-byte address for the watchdog device. /// - Throws: + /// - PumpOpsError.couldNotDecode /// - PumpOpsError.crosstalk /// - PumpOpsError.deviceError /// - PumpOpsError.noResponse @@ -715,8 +728,7 @@ extension PumpOpsSession { } guard let packet = MinimedPacket(encodedData: encodedData) else { - // TODO: Change error to better reflect that this is an encoding or CRC error - throw PumpOpsError.unknownResponse(rx: encodedData, during: "Watchdog listening") + throw PumpOpsError.couldNotDecode(rx: encodedData, during: "Watchdog listening") } guard let findMessage = PumpMessage(rxData: packet.data) else { @@ -932,6 +944,7 @@ extension PumpOpsSession { /// - Throws: /// - PumpCommandError.command /// - PumpCommandError.arguments + /// - PumpOpsError.couldNotDecode /// - PumpOpsError.crosstalk /// - PumpOpsError.deviceError /// - PumpOpsError.noResponse diff --git a/RileyLinkKit/es.lproj/Localizable.strings b/RileyLinkKit/es.lproj/Localizable.strings index 1381fce96..fd9cfbc60 100644 --- a/RileyLinkKit/es.lproj/Localizable.strings +++ b/RileyLinkKit/es.lproj/Localizable.strings @@ -17,7 +17,7 @@ "%1$@%2$@%3$@" = "%1$@%2$@%3$@"; /* Communications error for a bolus currently running */ -"A bolus is already in progress." = "Un bolo ya está en progreso..."; +"A bolus is already in progress" = "Un bolo ya está en progreso"; /* The title of the cell describing an awake radio */ "Awake Until" = "Despierto hasta"; @@ -89,7 +89,7 @@ "Get Pump Model" = "Obtener Modelo de Microinfusadora"; /* Recovery instruction for a certain bolus failure */ -"It is safe to retry." = "Es seguro intentarlo de nuevo."; +"It is safe to retry" = "Es seguro intentarlo de nuevo."; /* The title of the cell describing an awake radio */ "Last Awake" = "último despierto"; diff --git a/RileyLinkKit/ru.lproj/Localizable.strings b/RileyLinkKit/ru.lproj/Localizable.strings index 22067c302..2657d99e2 100644 --- a/RileyLinkKit/ru.lproj/Localizable.strings +++ b/RileyLinkKit/ru.lproj/Localizable.strings @@ -17,7 +17,7 @@ "%1$@%2$@%3$@" = "%1$@%2$@%3$@"; /* Communications error for a bolus currently running */ -"A bolus is already in progress." = "Болюс уже подается"; +"A bolus is already in progress" = "Болюс уже подается"; /* The title of the cell describing an awake radio */ "Awake Until" = "Рабочее состояние до"; @@ -89,7 +89,7 @@ "Get Pump Model" = "Получить модель помпы"; /* Recovery instruction for a certain bolus failure */ -"It is safe to retry." = "Можно повторить без опасений"; +"It is safe to retry" = "Можно повторить без опасений"; /* The title of the cell describing an awake radio */ "Last Awake" = "Недавнее состояние активности"; From b257e5771428caf4b0ec0b9761c2ef7df2681fde Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Tue, 31 Jul 2018 17:38:11 -0500 Subject: [PATCH 09/22] Build MinimedKit and RileyLinkKit for watchOS (#423) --- Cartfile.resolved | 2 +- .../PumpManager/MinimedPumpManager.swift | 2 ++ RileyLink.xcodeproj/project.pbxproj | 24 +++++++++++++++---- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/Cartfile.resolved b/Cartfile.resolved index 4bc265a80..fb79a039d 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1 +1 @@ -github "LoopKit/LoopKit" "7082c64333113ad83238e483e83029c161ac35bb" +github "LoopKit/LoopKit" "16fc21d01a7bf0758c6c81dbb25a5168588c9e30" diff --git a/MinimedKit/PumpManager/MinimedPumpManager.swift b/MinimedKit/PumpManager/MinimedPumpManager.swift index d6d158115..af10569b9 100644 --- a/MinimedKit/PumpManager/MinimedPumpManager.swift +++ b/MinimedKit/PumpManager/MinimedPumpManager.swift @@ -122,6 +122,8 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { return state.timeZone } + public static let localizedTitle = NSLocalizedString("Minimed 500/700 Series", comment: "Generic title of the minimed pump manager") + public var localizedTitle: String { return String(format: NSLocalizedString("Minimed %@", comment: "Pump title (1: model number)"), state.pumpModel.rawValue) } diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 8ed9ea739..dd9539bbb 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -3375,7 +3375,7 @@ ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/iOS", + "$(PROJECT_DIR)/Carthage/Build/$(CARTHAGE_PLATFORM_PATH_$(PLATFORM_NAME))", ); GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = RileyLinkKit/Info.plist; @@ -3385,7 +3385,9 @@ PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.RileyLinkKit; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos watchos watchsimulator"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2,4"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; @@ -3410,7 +3412,7 @@ ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/iOS", + "$(PROJECT_DIR)/Carthage/Build/$(CARTHAGE_PLATFORM_PATH_$(PLATFORM_NAME))", ); GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = RileyLinkKit/Info.plist; @@ -3420,6 +3422,8 @@ PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.RileyLinkKit; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos watchos watchsimulator"; + TARGETED_DEVICE_FAMILY = "1,2,4"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; @@ -3635,7 +3639,7 @@ ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/iOS", + "$(PROJECT_DIR)/Carthage/Build/$(CARTHAGE_PLATFORM_PATH_$(PLATFORM_NAME))", ); GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = MinimedKit/Info.plist; @@ -3645,7 +3649,9 @@ PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.MinimedKit; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos watchos watchsimulator"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2,4"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; @@ -3669,7 +3675,7 @@ ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/iOS", + "$(PROJECT_DIR)/Carthage/Build/$(CARTHAGE_PLATFORM_PATH_$(PLATFORM_NAME))", ); GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = MinimedKit/Info.plist; @@ -3679,6 +3685,8 @@ PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.MinimedKit; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos watchos watchsimulator"; + TARGETED_DEVICE_FAMILY = "1,2,4"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; @@ -3736,6 +3744,10 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CARTHAGE_PLATFORM_PATH_iphoneos = iOS; + CARTHAGE_PLATFORM_PATH_iphonesimulator = iOS; + CARTHAGE_PLATFORM_PATH_watchos = watchOS; + CARTHAGE_PLATFORM_PATH_watchsimulator = watchOS; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; @@ -3795,6 +3807,10 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CARTHAGE_PLATFORM_PATH_iphoneos = iOS; + CARTHAGE_PLATFORM_PATH_iphonesimulator = iOS; + CARTHAGE_PLATFORM_PATH_watchos = watchOS; + CARTHAGE_PLATFORM_PATH_watchsimulator = watchOS; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; From 143da3be985a98e602b15761f0cb0a092eaa9300 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 1 Aug 2018 16:24:55 -0500 Subject: [PATCH 10/22] Deployment target can be specified by dependant project (#424) --- RileyLink.xcodeproj/project.pbxproj | 2 -- 1 file changed, 2 deletions(-) diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index dd9539bbb..957abf44d 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -3799,7 +3799,6 @@ TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; WARNING_CFLAGS = "-Wall"; - WATCHOS_DEPLOYMENT_TARGET = 4.0; }; name = Debug; }; @@ -3856,7 +3855,6 @@ VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; WARNING_CFLAGS = "-Wall"; - WATCHOS_DEPLOYMENT_TARGET = 4.0; }; name = Release; }; From a2baf1fb69919cf996f9002f845b29b54d8defce Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sat, 11 Aug 2018 12:03:22 -0500 Subject: [PATCH 11/22] Update for Swift 4.2 compatibility (#425) --- RileyLinkBLEKit/RileyLinkDeviceManager.swift | 2 +- RileyLinkKit/RileyLinkPumpManager.swift | 4 ++-- RileyLinkKitUI/RileyLinkSettingsViewController.swift | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/RileyLinkBLEKit/RileyLinkDeviceManager.swift b/RileyLinkBLEKit/RileyLinkDeviceManager.swift index 153eab681..0480dc25f 100644 --- a/RileyLinkBLEKit/RileyLinkDeviceManager.swift +++ b/RileyLinkBLEKit/RileyLinkDeviceManager.swift @@ -290,7 +290,7 @@ extension RileyLinkDeviceManager { public override var debugDescription: String { var report = [ "## RileyLinkDeviceManager", - "central: \(central)", + "central: \(central!)", "autoConnectIDs: \(autoConnectIDs)", "timerTickEnabled: \(timerTickEnabled)", "idleListeningState: \(idleListeningState)" diff --git a/RileyLinkKit/RileyLinkPumpManager.swift b/RileyLinkKit/RileyLinkPumpManager.swift index 2ba354c46..7a45352b0 100644 --- a/RileyLinkKit/RileyLinkPumpManager.swift +++ b/RileyLinkKit/RileyLinkPumpManager.swift @@ -21,7 +21,7 @@ open class RileyLinkPumpManager { } /// Manages all the RileyLinks - open let rileyLinkManager: RileyLinkDeviceManager + public let rileyLinkManager: RileyLinkDeviceManager open var rileyLinkPumpManagerState: RileyLinkPumpManagerState { get { @@ -34,7 +34,7 @@ open class RileyLinkPumpManager { private let lockedRileyLinkPumpManagerState: Locked // TODO: Eveluate if this is necessary - open let queue = DispatchQueue(label: "com.loopkit.RileyLinkPumpManager", qos: .utility) + public let queue = DispatchQueue(label: "com.loopkit.RileyLinkPumpManager", qos: .utility) /// Isolated to queue // TODO: Put this on each RileyLinkDevice? diff --git a/RileyLinkKitUI/RileyLinkSettingsViewController.swift b/RileyLinkKitUI/RileyLinkSettingsViewController.swift index 5d21a60dc..d2dc717db 100644 --- a/RileyLinkKitUI/RileyLinkSettingsViewController.swift +++ b/RileyLinkKitUI/RileyLinkSettingsViewController.swift @@ -13,7 +13,7 @@ import RileyLinkKit open class RileyLinkSettingsViewController: UITableViewController { - open let devicesDataSource: RileyLinkDevicesTableViewDataSource + public let devicesDataSource: RileyLinkDevicesTableViewDataSource public init(rileyLinkPumpManager: RileyLinkPumpManager, devicesSectionIndex: Int, style: UITableViewStyle) { devicesDataSource = RileyLinkDevicesTableViewDataSource(rileyLinkPumpManager: rileyLinkPumpManager, devicesSectionIndex: devicesSectionIndex) From 55b81cd901c92a0cd7c6c8bdb0aa6922efecf68a Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Wed, 15 Aug 2018 15:12:44 -0500 Subject: [PATCH 12/22] Adding decoding for unknown event type 57 (#427) --- .../Messages/Models/PumpEventType.swift | 3 ++ .../PumpEvents/UnknownPumpEvent57.swift | 39 +++++++++++++++++++ MinimedKitTests/HistoryPageTests.swift | 13 +++++++ RileyLink.xcodeproj/project.pbxproj | 4 ++ 4 files changed, 59 insertions(+) create mode 100644 MinimedKit/PumpEvents/UnknownPumpEvent57.swift diff --git a/MinimedKit/Messages/Models/PumpEventType.swift b/MinimedKit/Messages/Models/PumpEventType.swift index d36fef386..dda063ea8 100644 --- a/MinimedKit/Messages/Models/PumpEventType.swift +++ b/MinimedKit/Messages/Models/PumpEventType.swift @@ -40,6 +40,7 @@ public enum PumpEventType: UInt8 { case journalEntryPumpLowReservoir = 0x34 case alarmClockReminder = 0x35 case changeMeterId = 0x36 + case unknown515Event = 0x39 case questionable3b = 0x3b case changeParadigmLinkID = 0x3c case bgReceived = 0x3f @@ -217,6 +218,8 @@ public enum PumpEventType: UInt8 { return ChangeMeterIDPumpEvent.self case .bolusReminder: return BolusReminderPumpEvent.self + case .unknown515Event: + return UnknownPumpEvent57.self default: return PlaceholderPumpEvent.self } diff --git a/MinimedKit/PumpEvents/UnknownPumpEvent57.swift b/MinimedKit/PumpEvents/UnknownPumpEvent57.swift new file mode 100644 index 000000000..37287eb83 --- /dev/null +++ b/MinimedKit/PumpEvents/UnknownPumpEvent57.swift @@ -0,0 +1,39 @@ +// +// UnknownPumpEvent57.swift +// MinimedKit +// +// Created by Pete Schwamb on 8/11/18. +// Copyright © 2018 Pete Schwamb. All rights reserved. +// + +import Foundation + +public struct UnknownPumpEvent57: TimestampedPumpEvent { + public let length: Int + public let rawData: Data + public let timestamp: DateComponents + + public init?(availableData: Data, pumpModel: PumpModel) { + length = 10 + + guard length <= availableData.count else { + return nil + } + + rawData = availableData.subdata(in: 0.. Date: Thu, 16 Aug 2018 10:21:29 -0500 Subject: [PATCH 13/22] Fix to make turning off autoconnect persist (#430) --- RileyLinkKit/RileyLinkPumpManager.swift | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/RileyLinkKit/RileyLinkPumpManager.swift b/RileyLinkKit/RileyLinkPumpManager.swift index 7a45352b0..9bdd4b661 100644 --- a/RileyLinkKit/RileyLinkPumpManager.swift +++ b/RileyLinkKit/RileyLinkPumpManager.swift @@ -118,10 +118,7 @@ extension RileyLinkPumpManager { } open func disconnectFromRileyLink(_ device: RileyLinkDevice) { - _ = lockedRileyLinkPumpManagerState.mutate { (state) in - state.connectedPeripheralIDs.remove(device.peripheralIdentifier.uuidString) - } - + rileyLinkPumpManagerState.connectedPeripheralIDs.remove(device.peripheralIdentifier.uuidString) rileyLinkManager.disconnect(device) } } From 462b8f728633d349b6f9b043427c93a550da144c Mon Sep 17 00:00:00 2001 From: katie disimone Date: Thu, 16 Aug 2018 08:22:21 -0700 Subject: [PATCH 14/22] Translations (#431) * initial language imports * more translations * touchups * added dutch fix --- Common/LocalizedString.swift | 17 + Common/NumberFormatter.swift | 2 +- Crypto/de.lproj/InfoPlist.strings | 3 + Crypto/es.lproj/InfoPlist.strings | 2 +- Crypto/fr.lproj/InfoPlist.strings | 3 + Crypto/it.lproj/InfoPlist.strings | 3 + Crypto/nb.lproj/InfoPlist.strings | 3 + Crypto/nl.lproj/InfoPlist.strings | 3 + Crypto/ru.lproj/InfoPlist.strings | 4 +- Crypto/zh-Hans.lproj/InfoPlist.strings | 3 + MinimedKit/Base.lproj/Localizable.strings | 99 ++++ .../Messages/PumpErrorMessageBody.swift | 8 +- MinimedKit/Messages/PumpMessage.swift | 2 +- MinimedKit/Models/BatteryChemistryType.swift | 4 +- MinimedKit/Models/PumpRegion.swift | 4 +- .../AlarmClockReminderPumpEvent.swift | 2 +- .../PumpEvents/AlarmSensorPumpEvent.swift | 2 +- .../BasalProfileStartPumpEvent.swift | 2 +- .../TempBasalDurationPumpEvent.swift | 2 +- .../PumpEvents/TempBasalPumpEvent.swift | 4 +- .../PumpManager/InsulinDataSource.swift | 4 +- .../PumpManager/MinimedPumpManager.swift | 4 +- .../PumpManager/MinimedPumpManagerError.swift | 4 +- MinimedKit/PumpManager/PumpOpsError.swift | 24 +- MinimedKit/de.lproj/InfoPlist.strings | 3 + MinimedKit/de.lproj/Localizable.strings | 99 ++++ MinimedKit/es.lproj/InfoPlist.strings | 2 +- MinimedKit/es.lproj/Localizable.strings | 57 +++ MinimedKit/fr.lproj/InfoPlist.strings | 3 + MinimedKit/fr.lproj/Localizable.strings | 99 ++++ MinimedKit/it.lproj/InfoPlist.strings | 3 + MinimedKit/it.lproj/Localizable.strings | 99 ++++ MinimedKit/nb.lproj/InfoPlist.strings | 3 + MinimedKit/nb.lproj/Localizable.strings | 99 ++++ MinimedKit/nl.lproj/InfoPlist.strings | 3 + MinimedKit/nl.lproj/Localizable.strings | 99 ++++ MinimedKit/ru.lproj/InfoPlist.strings | 4 +- MinimedKit/ru.lproj/Localizable.strings | 57 +++ MinimedKit/zh-Hans.lproj/InfoPlist.strings | 3 + MinimedKit/zh-Hans.lproj/Localizable.strings | 99 ++++ MinimedKitTests/de.lproj/InfoPlist.strings | 3 + MinimedKitTests/es.lproj/InfoPlist.strings | 3 + MinimedKitTests/fr.lproj/InfoPlist.strings | 3 + MinimedKitTests/it.lproj/InfoPlist.strings | 3 + MinimedKitTests/nb.lproj/InfoPlist.strings | 3 + MinimedKitTests/nl.lproj/InfoPlist.strings | 3 + MinimedKitTests/ru.lproj/InfoPlist.strings | 3 + .../zh-Hans.lproj/InfoPlist.strings | 3 + MinimedKitUI/Base.lproj/Localizable.strings | 195 ++++++++ .../CommandResponseViewController.swift | 46 +- MinimedKitUI/MinimedPumpManager+UI.swift | 4 +- .../MinimedPumpSettingsViewController.swift | 24 +- .../RadioSelectionTableViewController.swift | 4 +- ...LinkMinimedDeviceTableViewController.swift | 54 +-- .../MinimedPumpIDSetupViewController.swift | 2 +- ...MinimedPumpSentrySetupViewController.swift | 2 +- ...nimedPumpSettingsSetupViewController.swift | 4 +- MinimedKitUI/de.lproj/InfoPlist.strings | 3 + MinimedKitUI/de.lproj/Localizable.strings | 195 ++++++++ .../de.lproj/MinimedPumpManager.strings | 72 +++ MinimedKitUI/es.lproj/InfoPlist.strings | 3 + MinimedKitUI/es.lproj/Localizable.strings | 195 ++++++++ .../es.lproj/MinimedPumpManager.strings | 72 +++ MinimedKitUI/fr.lproj/InfoPlist.strings | 3 + MinimedKitUI/fr.lproj/Localizable.strings | 195 ++++++++ .../fr.lproj/MinimedPumpManager.strings | 72 +++ MinimedKitUI/it.lproj/InfoPlist.strings | 3 + MinimedKitUI/it.lproj/Localizable.strings | 195 ++++++++ .../it.lproj/MinimedPumpManager.strings | 72 +++ MinimedKitUI/nb.lproj/InfoPlist.strings | 3 + MinimedKitUI/nb.lproj/Localizable.strings | 195 ++++++++ .../nb.lproj/MinimedPumpManager.strings | 72 +++ MinimedKitUI/nl.lproj/InfoPlist.strings | 3 + MinimedKitUI/nl.lproj/Localizable.strings | 195 ++++++++ .../nl.lproj/MinimedPumpManager.strings | 72 +++ MinimedKitUI/ru.lproj/InfoPlist.strings | 3 + MinimedKitUI/ru.lproj/Localizable.strings | 195 ++++++++ .../ru.lproj/MinimedPumpManager.strings | 72 +++ MinimedKitUI/zh-Hans.lproj/InfoPlist.strings | 3 + .../zh-Hans.lproj/Localizable.strings | 195 ++++++++ .../zh-Hans.lproj/MinimedPumpManager.strings | 72 +++ .../de.lproj/InfoPlist.strings | 3 + .../es.lproj/InfoPlist.strings | 2 +- .../fr.lproj/InfoPlist.strings | 3 + .../it.lproj/InfoPlist.strings | 3 + .../nb.lproj/InfoPlist.strings | 3 + .../nl.lproj/InfoPlist.strings | 3 + .../ru.lproj/InfoPlist.strings | 4 +- .../zh-Hans.lproj/InfoPlist.strings | 3 + .../de.lproj/InfoPlist.strings | 3 + .../es.lproj/InfoPlist.strings | 3 + .../fr.lproj/InfoPlist.strings | 3 + .../it.lproj/InfoPlist.strings | 3 + .../nb.lproj/InfoPlist.strings | 3 + .../nl.lproj/InfoPlist.strings | 3 + .../ru.lproj/InfoPlist.strings | 3 + .../zh-Hans.lproj/InfoPlist.strings | 3 + RileyLink.xcodeproj/project.pbxproj | 446 ++++++++++++++++++ RileyLink/Base.lproj/Localizable.strings | 53 +++ RileyLink/Extensions/UIViewController.swift | 2 +- RileyLink/Models/NightscoutService.swift | 8 +- .../AuthenticationViewController.swift | 6 +- .../RadioSelectionTableViewController.swift | 2 +- .../SettingsTableViewController.swift | 16 +- RileyLink/Views/ValidatingIndicatorView.swift | 2 +- RileyLink/de.lproj/InfoPlist.strings | 0 RileyLink/de.lproj/Localizable.strings | 54 +++ RileyLink/de.lproj/LoopKit.strings | 3 + RileyLink/es.lproj/InfoPlist.strings | 4 +- RileyLink/es.lproj/Localizable.strings | 17 +- RileyLink/fr.lproj/InfoPlist.strings | 0 RileyLink/fr.lproj/Localizable.strings | 54 +++ RileyLink/fr.lproj/LoopKit.strings | 3 + RileyLink/it.lproj/InfoPlist.strings | 0 RileyLink/it.lproj/Localizable.strings | 54 +++ RileyLink/it.lproj/LoopKit.strings | 3 + RileyLink/nb.lproj/InfoPlist.strings | 0 RileyLink/nb.lproj/Localizable.strings | 54 +++ RileyLink/nb.lproj/LoopKit.strings | 3 + RileyLink/nl.lproj/InfoPlist.strings | 6 + RileyLink/nl.lproj/Localizable.strings | 54 +++ RileyLink/nl.lproj/LoopKit.strings | 3 + RileyLink/ru.lproj/InfoPlist.strings | 7 +- RileyLink/ru.lproj/Localizable.strings | 15 +- RileyLink/zh-Hans.lproj/InfoPlist.strings | 6 + RileyLink/zh-Hans.lproj/Localizable.strings | 54 +++ RileyLink/zh-Hans.lproj/LoopKit.strings | 3 + .../Base.lproj/Localizable.strings | 30 ++ RileyLinkBLEKit/PeripheralManagerError.swift | 10 +- RileyLinkBLEKit/RileyLinkDeviceError.swift | 10 +- RileyLinkBLEKit/de.lproj/InfoPlist.strings | 3 + RileyLinkBLEKit/de.lproj/Localizable.strings | 30 ++ RileyLinkBLEKit/es.lproj/InfoPlist.strings | 2 +- RileyLinkBLEKit/es.lproj/Localizable.strings | 27 ++ RileyLinkBLEKit/fr.lproj/InfoPlist.strings | 3 + RileyLinkBLEKit/fr.lproj/Localizable.strings | 27 ++ RileyLinkBLEKit/it.lproj/InfoPlist.strings | 3 + RileyLinkBLEKit/it.lproj/Localizable.strings | 30 ++ RileyLinkBLEKit/nb.lproj/InfoPlist.strings | 3 + RileyLinkBLEKit/nb.lproj/Localizable.strings | 30 ++ RileyLinkBLEKit/nl.lproj/InfoPlist.strings | 3 + RileyLinkBLEKit/nl.lproj/Localizable.strings | 30 ++ RileyLinkBLEKit/ru.lproj/InfoPlist.strings | 4 +- RileyLinkBLEKit/ru.lproj/Localizable.strings | 30 ++ .../zh-Hans.lproj/InfoPlist.strings | 3 + .../zh-Hans.lproj/Localizable.strings | 30 ++ .../de.lproj/InfoPlist.strings | 3 + .../es.lproj/InfoPlist.strings | 3 + .../fr.lproj/InfoPlist.strings | 3 + .../it.lproj/InfoPlist.strings | 3 + .../nb.lproj/InfoPlist.strings | 3 + .../nl.lproj/InfoPlist.strings | 3 + .../ru.lproj/InfoPlist.strings | 3 + .../zh-Hans.lproj/InfoPlist.strings | 3 + RileyLinkKit/de.lproj/InfoPlist.strings | 3 + RileyLinkKit/de.lproj/Localizable.strings | 189 ++++++++ RileyLinkKit/es.lproj/InfoPlist.strings | 2 +- RileyLinkKit/fr.lproj/InfoPlist.strings | 3 + RileyLinkKit/fr.lproj/Localizable.strings | 189 ++++++++ RileyLinkKit/it.lproj/InfoPlist.strings | 3 + RileyLinkKit/it.lproj/Localizable.strings | 189 ++++++++ RileyLinkKit/nb.lproj/InfoPlist.strings | 3 + RileyLinkKit/nb.lproj/Localizable.strings | 189 ++++++++ RileyLinkKit/nl.lproj/InfoPlist.strings | 3 + RileyLinkKit/nl.lproj/Localizable.strings | 189 ++++++++ RileyLinkKit/ru.lproj/InfoPlist.strings | 4 +- RileyLinkKit/zh-Hans.lproj/InfoPlist.strings | 3 + .../zh-Hans.lproj/Localizable.strings | 189 ++++++++ RileyLinkKitTests/de.lproj/InfoPlist.strings | 3 + RileyLinkKitTests/es.lproj/InfoPlist.strings | 3 + RileyLinkKitTests/fr.lproj/InfoPlist.strings | 3 + RileyLinkKitTests/it.lproj/InfoPlist.strings | 3 + RileyLinkKitTests/nb.lproj/InfoPlist.strings | 3 + RileyLinkKitTests/nl.lproj/InfoPlist.strings | 3 + RileyLinkKitTests/ru.lproj/InfoPlist.strings | 3 + .../zh-Hans.lproj/InfoPlist.strings | 3 + RileyLinkKitUI/Base.lproj/Localizable.strings | 52 ++ RileyLinkKitUI/CBPeripheralState.swift | 8 +- .../RileyLinkDeviceTableViewController.swift | 20 +- .../RileyLinkDevicesTableViewDataSource.swift | 2 +- .../RileyLinkSetupTableViewController.swift | 2 +- RileyLinkKitUI/de.lproj/InfoPlist.strings | 3 + RileyLinkKitUI/de.lproj/Localizable.strings | 51 ++ RileyLinkKitUI/es.lproj/InfoPlist.strings | 3 + RileyLinkKitUI/es.lproj/Localizable.strings | 51 ++ RileyLinkKitUI/fr.lproj/InfoPlist.strings | 3 + RileyLinkKitUI/fr.lproj/Localizable.strings | 51 ++ RileyLinkKitUI/it.lproj/InfoPlist.strings | 3 + RileyLinkKitUI/it.lproj/Localizable.strings | 51 ++ RileyLinkKitUI/nb.lproj/InfoPlist.strings | 3 + RileyLinkKitUI/nb.lproj/Localizable.strings | 51 ++ RileyLinkKitUI/nl.lproj/InfoPlist.strings | 3 + RileyLinkKitUI/nl.lproj/Localizable.strings | 51 ++ RileyLinkKitUI/ru.lproj/InfoPlist.strings | 3 + RileyLinkKitUI/ru.lproj/Localizable.strings | 51 ++ .../zh-Hans.lproj/InfoPlist.strings | 3 + .../zh-Hans.lproj/Localizable.strings | 51 ++ RileyLinkTests/de.lproj/InfoPlist.strings | 2 + RileyLinkTests/fr.lproj/InfoPlist.strings | 2 + RileyLinkTests/it.lproj/InfoPlist.strings | 2 + RileyLinkTests/nb.lproj/InfoPlist.strings | 2 + RileyLinkTests/nl.lproj/InfoPlist.strings | 2 + .../zh-Hans.lproj/InfoPlist.strings | 2 + 203 files changed, 6307 insertions(+), 174 deletions(-) create mode 100644 Common/LocalizedString.swift create mode 100644 Crypto/de.lproj/InfoPlist.strings create mode 100644 Crypto/fr.lproj/InfoPlist.strings create mode 100644 Crypto/it.lproj/InfoPlist.strings create mode 100644 Crypto/nb.lproj/InfoPlist.strings create mode 100644 Crypto/nl.lproj/InfoPlist.strings create mode 100644 Crypto/zh-Hans.lproj/InfoPlist.strings create mode 100644 MinimedKit/Base.lproj/Localizable.strings create mode 100644 MinimedKit/de.lproj/InfoPlist.strings create mode 100644 MinimedKit/de.lproj/Localizable.strings create mode 100644 MinimedKit/fr.lproj/InfoPlist.strings create mode 100644 MinimedKit/fr.lproj/Localizable.strings create mode 100644 MinimedKit/it.lproj/InfoPlist.strings create mode 100644 MinimedKit/it.lproj/Localizable.strings create mode 100644 MinimedKit/nb.lproj/InfoPlist.strings create mode 100644 MinimedKit/nb.lproj/Localizable.strings create mode 100644 MinimedKit/nl.lproj/InfoPlist.strings create mode 100644 MinimedKit/nl.lproj/Localizable.strings create mode 100644 MinimedKit/zh-Hans.lproj/InfoPlist.strings create mode 100644 MinimedKit/zh-Hans.lproj/Localizable.strings create mode 100644 MinimedKitTests/de.lproj/InfoPlist.strings create mode 100644 MinimedKitTests/es.lproj/InfoPlist.strings create mode 100644 MinimedKitTests/fr.lproj/InfoPlist.strings create mode 100644 MinimedKitTests/it.lproj/InfoPlist.strings create mode 100644 MinimedKitTests/nb.lproj/InfoPlist.strings create mode 100644 MinimedKitTests/nl.lproj/InfoPlist.strings create mode 100644 MinimedKitTests/ru.lproj/InfoPlist.strings create mode 100644 MinimedKitTests/zh-Hans.lproj/InfoPlist.strings create mode 100644 MinimedKitUI/Base.lproj/Localizable.strings create mode 100644 MinimedKitUI/de.lproj/InfoPlist.strings create mode 100644 MinimedKitUI/de.lproj/Localizable.strings create mode 100644 MinimedKitUI/de.lproj/MinimedPumpManager.strings create mode 100644 MinimedKitUI/es.lproj/InfoPlist.strings create mode 100644 MinimedKitUI/es.lproj/Localizable.strings create mode 100644 MinimedKitUI/es.lproj/MinimedPumpManager.strings create mode 100644 MinimedKitUI/fr.lproj/InfoPlist.strings create mode 100644 MinimedKitUI/fr.lproj/Localizable.strings create mode 100644 MinimedKitUI/fr.lproj/MinimedPumpManager.strings create mode 100644 MinimedKitUI/it.lproj/InfoPlist.strings create mode 100644 MinimedKitUI/it.lproj/Localizable.strings create mode 100644 MinimedKitUI/it.lproj/MinimedPumpManager.strings create mode 100644 MinimedKitUI/nb.lproj/InfoPlist.strings create mode 100644 MinimedKitUI/nb.lproj/Localizable.strings create mode 100644 MinimedKitUI/nb.lproj/MinimedPumpManager.strings create mode 100644 MinimedKitUI/nl.lproj/InfoPlist.strings create mode 100644 MinimedKitUI/nl.lproj/Localizable.strings create mode 100644 MinimedKitUI/nl.lproj/MinimedPumpManager.strings create mode 100644 MinimedKitUI/ru.lproj/InfoPlist.strings create mode 100644 MinimedKitUI/ru.lproj/Localizable.strings create mode 100644 MinimedKitUI/ru.lproj/MinimedPumpManager.strings create mode 100644 MinimedKitUI/zh-Hans.lproj/InfoPlist.strings create mode 100644 MinimedKitUI/zh-Hans.lproj/Localizable.strings create mode 100644 MinimedKitUI/zh-Hans.lproj/MinimedPumpManager.strings create mode 100644 NightscoutUploadKit/de.lproj/InfoPlist.strings create mode 100644 NightscoutUploadKit/fr.lproj/InfoPlist.strings create mode 100644 NightscoutUploadKit/it.lproj/InfoPlist.strings create mode 100644 NightscoutUploadKit/nb.lproj/InfoPlist.strings create mode 100644 NightscoutUploadKit/nl.lproj/InfoPlist.strings create mode 100644 NightscoutUploadKit/zh-Hans.lproj/InfoPlist.strings create mode 100644 NightscoutUploadKitTests/de.lproj/InfoPlist.strings create mode 100644 NightscoutUploadKitTests/es.lproj/InfoPlist.strings create mode 100644 NightscoutUploadKitTests/fr.lproj/InfoPlist.strings create mode 100644 NightscoutUploadKitTests/it.lproj/InfoPlist.strings create mode 100644 NightscoutUploadKitTests/nb.lproj/InfoPlist.strings create mode 100644 NightscoutUploadKitTests/nl.lproj/InfoPlist.strings create mode 100644 NightscoutUploadKitTests/ru.lproj/InfoPlist.strings create mode 100644 NightscoutUploadKitTests/zh-Hans.lproj/InfoPlist.strings create mode 100644 RileyLink/Base.lproj/Localizable.strings create mode 100644 RileyLink/de.lproj/InfoPlist.strings create mode 100644 RileyLink/de.lproj/Localizable.strings create mode 100644 RileyLink/de.lproj/LoopKit.strings create mode 100644 RileyLink/fr.lproj/InfoPlist.strings create mode 100644 RileyLink/fr.lproj/Localizable.strings create mode 100644 RileyLink/fr.lproj/LoopKit.strings create mode 100644 RileyLink/it.lproj/InfoPlist.strings create mode 100644 RileyLink/it.lproj/Localizable.strings create mode 100644 RileyLink/it.lproj/LoopKit.strings create mode 100644 RileyLink/nb.lproj/InfoPlist.strings create mode 100644 RileyLink/nb.lproj/Localizable.strings create mode 100644 RileyLink/nb.lproj/LoopKit.strings create mode 100644 RileyLink/nl.lproj/InfoPlist.strings create mode 100644 RileyLink/nl.lproj/Localizable.strings create mode 100644 RileyLink/nl.lproj/LoopKit.strings create mode 100644 RileyLink/zh-Hans.lproj/InfoPlist.strings create mode 100644 RileyLink/zh-Hans.lproj/Localizable.strings create mode 100644 RileyLink/zh-Hans.lproj/LoopKit.strings create mode 100644 RileyLinkBLEKit/Base.lproj/Localizable.strings create mode 100644 RileyLinkBLEKit/de.lproj/InfoPlist.strings create mode 100644 RileyLinkBLEKit/de.lproj/Localizable.strings create mode 100644 RileyLinkBLEKit/es.lproj/Localizable.strings create mode 100644 RileyLinkBLEKit/fr.lproj/InfoPlist.strings create mode 100644 RileyLinkBLEKit/fr.lproj/Localizable.strings create mode 100644 RileyLinkBLEKit/it.lproj/InfoPlist.strings create mode 100644 RileyLinkBLEKit/it.lproj/Localizable.strings create mode 100644 RileyLinkBLEKit/nb.lproj/InfoPlist.strings create mode 100644 RileyLinkBLEKit/nb.lproj/Localizable.strings create mode 100644 RileyLinkBLEKit/nl.lproj/InfoPlist.strings create mode 100644 RileyLinkBLEKit/nl.lproj/Localizable.strings create mode 100644 RileyLinkBLEKit/ru.lproj/Localizable.strings create mode 100644 RileyLinkBLEKit/zh-Hans.lproj/InfoPlist.strings create mode 100644 RileyLinkBLEKit/zh-Hans.lproj/Localizable.strings create mode 100644 RileyLinkBLEKitTests/de.lproj/InfoPlist.strings create mode 100644 RileyLinkBLEKitTests/es.lproj/InfoPlist.strings create mode 100644 RileyLinkBLEKitTests/fr.lproj/InfoPlist.strings create mode 100644 RileyLinkBLEKitTests/it.lproj/InfoPlist.strings create mode 100644 RileyLinkBLEKitTests/nb.lproj/InfoPlist.strings create mode 100644 RileyLinkBLEKitTests/nl.lproj/InfoPlist.strings create mode 100644 RileyLinkBLEKitTests/ru.lproj/InfoPlist.strings create mode 100644 RileyLinkBLEKitTests/zh-Hans.lproj/InfoPlist.strings create mode 100644 RileyLinkKit/de.lproj/InfoPlist.strings create mode 100644 RileyLinkKit/de.lproj/Localizable.strings create mode 100644 RileyLinkKit/fr.lproj/InfoPlist.strings create mode 100644 RileyLinkKit/fr.lproj/Localizable.strings create mode 100644 RileyLinkKit/it.lproj/InfoPlist.strings create mode 100644 RileyLinkKit/it.lproj/Localizable.strings create mode 100644 RileyLinkKit/nb.lproj/InfoPlist.strings create mode 100644 RileyLinkKit/nb.lproj/Localizable.strings create mode 100644 RileyLinkKit/nl.lproj/InfoPlist.strings create mode 100644 RileyLinkKit/nl.lproj/Localizable.strings create mode 100644 RileyLinkKit/zh-Hans.lproj/InfoPlist.strings create mode 100644 RileyLinkKit/zh-Hans.lproj/Localizable.strings create mode 100644 RileyLinkKitTests/de.lproj/InfoPlist.strings create mode 100644 RileyLinkKitTests/es.lproj/InfoPlist.strings create mode 100644 RileyLinkKitTests/fr.lproj/InfoPlist.strings create mode 100644 RileyLinkKitTests/it.lproj/InfoPlist.strings create mode 100644 RileyLinkKitTests/nb.lproj/InfoPlist.strings create mode 100644 RileyLinkKitTests/nl.lproj/InfoPlist.strings create mode 100644 RileyLinkKitTests/ru.lproj/InfoPlist.strings create mode 100644 RileyLinkKitTests/zh-Hans.lproj/InfoPlist.strings create mode 100644 RileyLinkKitUI/Base.lproj/Localizable.strings create mode 100644 RileyLinkKitUI/de.lproj/InfoPlist.strings create mode 100644 RileyLinkKitUI/de.lproj/Localizable.strings create mode 100644 RileyLinkKitUI/es.lproj/InfoPlist.strings create mode 100644 RileyLinkKitUI/es.lproj/Localizable.strings create mode 100644 RileyLinkKitUI/fr.lproj/InfoPlist.strings create mode 100644 RileyLinkKitUI/fr.lproj/Localizable.strings create mode 100644 RileyLinkKitUI/it.lproj/InfoPlist.strings create mode 100644 RileyLinkKitUI/it.lproj/Localizable.strings create mode 100644 RileyLinkKitUI/nb.lproj/InfoPlist.strings create mode 100644 RileyLinkKitUI/nb.lproj/Localizable.strings create mode 100644 RileyLinkKitUI/nl.lproj/InfoPlist.strings create mode 100644 RileyLinkKitUI/nl.lproj/Localizable.strings create mode 100644 RileyLinkKitUI/ru.lproj/InfoPlist.strings create mode 100644 RileyLinkKitUI/ru.lproj/Localizable.strings create mode 100644 RileyLinkKitUI/zh-Hans.lproj/InfoPlist.strings create mode 100644 RileyLinkKitUI/zh-Hans.lproj/Localizable.strings create mode 100644 RileyLinkTests/de.lproj/InfoPlist.strings create mode 100644 RileyLinkTests/fr.lproj/InfoPlist.strings create mode 100644 RileyLinkTests/it.lproj/InfoPlist.strings create mode 100644 RileyLinkTests/nb.lproj/InfoPlist.strings create mode 100644 RileyLinkTests/nl.lproj/InfoPlist.strings create mode 100644 RileyLinkTests/zh-Hans.lproj/InfoPlist.strings diff --git a/Common/LocalizedString.swift b/Common/LocalizedString.swift new file mode 100644 index 000000000..72a61df82 --- /dev/null +++ b/Common/LocalizedString.swift @@ -0,0 +1,17 @@ +// +// LocalizedString.swift +// RileyLink +// +// Created by Kathryn DiSimone on 8/15/18. +// Copyright © 2018 Pete Schwamb. All rights reserved. +// + +import Foundation + +private class FrameworkBundle { + static let main = Bundle(for: FrameworkBundle.self) +} + +func LocalizedString(_ key: String, tableName: String? = nil, value: String = "", comment: String) -> String { + return NSLocalizedString(key, tableName: tableName, bundle: FrameworkBundle.main, value: value, comment: comment) +} diff --git a/Common/NumberFormatter.swift b/Common/NumberFormatter.swift index 676a21f61..137dbe1d0 100644 --- a/Common/NumberFormatter.swift +++ b/Common/NumberFormatter.swift @@ -10,7 +10,7 @@ import Foundation extension NumberFormatter { func decibleString(from decibles: Int?) -> String? { if let decibles = decibles, let formatted = string(from: NSNumber(value: decibles)) { - return String(format: NSLocalizedString("%@ dB", comment: "Unit format string for an RSSI value in decibles"), formatted) + return String(format: LocalizedString("%@ dB", comment: "Unit format string for an RSSI value in decibles"), formatted) } else { return nil } diff --git a/Crypto/de.lproj/InfoPlist.strings b/Crypto/de.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/Crypto/de.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/Crypto/es.lproj/InfoPlist.strings b/Crypto/es.lproj/InfoPlist.strings index f8e9a2b43..bbcf8f904 100644 --- a/Crypto/es.lproj/InfoPlist.strings +++ b/Crypto/es.lproj/InfoPlist.strings @@ -1,3 +1,3 @@ -/* (No Comment) */ +/* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; diff --git a/Crypto/fr.lproj/InfoPlist.strings b/Crypto/fr.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/Crypto/fr.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/Crypto/it.lproj/InfoPlist.strings b/Crypto/it.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/Crypto/it.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/Crypto/nb.lproj/InfoPlist.strings b/Crypto/nb.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/Crypto/nb.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/Crypto/nl.lproj/InfoPlist.strings b/Crypto/nl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/Crypto/nl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/Crypto/ru.lproj/InfoPlist.strings b/Crypto/ru.lproj/InfoPlist.strings index 874e8a453..bbcf8f904 100644 --- a/Crypto/ru.lproj/InfoPlist.strings +++ b/Crypto/ru.lproj/InfoPlist.strings @@ -1 +1,3 @@ -/* No Localized Strings */ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/Crypto/zh-Hans.lproj/InfoPlist.strings b/Crypto/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/Crypto/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKit/Base.lproj/Localizable.strings b/MinimedKit/Base.lproj/Localizable.strings new file mode 100644 index 000000000..ca422cffd --- /dev/null +++ b/MinimedKit/Base.lproj/Localizable.strings @@ -0,0 +1,99 @@ +/* Communications error for a bolus currently running */ +"A bolus is already in progress" = "A bolus is already in progress"; + +/* The description of AlarmClockReminderPumpEvent */ +"AlarmClockReminder" = "AlarmClockReminder"; + +/* The description of AlarmSensorPumpEvent */ +"AlarmSensor" = "AlarmSensor"; + +/* Describing the battery chemistry as Alkaline */ +"Alkaline" = "Alkaline"; + +/* The format string description of a BasalProfileStartPumpEvent. (1: The index of the profile)(2: The basal rate) */ +"Basal Profile %1$@: %2$@ U/hour" = "Basal Profile %1$@: %2$@ U/hour"; + +/* Pump error code when bolus is in progress */ +"Bolus in progress" = "Bolus en progreso"; + +/* Suggestions for diagnosing a command refused pump error */ +"Check that the pump is not suspended or priming, or has a percent temp basal type" = "Check that the pump is not suspended or priming, or has a percent temp basal type"; + +/* Pump error code returned when command refused */ +"Command refused" = "Command refused"; + +/* No comment provided by engineer. */ +"Comms with another pump detected" = "Comms with another pump detected."; + +/* Error description */ +"Decoding Error" = "Decoding Error"; + +/* Error description */ +"Device Error" = "Device Error"; + +/* Describing the pump history insulin data source */ +"Event History" = "Event History"; + +/* Format string for failure reason. (1: The operation being performed) (2: The response data) */ +"Invalid response during %1$@: %2$@" = "Invalid response during %1$@: %2$@"; + +/* Describing the battery chemistry as Lithium */ +"Lithium" = "Lithium"; + +/* Recovery suggestion */ +"Make sure your RileyLink is nearby and powered on" = "Make sure your RileyLink is nearby and powered on"; + +/* Pump error code describing max setting exceeded */ +"Max setting exceeded" = "Max setting exceeded"; + +/* Pump title (1: model number) */ +"Minimed %@" = "Minimed %@"; + +/* Generic title of the minimed pump manager */ +"Minimed 500/700 Series" = "Minimed 500/700 Series"; + +/* Describing the North America pump region */ +"North America" = "North America"; + +/* No comment provided by engineer. */ +"Pump did not respond" = "Pump did not respond"; + +/* Error description */ +"Pump Error" = "Pump Error"; + +/* No comment provided by engineer. */ +"Pump is suspended" = "Pump is suspended"; + +/* No comment provided by engineer. */ +"Pump responded unexpectedly" = "Pump responded unexpectedly"; + +/* The format string describing a pump message. (1: The packet type)(2: The message type)(3: The message address)(4: The message data */ +"PumpMessage(%1$@, %2$@, %3$@, %4$@)" = "PumpMessage(%1$@, %2$@, %3$@, %4$@)"; + +/* Describing the reservoir insulin data source */ +"Reservoir" = "Reservoir"; + +/* Error description */ +"RileyLink radio tune failed" = "RileyLink radio tune failed"; + +/* The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in minutes) */ +"Temporary Basal: %1$.3f U/hour" = "Temporary Basal: %1$.3f U/hour"; + +/* The format string description of a TempBasalDurationPumpEvent. (1: The duration of the temp basal in minutes) */ +"Temporary Basal: %1$d min" = "Temporary Basal: %1$d min"; + +/* The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in percent) */ +"Temporary Basal: %1$d%%" = "Temporary Basal: %1$d%%"; + +/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ +"Unknown pump error code: %1$@" = "Unknown pump error code: %1$@"; + +/* No comment provided by engineer. */ +"Unknown pump model: %@" = "Unknown pump model: %@"; + +/* Format string for an unknown response. (1: The operation being performed) (2: The response data) */ +"Unknown response during %1$@: %2$@" = "Unknown response during %1$@: %2$@"; + +/* Describing the worldwide pump region */ +"World-Wide" = "World-Wide"; + diff --git a/MinimedKit/Messages/PumpErrorMessageBody.swift b/MinimedKit/Messages/PumpErrorMessageBody.swift index 99e0cdbf2..ea91b3ee6 100644 --- a/MinimedKit/Messages/PumpErrorMessageBody.swift +++ b/MinimedKit/Messages/PumpErrorMessageBody.swift @@ -17,18 +17,18 @@ public enum PumpErrorCode: UInt8, CustomStringConvertible { public var description: String { switch self { case .commandRefused: - return NSLocalizedString("Command refused", comment: "Pump error code returned when command refused") + return LocalizedString("Command refused", comment: "Pump error code returned when command refused") case .maxSettingExceeded: - return NSLocalizedString("Max setting exceeded", comment: "Pump error code describing max setting exceeded") + return LocalizedString("Max setting exceeded", comment: "Pump error code describing max setting exceeded") case .bolusInProgress: - return NSLocalizedString("Bolus in progress", comment: "Pump error code when bolus is in progress") + return LocalizedString("Bolus in progress", comment: "Pump error code when bolus is in progress") } } public var recoverySuggestion: String? { switch self { case .commandRefused: - return NSLocalizedString("Check that the pump is not suspended or priming, or has a percent temp basal type", comment: "Suggestions for diagnosing a command refused pump error") + return LocalizedString("Check that the pump is not suspended or priming, or has a percent temp basal type", comment: "Suggestions for diagnosing a command refused pump error") default: return nil } diff --git a/MinimedKit/Messages/PumpMessage.swift b/MinimedKit/Messages/PumpMessage.swift index 8e4f73439..471ae79aa 100644 --- a/MinimedKit/Messages/PumpMessage.swift +++ b/MinimedKit/Messages/PumpMessage.swift @@ -48,7 +48,7 @@ public struct PumpMessage : CustomStringConvertible { } public var description: String { - return String(format: NSLocalizedString("PumpMessage(%1$@, %2$@, %3$@, %4$@)", comment: "The format string describing a pump message. (1: The packet type)(2: The message type)(3: The message address)(4: The message data"), String(describing: packetType), String(describing: messageType), String(describing: address), String(describing: self.messageBody.txData)) + return String(format: LocalizedString("PumpMessage(%1$@, %2$@, %3$@, %4$@)", comment: "The format string describing a pump message. (1: The packet type)(2: The message type)(3: The message address)(4: The message data"), String(describing: packetType), String(describing: messageType), String(describing: address), String(describing: self.messageBody.txData)) } } diff --git a/MinimedKit/Models/BatteryChemistryType.swift b/MinimedKit/Models/BatteryChemistryType.swift index a797e7571..997683433 100644 --- a/MinimedKit/Models/BatteryChemistryType.swift +++ b/MinimedKit/Models/BatteryChemistryType.swift @@ -15,9 +15,9 @@ public enum BatteryChemistryType: Int, CustomStringConvertible { public var description: String { switch self { case .alkaline: - return NSLocalizedString("Alkaline", comment: "Describing the battery chemistry as Alkaline") + return LocalizedString("Alkaline", comment: "Describing the battery chemistry as Alkaline") case .lithium: - return NSLocalizedString("Lithium", comment: "Describing the battery chemistry as Lithium") + return LocalizedString("Lithium", comment: "Describing the battery chemistry as Lithium") } } diff --git a/MinimedKit/Models/PumpRegion.swift b/MinimedKit/Models/PumpRegion.swift index efc90c1a9..1822e2220 100644 --- a/MinimedKit/Models/PumpRegion.swift +++ b/MinimedKit/Models/PumpRegion.swift @@ -15,9 +15,9 @@ public enum PumpRegion: Int, CustomStringConvertible { public var description: String { switch self { case .worldWide: - return NSLocalizedString("World-Wide", comment: "Describing the worldwide pump region") + return LocalizedString("World-Wide", comment: "Describing the worldwide pump region") case .northAmerica: - return NSLocalizedString("North America", comment: "Describing the North America pump region") + return LocalizedString("North America", comment: "Describing the North America pump region") } } } diff --git a/MinimedKit/PumpEvents/AlarmClockReminderPumpEvent.swift b/MinimedKit/PumpEvents/AlarmClockReminderPumpEvent.swift index 613cae149..17bef7b56 100644 --- a/MinimedKit/PumpEvents/AlarmClockReminderPumpEvent.swift +++ b/MinimedKit/PumpEvents/AlarmClockReminderPumpEvent.swift @@ -32,6 +32,6 @@ public struct AlarmClockReminderPumpEvent: TimestampedPumpEvent { } public var description: String { - return NSLocalizedString("AlarmClockReminder", comment: "The description of AlarmClockReminderPumpEvent") + return LocalizedString("AlarmClockReminder", comment: "The description of AlarmClockReminderPumpEvent") } } diff --git a/MinimedKit/PumpEvents/AlarmSensorPumpEvent.swift b/MinimedKit/PumpEvents/AlarmSensorPumpEvent.swift index 51acc7ed4..f22ba2461 100644 --- a/MinimedKit/PumpEvents/AlarmSensorPumpEvent.swift +++ b/MinimedKit/PumpEvents/AlarmSensorPumpEvent.swift @@ -32,6 +32,6 @@ public struct AlarmSensorPumpEvent: TimestampedPumpEvent { } public var description: String { - return NSLocalizedString("AlarmSensor", comment: "The description of AlarmSensorPumpEvent") + return LocalizedString("AlarmSensor", comment: "The description of AlarmSensorPumpEvent") } } diff --git a/MinimedKit/PumpEvents/BasalProfileStartPumpEvent.swift b/MinimedKit/PumpEvents/BasalProfileStartPumpEvent.swift index 35c2af481..4d782e7ff 100644 --- a/MinimedKit/PumpEvents/BasalProfileStartPumpEvent.swift +++ b/MinimedKit/PumpEvents/BasalProfileStartPumpEvent.swift @@ -45,6 +45,6 @@ public struct BasalProfileStartPumpEvent: TimestampedPumpEvent { } public var description: String { - return String(format: NSLocalizedString("Basal Profile %1$@: %2$@ U/hour", comment: "The format string description of a BasalProfileStartPumpEvent. (1: The index of the profile)(2: The basal rate)"), scheduleEntry.index, scheduleEntry.rate) + return String(format: LocalizedString("Basal Profile %1$@: %2$@ U/hour", comment: "The format string description of a BasalProfileStartPumpEvent. (1: The index of the profile)(2: The basal rate)"), scheduleEntry.index, scheduleEntry.rate) } } diff --git a/MinimedKit/PumpEvents/TempBasalDurationPumpEvent.swift b/MinimedKit/PumpEvents/TempBasalDurationPumpEvent.swift index 81e44e818..f57a44e11 100644 --- a/MinimedKit/PumpEvents/TempBasalDurationPumpEvent.swift +++ b/MinimedKit/PumpEvents/TempBasalDurationPumpEvent.swift @@ -39,6 +39,6 @@ public struct TempBasalDurationPumpEvent: TimestampedPumpEvent { } public var description: String { - return String(format: NSLocalizedString("Temporary Basal: %1$d min", comment: "The format string description of a TempBasalDurationPumpEvent. (1: The duration of the temp basal in minutes)"), duration) + return String(format: LocalizedString("Temporary Basal: %1$d min", comment: "The format string description of a TempBasalDurationPumpEvent. (1: The duration of the temp basal in minutes)"), duration) } } diff --git a/MinimedKit/PumpEvents/TempBasalPumpEvent.swift b/MinimedKit/PumpEvents/TempBasalPumpEvent.swift index 1424b9544..ed44c26ff 100644 --- a/MinimedKit/PumpEvents/TempBasalPumpEvent.swift +++ b/MinimedKit/PumpEvents/TempBasalPumpEvent.swift @@ -56,9 +56,9 @@ public struct TempBasalPumpEvent: TimestampedPumpEvent { public var description: String { switch rateType { case .Absolute: - return String(format: NSLocalizedString("Temporary Basal: %1$.3f U/hour", comment: "The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in minutes)"), rate) + return String(format: LocalizedString("Temporary Basal: %1$.3f U/hour", comment: "The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in minutes)"), rate) case .Percent: - return String(format: NSLocalizedString("Temporary Basal: %1$d%%", comment: "The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in percent)"), Int(rate)) + return String(format: LocalizedString("Temporary Basal: %1$d%%", comment: "The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in percent)"), Int(rate)) } } } diff --git a/MinimedKit/PumpManager/InsulinDataSource.swift b/MinimedKit/PumpManager/InsulinDataSource.swift index 3f38c5c43..83682b9c6 100644 --- a/MinimedKit/PumpManager/InsulinDataSource.swift +++ b/MinimedKit/PumpManager/InsulinDataSource.swift @@ -16,9 +16,9 @@ public enum InsulinDataSource: Int, CustomStringConvertible { public var description: String { switch self { case .pumpHistory: - return NSLocalizedString("Event History", comment: "Describing the pump history insulin data source") + return LocalizedString("Event History", comment: "Describing the pump history insulin data source") case .reservoir: - return NSLocalizedString("Reservoir", comment: "Describing the reservoir insulin data source") + return LocalizedString("Reservoir", comment: "Describing the reservoir insulin data source") } } } diff --git a/MinimedKit/PumpManager/MinimedPumpManager.swift b/MinimedKit/PumpManager/MinimedPumpManager.swift index af10569b9..0d377625b 100644 --- a/MinimedKit/PumpManager/MinimedPumpManager.swift +++ b/MinimedKit/PumpManager/MinimedPumpManager.swift @@ -122,10 +122,10 @@ public class MinimedPumpManager: RileyLinkPumpManager, PumpManager { return state.timeZone } - public static let localizedTitle = NSLocalizedString("Minimed 500/700 Series", comment: "Generic title of the minimed pump manager") + public static let localizedTitle = LocalizedString("Minimed 500/700 Series", comment: "Generic title of the minimed pump manager") public var localizedTitle: String { - return String(format: NSLocalizedString("Minimed %@", comment: "Pump title (1: model number)"), state.pumpModel.rawValue) + return String(format: LocalizedString("Minimed %@", comment: "Pump title (1: model number)"), state.pumpModel.rawValue) } // MARK: - RileyLink Updates diff --git a/MinimedKit/PumpManager/MinimedPumpManagerError.swift b/MinimedKit/PumpManager/MinimedPumpManagerError.swift index e6cebd923..dc5ee656e 100644 --- a/MinimedKit/PumpManager/MinimedPumpManagerError.swift +++ b/MinimedKit/PumpManager/MinimedPumpManagerError.swift @@ -22,7 +22,7 @@ extension MinimedPumpManagerError: LocalizedError { case .noDate: return nil case .tuneFailed(let error): - return [NSLocalizedString("RileyLink radio tune failed", comment: "Error description"), error.errorDescription].compactMap({ $0 }).joined(separator: ": ") + return [LocalizedString("RileyLink radio tune failed", comment: "Error description"), error.errorDescription].compactMap({ $0 }).joined(separator: ": ") } } @@ -40,7 +40,7 @@ extension MinimedPumpManagerError: LocalizedError { public var recoverySuggestion: String? { switch self { case .noRileyLink: - return NSLocalizedString("Make sure your RileyLink is nearby and powered on", comment: "Recovery suggestion") + return LocalizedString("Make sure your RileyLink is nearby and powered on", comment: "Recovery suggestion") case .noDate: return nil case .tuneFailed(let error): diff --git a/MinimedKit/PumpManager/PumpOpsError.swift b/MinimedKit/PumpManager/PumpOpsError.swift index 459323850..b864b47c8 100644 --- a/MinimedKit/PumpManager/PumpOpsError.swift +++ b/MinimedKit/PumpManager/PumpOpsError.swift @@ -40,15 +40,15 @@ extension PumpOpsError: LocalizedError { case .bolusInProgress: return nil case .couldNotDecode: - return NSLocalizedString("Decoding Error", comment: "Error description") + return LocalizedString("Decoding Error", comment: "Error description") case .crosstalk: return nil case .deviceError: - return NSLocalizedString("Device Error", comment: "Error description") + return LocalizedString("Device Error", comment: "Error description") case .noResponse: return nil case .pumpError: - return NSLocalizedString("Pump Error", comment: "Error description") + return LocalizedString("Pump Error", comment: "Error description") case .pumpSuspended: return nil case .rfCommsFailure: @@ -67,25 +67,25 @@ extension PumpOpsError: LocalizedError { public var failureReason: String? { switch self { case .bolusInProgress: - return NSLocalizedString("A bolus is already in progress", comment: "Communications error for a bolus currently running") + return LocalizedString("A bolus is already in progress", comment: "Communications error for a bolus currently running") case .couldNotDecode(rx: let data, during: let during): - return String(format: NSLocalizedString("Invalid response during %1$@: %2$@", comment: "Format string for failure reason. (1: The operation being performed) (2: The response data)"), String(describing: during), data.hexadecimalString) + return String(format: LocalizedString("Invalid response during %1$@: %2$@", comment: "Format string for failure reason. (1: The operation being performed) (2: The response data)"), String(describing: during), data.hexadecimalString) case .crosstalk: - return NSLocalizedString("Comms with another pump detected", comment: "") + return LocalizedString("Comms with another pump detected", comment: "") case .noResponse: - return NSLocalizedString("Pump did not respond", comment: "") + return LocalizedString("Pump did not respond", comment: "") case .pumpSuspended: - return NSLocalizedString("Pump is suspended", comment: "") + return LocalizedString("Pump is suspended", comment: "") case .rfCommsFailure(let msg): return msg case .unexpectedResponse: - return NSLocalizedString("Pump responded unexpectedly", comment: "") + return LocalizedString("Pump responded unexpectedly", comment: "") case .unknownPumpErrorCode(let code): - return String(format: NSLocalizedString("Unknown pump error code: %1$@", comment: "The format string description of an unknown pump error code. (1: The specific error code raw value)"), String(describing: code)) + return String(format: LocalizedString("Unknown pump error code: %1$@", comment: "The format string description of an unknown pump error code. (1: The specific error code raw value)"), String(describing: code)) case .unknownPumpModel(let model): - return String(format: NSLocalizedString("Unknown pump model: %@", comment: ""), model) + return String(format: LocalizedString("Unknown pump model: %@", comment: ""), model) case .unknownResponse(rx: let data, during: let during): - return String(format: NSLocalizedString("Unknown response during %1$@: %2$@", comment: "Format string for an unknown response. (1: The operation being performed) (2: The response data)"), String(describing: during), data.hexadecimalString) + return String(format: LocalizedString("Unknown response during %1$@: %2$@", comment: "Format string for an unknown response. (1: The operation being performed) (2: The response data)"), String(describing: during), data.hexadecimalString) case .pumpError(let errorCode): return String(describing: errorCode) case .deviceError(let error): diff --git a/MinimedKit/de.lproj/InfoPlist.strings b/MinimedKit/de.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKit/de.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKit/de.lproj/Localizable.strings b/MinimedKit/de.lproj/Localizable.strings new file mode 100644 index 000000000..f04adfcd6 --- /dev/null +++ b/MinimedKit/de.lproj/Localizable.strings @@ -0,0 +1,99 @@ +/* Communications error for a bolus currently running */ +"A bolus is already in progress" = "Ein Bolus wird bereits abgegeben"; + +/* The description of AlarmClockReminderPumpEvent */ +"AlarmClockReminder" = "AlarmClockReminder"; + +/* The description of AlarmSensorPumpEvent */ +"AlarmSensor" = "AlarmSensor"; + +/* Describing the battery chemistry as Alkaline */ +"Alkaline" = "Alkalisch"; + +/* The format string description of a BasalProfileStartPumpEvent. (1: The index of the profile)(2: The basal rate) */ +"Basal Profile %1$@: %2$@ U/hour" = "Basalprofil %1$@: %2$@ E/Stunde"; + +/* Pump error code when bolus is in progress */ +"Bolus in progress" = "Bolus im Gang"; + +/* Suggestions for diagnosing a command refused pump error */ +"Check that the pump is not suspended or priming, or has a percent temp basal type" = "Überprüfen, ob die Pumpe nicht unterbrochen wurde oder sich im Füllmodus befindet, oder prozentuell temporären Basalraten aktiviert sind"; + +/* Pump error code returned when command refused */ +"Command refused" = "Befehl verweigert"; + +/* No comment provided by engineer. */ +"Comms with another pump detected" = "Kommunikation mit einer anderen Pumpe festgestellt"; + +/* Error description */ +"Decoding Error" = "Dekodierungsfehler"; + +/* Error description */ +"Device Error" = "Gerätefehler"; + +/* Describing the pump history insulin data source */ +"Event History" = "Ereignisverlauf"; + +/* Format string for failure reason. (1: The operation being performed) (2: The response data) */ +"Invalid response during %1$@: %2$@" = "Ungültige Antwort während %1$@: %2$@"; + +/* Describing the battery chemistry as Lithium */ +"Lithium" = "Lithium"; + +/* Recovery suggestion */ +"Make sure your RileyLink is nearby and powered on" = "Sicherstellen, dass RileyLink sich in der Nähe befindet und angeschaltet ist"; + +/* Pump error code describing max setting exceeded */ +"Max setting exceeded" = "Max Einstellung überschritten"; + +/* Pump title (1: model number) */ +"Minimed %@" = "Minimed %@"; + +/* Generic title of the minimed pump manager */ +"Minimed 500/700 Series" = "Minimed 500/700 Serie"; + +/* Describing the North America pump region */ +"North America" = "Nordamerika"; + +/* No comment provided by engineer. */ +"Pump did not respond" = "Pumpe hat nicht geantwortet"; + +/* Error description */ +"Pump Error" = "Pumpenfehler"; + +/* No comment provided by engineer. */ +"Pump is suspended" = "Pumpe ist gesperrt"; + +/* No comment provided by engineer. */ +"Pump responded unexpectedly" = "Pumpe hat unerwartet geantwortet"; + +/* The format string describing a pump message. (1: The packet type)(2: The message type)(3: The message address)(4: The message data */ +"PumpMessage(%1$@, %2$@, %3$@, %4$@)" = "MensageMicroinfusadora(%1$@, %2$@, %3$@, %4$@)"; + +/* Describing the reservoir insulin data source */ +"Reservoir" = "Reservoir"; + +/* Error description */ +"RileyLink radio tune failed" = "RileyLink Radiosignal fehlerhaft"; + +/* The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in minutes) */ +"Temporary Basal: %1$.3f U/hour" = "Temporäre Basalrate: %1$.3f E/St"; + +/* The format string description of a TempBasalDurationPumpEvent. (1: The duration of the temp basal in minutes) */ +"Temporary Basal: %1$d min" = "Temporäre Basalrate: %1$d min"; + +/* The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in percent) */ +"Temporary Basal: %1$d%%" = "Temporäre Basalrate: %1$d%%"; + +/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ +"Unknown pump error code: %1$@" = "Unbekannter Fehlercode der Pumpe: %1$@"; + +/* No comment provided by engineer. */ +"Unknown pump model: %@" = "Unbekanntes Pumpenmodell: %@"; + +/* Format string for an unknown response. (1: The operation being performed) (2: The response data) */ +"Unknown response during %1$@: %2$@" = "Unbekannte Antwort oder %1$@: %2$@"; + +/* Describing the worldwide pump region */ +"World-Wide" = "Weltweit"; + diff --git a/MinimedKit/es.lproj/InfoPlist.strings b/MinimedKit/es.lproj/InfoPlist.strings index f8e9a2b43..bbcf8f904 100644 --- a/MinimedKit/es.lproj/InfoPlist.strings +++ b/MinimedKit/es.lproj/InfoPlist.strings @@ -1,3 +1,3 @@ -/* (No Comment) */ +/* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; diff --git a/MinimedKit/es.lproj/Localizable.strings b/MinimedKit/es.lproj/Localizable.strings index ac542e3e4..6da8c08d9 100644 --- a/MinimedKit/es.lproj/Localizable.strings +++ b/MinimedKit/es.lproj/Localizable.strings @@ -1,3 +1,6 @@ +/* Communications error for a bolus currently running */ +"A bolus is already in progress" = "Un bolo ya está en progreso"; + /* The description of AlarmClockReminderPumpEvent */ "AlarmClockReminder" = "AlarmClockReminder"; @@ -13,21 +16,66 @@ /* Pump error code when bolus is in progress */ "Bolus in progress" = "Bolo en progreso"; +/* Suggestions for diagnosing a command refused pump error */ +"Check that the pump is not suspended or priming, or has a percent temp basal type" = "Revisa que la microinfusora no esté suspendida o en cebado, o que tenga una basal de tipo temporal"; + /* Pump error code returned when command refused */ "Command refused" = "Comando rechazado"; +/* No comment provided by engineer. */ +"Comms with another pump detected" = "Comunicación con otra microinfusadora detectado."; + +/* Error description */ +"Decoding Error" = "Error de decodificación"; + +/* Error description */ +"Device Error" = "Error de Dispositivo"; + +/* Describing the pump history insulin data source */ +"Event History" = "Historial de Eventos"; + +/* Format string for failure reason. (1: The operation being performed) (2: The response data) */ +"Invalid response during %1$@: %2$@" = "Respuesta inválida durante %1$@: %2$@"; + /* Describing the battery chemistry as Lithium */ "Lithium" = "Litio"; +/* Recovery suggestion */ +"Make sure your RileyLink is nearby and powered on" = "Asegúrate de que tu RileyLink esté cerca y encendido"; + /* Pump error code describing max setting exceeded */ "Max setting exceeded" = "Ajuste máximo excedido"; +/* Pump title (1: model number) */ +"Minimed %@" = "Minimed %@"; + +/* Generic title of the minimed pump manager */ +"Minimed 500/700 Series" = "Minimed Serie 500/700"; + /* Describing the North America pump region */ "North America" = "Norte America"; +/* No comment provided by engineer. */ +"Pump did not respond" = "La microinfusora no respondió"; + +/* Error description */ +"Pump Error" = "Error de microinfusora"; + +/* No comment provided by engineer. */ +"Pump is suspended" = "La microinfusora está suspendida"; + +/* No comment provided by engineer. */ +"Pump responded unexpectedly" = "La microinfusora respondió de forma inesperada"; + /* The format string describing a pump message. (1: The packet type)(2: The message type)(3: The message address)(4: The message data */ "PumpMessage(%1$@, %2$@, %3$@, %4$@)" = "MensageMicroinfusadora(%1$@, %2$@, %3$@, %4$@)"; +/* Describing the reservoir insulin data source */ +"Reservoir" = "Reservorio"; + +/* Error description */ +"RileyLink radio tune failed" = "Sintonización de señal de radio de RileyLink falló"; + /* The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in minutes) */ "Temporary Basal: %1$.3f U/hour" = "Basal Temporal: %1$.3f U/hora"; @@ -37,6 +85,15 @@ /* The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in percent) */ "Temporary Basal: %1$d%%" = "Basal Temporal: %1$d%%"; +/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ +"Unknown pump error code: %1$@" = "Error desconocido de código de microinfusora: %1$@"; + +/* No comment provided by engineer. */ +"Unknown pump model: %@" = "Modelo desconocido de microinfusora: %@"; + +/* Format string for an unknown response. (1: The operation being performed) (2: The response data) */ +"Unknown response during %1$@: %2$@" = "Respuesta desconocida durante %1$@: %2$@"; + /* Describing the worldwide pump region */ "World-Wide" = "Mundial"; diff --git a/MinimedKit/fr.lproj/InfoPlist.strings b/MinimedKit/fr.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKit/fr.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKit/fr.lproj/Localizable.strings b/MinimedKit/fr.lproj/Localizable.strings new file mode 100644 index 000000000..557046287 --- /dev/null +++ b/MinimedKit/fr.lproj/Localizable.strings @@ -0,0 +1,99 @@ +/* Communications error for a bolus currently running */ +"A bolus is already in progress" = "Un bolus est déjà en cours"; + +/* The description of AlarmClockReminderPumpEvent */ +"AlarmClockReminder" = "AlarmClockReminder"; + +/* The description of AlarmSensorPumpEvent */ +"AlarmSensor" = "AlarmSensor"; + +/* Describing the battery chemistry as Alkaline */ +"Alkaline" = "Alcaline"; + +/* The format string description of a BasalProfileStartPumpEvent. (1: The index of the profile)(2: The basal rate) */ +"Basal Profile %1$@: %2$@ U/hour" = "Profil basal %1$@: %2$@ U/heure"; + +/* Pump error code when bolus is in progress */ +"Bolus in progress" = "Bolus en cours"; + +/* Suggestions for diagnosing a command refused pump error */ +"Check that the pump is not suspended or priming, or has a percent temp basal type" = "Vérifiez que la pompe n’est pas suspendue ou amorcée, ou a un type basal temporaire de pour cent"; + +/* Pump error code returned when command refused */ +"Command refused" = "Commande refusée"; + +/* No comment provided by engineer. */ +"Comms with another pump detected" = "Communications avec une autre pompe détectée"; + +/* Error description */ +"Decoding Error" = "Erreur de décodage"; + +/* Error description */ +"Device Error" = "Erreur de périphérique"; + +/* Describing the pump history insulin data source */ +"Event History" = "Historique des événements"; + +/* Format string for failure reason. (1: The operation being performed) (2: The response data) */ +"Invalid response during %1$@: %2$@" = "Réponse invalide pendant %1$@: %2$@"; + +/* Describing the battery chemistry as Lithium */ +"Lithium" = "Lithium"; + +/* Recovery suggestion */ +"Make sure your RileyLink is nearby and powered on" = "Assurez-vous que votre RileyLink est à proximité et sous tension"; + +/* Pump error code describing max setting exceeded */ +"Max setting exceeded" = "Paramètre maximum dépassée"; + +/* Pump title (1: model number) */ +"Minimed %@" = "Minimed %@"; + +/* Generic title of the minimed pump manager */ +"Minimed 500/700 Series" = "Serié Minimed 500/700"; + +/* Describing the North America pump region */ +"North America" = "Amérique du Nord"; + +/* No comment provided by engineer. */ +"Pump did not respond" = "La pompe n’a pas répondu"; + +/* Error description */ +"Pump Error" = "Erreur de pompe"; + +/* No comment provided by engineer. */ +"Pump is suspended" = "La pompe est suspendue"; + +/* No comment provided by engineer. */ +"Pump responded unexpectedly" = "La pompe a réagi de manière inattendue"; + +/* The format string describing a pump message. (1: The packet type)(2: The message type)(3: The message address)(4: The message data */ +"PumpMessage(%1$@, %2$@, %3$@, %4$@)" = "Message de pompe(%1$@, %2$@, %3$@, %4$@)"; + +/* Describing the reservoir insulin data source */ +"Reservoir" = "Réservoir"; + +/* Error description */ +"RileyLink radio tune failed" = "La synthèse radio RileyLink a échoué"; + +/* The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in minutes) */ +"Temporary Basal: %1$.3f U/hour" = "Basal Temporaire: %1$.3f U/heure"; + +/* The format string description of a TempBasalDurationPumpEvent. (1: The duration of the temp basal in minutes) */ +"Temporary Basal: %1$d min" = "Basal Temporaire: %1$d min"; + +/* The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in percent) */ +"Temporary Basal: %1$d%%" = "Basal Temporaire: %1$d%%"; + +/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ +"Unknown pump error code: %1$@" = "Code d’erreur de pompe inconnu: %1$@"; + +/* No comment provided by engineer. */ +"Unknown pump model: %@" = "Modèle de pompe inconnu: %@"; + +/* Format string for an unknown response. (1: The operation being performed) (2: The response data) */ +"Unknown response during %1$@: %2$@" = "Réponse inconnue pendant %1$@: %2$@"; + +/* Describing the worldwide pump region */ +"World-Wide" = "Monde Entier"; + diff --git a/MinimedKit/it.lproj/InfoPlist.strings b/MinimedKit/it.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKit/it.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKit/it.lproj/Localizable.strings b/MinimedKit/it.lproj/Localizable.strings new file mode 100644 index 000000000..d36c353ce --- /dev/null +++ b/MinimedKit/it.lproj/Localizable.strings @@ -0,0 +1,99 @@ +/* Communications error for a bolus currently running */ +"A bolus is already in progress" = "Un bolo è già in esecuzione"; + +/* The description of AlarmClockReminderPumpEvent */ +"AlarmClockReminder" = "Promemoria sveglia"; + +/* The description of AlarmSensorPumpEvent */ +"AlarmSensor" = "Allarme Sensori"; + +/* Describing the battery chemistry as Alkaline */ +"Alkaline" = "Alcalina"; + +/* The format string description of a BasalProfileStartPumpEvent. (1: The index of the profile)(2: The basal rate) */ +"Basal Profile %1$@: %2$@ U/hour" = "Profilo basale %1$@: %2$@ U/ora"; + +/* Pump error code when bolus is in progress */ +"Bolus in progress" = "Bolo in esecuzione"; + +/* Suggestions for diagnosing a command refused pump error */ +"Check that the pump is not suspended or priming, or has a percent temp basal type" = "Verificare che il microinfusore non sia sospeso o che stia riavvolgendo o che abbia un tipo basale impostato su percentuale"; + +/* Pump error code returned when command refused */ +"Command refused" = "Comando negato"; + +/* No comment provided by engineer. */ +"Comms with another pump detected" = "Comunicazione con un altro microinfusore rilevata"; + +/* Error description */ +"Decoding Error" = "Errore di Decodifica"; + +/* Error description */ +"Device Error" = "Errore del Dispositivo"; + +/* Describing the pump history insulin data source */ +"Event History" = "Storia degli Eventi"; + +/* Format string for failure reason. (1: The operation being performed) (2: The response data) */ +"Invalid response during %1$@: %2$@" = "Risposta non valida per %1$@: %2$@"; + +/* Describing the battery chemistry as Lithium */ +"Lithium" = "Litio"; + +/* Recovery suggestion */ +"Make sure your RileyLink is nearby and powered on" = "Assicurati che il tuo RileyLink sia nelle vicinanze e acceso"; + +/* Pump error code describing max setting exceeded */ +"Max setting exceeded" = "Impostazione massima superata"; + +/* Pump title (1: model number) */ +"Minimed %@" = "Minimed %@"; + +/* Generic title of the minimed pump manager */ +"Minimed 500/700 Series" = "Minimed serie 500/700"; + +/* Describing the North America pump region */ +"North America" = "Nord America"; + +/* No comment provided by engineer. */ +"Pump did not respond" = "Il microinfusore non risponde"; + +/* Error description */ +"Pump Error" = "Errore Mincroinfusore"; + +/* No comment provided by engineer. */ +"Pump is suspended" = "Il microinfusore è sospeso"; + +/* No comment provided by engineer. */ +"Pump responded unexpectedly" = "Il microinfusore ha risposto inaspettatamente"; + +/* The format string describing a pump message. (1: The packet type)(2: The message type)(3: The message address)(4: The message data */ +"PumpMessage(%1$@, %2$@, %3$@, %4$@)" = "PumpMessage(%1$@, %2$@, %3$@, %4$@)"; + +/* Describing the reservoir insulin data source */ +"Reservoir" = "Serbatoio"; + +/* Error description */ +"RileyLink radio tune failed" = "Sintonizzazione radio RileyLink fallita"; + +/* The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in minutes) */ +"Temporary Basal: %1$.3f U/hour" = "Basale Temporanea: %1$.3f U/ora"; + +/* The format string description of a TempBasalDurationPumpEvent. (1: The duration of the temp basal in minutes) */ +"Temporary Basal: %1$d min" = "Basale Temporanea: %1$d min"; + +/* The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in percent) */ +"Temporary Basal: %1$d%%" = "Basale Temporanea: %1$d%%"; + +/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ +"Unknown pump error code: %1$@" = "Codice errore microinfusore sconosciuto: %1$@"; + +/* No comment provided by engineer. */ +"Unknown pump model: %@" = "Modello di microinfusore sconosciuto: %@"; + +/* Format string for an unknown response. (1: The operation being performed) (2: The response data) */ +"Unknown response during %1$@: %2$@" = "Risposta sconosciuta per %1$@: %2$@"; + +/* Describing the worldwide pump region */ +"World-Wide" = "Internazionale"; + diff --git a/MinimedKit/nb.lproj/InfoPlist.strings b/MinimedKit/nb.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKit/nb.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKit/nb.lproj/Localizable.strings b/MinimedKit/nb.lproj/Localizable.strings new file mode 100644 index 000000000..ed3f73a6a --- /dev/null +++ b/MinimedKit/nb.lproj/Localizable.strings @@ -0,0 +1,99 @@ +/* Communications error for a bolus currently running */ +"A bolus is already in progress" = "En bolus pågår allerede"; + +/* The description of AlarmClockReminderPumpEvent */ +"AlarmClockReminder" = "PåminnelseAlarmklokke"; + +/* The description of AlarmSensorPumpEvent */ +"AlarmSensor" = "AlarmSensor"; + +/* Describing the battery chemistry as Alkaline */ +"Alkaline" = "Alkalisk"; + +/* The format string description of a BasalProfileStartPumpEvent. (1: The index of the profile)(2: The basal rate) */ +"Basal Profile %1$@: %2$@ U/hour" = "Basalprofil %1$@: %2$@ E/timen"; + +/* Pump error code when bolus is in progress */ +"Bolus in progress" = "Bolus pågår"; + +/* Suggestions for diagnosing a command refused pump error */ +"Check that the pump is not suspended or priming, or has a percent temp basal type" = "Sjekk at pumpa ikke har stoppet tilførsel av insulin, at priming ikke foregår, eller har en midlertidig prosentbasaltype pågående."; + +/* Pump error code returned when command refused */ +"Command refused" = "Kommando avvist"; + +/* No comment provided by engineer. */ +"Comms with another pump detected" = "Oppdaget kommunikasjon med en annen pumpe"; + +/* Error description */ +"Decoding Error" = "Dekodingsfeil"; + +/* Error description */ +"Device Error" = "Enhetsfeil"; + +/* Describing the pump history insulin data source */ +"Event History" = "Hendelseshistorikk"; + +/* Format string for failure reason. (1: The operation being performed) (2: The response data) */ +"Invalid response during %1$@: %2$@" = "Ugyldig respons ved %1$@: %2$@"; + +/* Describing the battery chemistry as Lithium */ +"Lithium" = "Lithium"; + +/* Recovery suggestion */ +"Make sure your RileyLink is nearby and powered on" = "Kontroller at din RileyLink er i nærheten og er påslått"; + +/* Pump error code describing max setting exceeded */ +"Max setting exceeded" = "Maksinnstilling overskredet"; + +/* Pump title (1: model number) */ +"Minimed %@" = "Minimed %@"; + +/* Generic title of the minimed pump manager */ +"Minimed 500/700 Series" = "Minimed 500/700 series"; + +/* Describing the North America pump region */ +"North America" = "Nord Amerika"; + +/* No comment provided by engineer. */ +"Pump did not respond" = "Pumpa svarte ikke"; + +/* Error description */ +"Pump Error" = "Pumpefeil"; + +/* No comment provided by engineer. */ +"Pump is suspended" = "Pumpe er pauset"; + +/* No comment provided by engineer. */ +"Pump responded unexpectedly" = "Pumpen svarte uventet"; + +/* The format string describing a pump message. (1: The packet type)(2: The message type)(3: The message address)(4: The message data */ +"PumpMessage(%1$@, %2$@, %3$@, %4$@)" = "Pumpemelding(%1$@, %2$@, %3$@, %4$@)"; + +/* Describing the reservoir insulin data source */ +"Reservoir" = "Reservoar"; + +/* Error description */ +"RileyLink radio tune failed" = "RileyLink radiotuning feilet"; + +/* The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in minutes) */ +"Temporary Basal: %1$.3f U/hour" = "Midlertidig basaldose: %1$.3f E/timen"; + +/* The format string description of a TempBasalDurationPumpEvent. (1: The duration of the temp basal in minutes) */ +"Temporary Basal: %1$d min" = "Midlertidig basaldose: %1$d min"; + +/* The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in percent) */ +"Temporary Basal: %1$d%%" = "Midlertidig basaldose: %1$d%%"; + +/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ +"Unknown pump error code: %1$@" = "Ukjent feilkode fra pumpe: %1$@"; + +/* No comment provided by engineer. */ +"Unknown pump model: %@" = "Ukjent pumpemodell: %@"; + +/* Format string for an unknown response. (1: The operation being performed) (2: The response data) */ +"Unknown response during %1$@: %2$@" = "Ukjent respons ved %1$@: %2$@"; + +/* Describing the worldwide pump region */ +"World-Wide" = "World-Wide"; + diff --git a/MinimedKit/nl.lproj/InfoPlist.strings b/MinimedKit/nl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKit/nl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKit/nl.lproj/Localizable.strings b/MinimedKit/nl.lproj/Localizable.strings new file mode 100644 index 000000000..029300ad7 --- /dev/null +++ b/MinimedKit/nl.lproj/Localizable.strings @@ -0,0 +1,99 @@ +/* Communications error for a bolus currently running */ +"A bolus is already in progress" = "Er is al een bolus actief"; + +/* The description of AlarmClockReminderPumpEvent */ +"AlarmClockReminder" = "AlarmClockReminder"; + +/* The description of AlarmSensorPumpEvent */ +"AlarmSensor" = "AlarmSensor"; + +/* Describing the battery chemistry as Alkaline */ +"Alkaline" = "Alkaline"; + +/* The format string description of a BasalProfileStartPumpEvent. (1: The index of the profile)(2: The basal rate) */ +"Basal Profile %1$@: %2$@ U/hour" = "Basaal profiel %1$@: %2$@ E/uur"; + +/* Pump error code when bolus is in progress */ +"Bolus in progress" = "Bolus bezig"; + +/* Suggestions for diagnosing a command refused pump error */ +"Check that the pump is not suspended or priming, or has a percent temp basal type" = "Controleer dat de pomp niet is onderbroken of aan het initialiseren, of dat er een tijdelijke basaal (in %) staat ingesteld "; + +/* Pump error code returned when command refused */ +"Command refused" = "Commando geweigerd"; + +/* No comment provided by engineer. */ +"Comms with another pump detected" = "Communicatie met een andere pomp gedetecteerd"; + +/* Error description */ +"Decoding Error" = "Decodingsfout"; + +/* Error description */ +"Device Error" = "Apparaatfout"; + +/* Describing the pump history insulin data source */ +"Event History" = "Pomp historie"; + +/* Format string for failure reason. (1: The operation being performed) (2: The response data) */ +"Invalid response during %1$@: %2$@" = "Foutief antwoord gedurende %1$@: %2$@"; + +/* Describing the battery chemistry as Lithium */ +"Lithium" = "Lithium"; + +/* Recovery suggestion */ +"Make sure your RileyLink is nearby and powered on" = "Wees er zeker van dat de RileyLink is in de buurt en aanstaat"; + +/* Pump error code describing max setting exceeded */ +"Max setting exceeded" = "Max instelling overschreden"; + +/* Pump title (1: model number) */ +"Minimed %@" = "Minimed %@"; + +/* Generic title of the minimed pump manager */ +"Minimed 500/700 Series" = "Minimed 500/700 series"; + +/* Describing the North America pump region */ +"North America" = "Noord-Amerika"; + +/* No comment provided by engineer. */ +"Pump did not respond" = "Pomp reageert niet"; + +/* Error description */ +"Pump Error" = "Pomp foutmelding"; + +/* No comment provided by engineer. */ +"Pump is suspended" = "Pomp is onderbroken"; + +/* No comment provided by engineer. */ +"Pump responded unexpectedly" = "Pomp reageerde onverwacht"; + +/* The format string describing a pump message. (1: The packet type)(2: The message type)(3: The message address)(4: The message data */ +"PumpMessage(%1$@, %2$@, %3$@, %4$@)" = "Bericht Pomp (%1$@, %2$@, %3$@, %4$@)"; + +/* Describing the reservoir insulin data source */ +"Reservoir" = "Reservoir"; + +/* Error description */ +"RileyLink radio tune failed" = "Afstemmen van de RileyLink Radio mislukt"; + +/* The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in minutes) */ +"Temporary Basal: %1$.3f U/hour" = "Tijdelijk basaal: %1$.3f E/uur"; + +/* The format string description of a TempBasalDurationPumpEvent. (1: The duration of the temp basal in minutes) */ +"Temporary Basal: %1$d min" = "Tijdelijk basaal: %1$d min"; + +/* The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in percent) */ +"Temporary Basal: %1$d%%" = "Tijdelijk basaal: %1$d%%"; + +/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ +"Unknown pump error code: %1$@" = "Onbekende foutmelding pomp: %1$@"; + +/* No comment provided by engineer. */ +"Unknown pump model: %@" = "Onbekend model pomp: %@"; + +/* Format string for an unknown response. (1: The operation being performed) (2: The response data) */ +"Unknown response during %1$@: %2$@" = "Onbekend antwoord gedurende %1$@: %2$@"; + +/* Describing the worldwide pump region */ +"World-Wide" = "Wereldwijd"; + diff --git a/MinimedKit/ru.lproj/InfoPlist.strings b/MinimedKit/ru.lproj/InfoPlist.strings index 874e8a453..bbcf8f904 100644 --- a/MinimedKit/ru.lproj/InfoPlist.strings +++ b/MinimedKit/ru.lproj/InfoPlist.strings @@ -1 +1,3 @@ -/* No Localized Strings */ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKit/ru.lproj/Localizable.strings b/MinimedKit/ru.lproj/Localizable.strings index 848a1af69..6276f7459 100644 --- a/MinimedKit/ru.lproj/Localizable.strings +++ b/MinimedKit/ru.lproj/Localizable.strings @@ -1,3 +1,6 @@ +/* Communications error for a bolus currently running */ +"A bolus is already in progress" = "Болюс уже подается"; + /* The description of AlarmClockReminderPumpEvent */ "AlarmClockReminder" = "Напоминание будильника"; @@ -13,21 +16,66 @@ /* Pump error code when bolus is in progress */ "Bolus in progress" = "Подается болюс"; +/* Suggestions for diagnosing a command refused pump error */ +"Check that the pump is not suspended or priming, or has a percent temp basal type" = "Убедитесь, что помпа не остановлена и не заполняется или не находится в режиме подачи оставшихся процентов временного базала"; + /* Pump error code returned when command refused */ "Command refused" = "Отказ в выполнении команды"; +/* No comment provided by engineer. */ +"Comms with another pump detected" = "Обнаружена коммуникация с другой помпой"; + +/* Error description */ +"Decoding Error" = "Ошибка декодирования"; + +/* Error description */ +"Device Error" = "Ошибка устройства"; + +/* Describing the pump history insulin data source */ +"Event History" = "История событий"; + +/* Format string for failure reason. (1: The operation being performed) (2: The response data) */ +"Invalid response during %1$@: %2$@" = "Неверный отклик в интервале %1$@: %2$@"; + /* Describing the battery chemistry as Lithium */ "Lithium" = "Литиевая"; +/* Recovery suggestion */ +"Make sure your RileyLink is nearby and powered on" = "Убедитесь, что RileyLink включен и находится поблизости"; + /* Pump error code describing max setting exceeded */ "Max setting exceeded" = "Максимальное значение превышено"; +/* Pump title (1: model number) */ +"Minimed %@" = "Minimed %@"; + +/* Generic title of the minimed pump manager */ +"Minimed 500/700 Series" = "Minimed серий 500/700"; + /* Describing the North America pump region */ "North America" = "Сев Америка"; +/* No comment provided by engineer. */ +"Pump did not respond" = "Помпа не ответила"; + +/* Error description */ +"Pump Error" = "Ошибка помпы"; + +/* No comment provided by engineer. */ +"Pump is suspended" = "Помпа остановлена"; + +/* No comment provided by engineer. */ +"Pump responded unexpectedly" = "Неожиданный отклик помпы"; + /* The format string describing a pump message. (1: The packet type)(2: The message type)(3: The message address)(4: The message data */ "PumpMessage(%1$@, %2$@, %3$@, %4$@)" = "Сообщение помпы(%1$@, %2$@, %3$@, %4$@)"; +/* Describing the reservoir insulin data source */ +"Reservoir" = "Резервуар"; + +/* Error description */ +"RileyLink radio tune failed" = "Настройка радиосвязи с RileyLink не удалась"; + /* The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in minutes) */ "Temporary Basal: %1$.3f U/hour" = "Временный базал: %1$.3f ед/ч"; @@ -37,6 +85,15 @@ /* The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in percent) */ "Temporary Basal: %1$d%%" = "Временный базал: %1$d%%"; +/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ +"Unknown pump error code: %1$@" = "Неизвестный код ошибки помпы: %1$@"; + +/* No comment provided by engineer. */ +"Unknown pump model: %@" = "Неизвестная модель помпы: %@"; + +/* Format string for an unknown response. (1: The operation being performed) (2: The response data) */ +"Unknown response during %1$@: %2$@" = "Неизвестный отклик в интервале %1$@: %2$@"; + /* Describing the worldwide pump region */ "World-Wide" = "Глобальный"; diff --git a/MinimedKit/zh-Hans.lproj/InfoPlist.strings b/MinimedKit/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKit/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKit/zh-Hans.lproj/Localizable.strings b/MinimedKit/zh-Hans.lproj/Localizable.strings new file mode 100644 index 000000000..7c44468bd --- /dev/null +++ b/MinimedKit/zh-Hans.lproj/Localizable.strings @@ -0,0 +1,99 @@ +/* Communications error for a bolus currently running */ +"A bolus is already in progress" = "正在输注大剂量"; + +/* The description of AlarmClockReminderPumpEvent */ +"AlarmClockReminder" = "AlarmClockReminder"; + +/* The description of AlarmSensorPumpEvent */ +"AlarmSensor" = "AlarmSensor"; + +/* Describing the battery chemistry as Alkaline */ +"Alkaline" = "碱性电池"; + +/* The format string description of a BasalProfileStartPumpEvent. (1: The index of the profile)(2: The basal rate) */ +"Basal Profile %1$@: %2$@ U/hour" = "基础率配置 %1$@: %2$@ U/小时"; + +/* Pump error code when bolus is in progress */ +"Bolus in progress" = "大剂量输注中"; + +/* Suggestions for diagnosing a command refused pump error */ +"Check that the pump is not suspended or priming, or has a percent temp basal type" = "确认胰岛素泵是否处于暂停或者充盈状态,或者正在执行百分比模式临时基础率。"; + +/* Pump error code returned when command refused */ +"Command refused" = "当前无法执行命令"; + +/* No comment provided by engineer. */ +"Comms with another pump detected" = "发现其他胰岛素泵"; + +/* Error description */ +"Decoding Error" = "解码错误"; + +/* Error description */ +"Device Error" = "设备错误"; + +/* Describing the pump history insulin data source */ +"Event History" = "历史事件"; + +/* Format string for failure reason. (1: The operation being performed) (2: The response data) */ +"Invalid response during %1$@: %2$@" = "无效响应 %1$@: %2$@"; + +/* Describing the battery chemistry as Lithium */ +"Lithium" = "锂铁电池"; + +/* Recovery suggestion */ +"Make sure your RileyLink is nearby and powered on" = "请确认Rileylink靠近手机并且已打开"; + +/* Pump error code describing max setting exceeded */ +"Max setting exceeded" = "超过最大限制"; + +/* Pump title (1: model number) */ +"Minimed %@" = "Minimed %@"; + +/* Generic title of the minimed pump manager */ +"Minimed 500/700 Series" = "Minimed 500/700系列"; + +/* Describing the North America pump region */ +"North America" = "北美"; + +/* No comment provided by engineer. */ +"Pump did not respond" = "胰岛素泵无响应"; + +/* Error description */ +"Pump Error" = "胰岛素泵错误"; + +/* No comment provided by engineer. */ +"Pump is suspended" = "胰岛素泵暂停输注"; + +/* No comment provided by engineer. */ +"Pump responded unexpectedly" = "胰岛素泵通信异常"; + +/* The format string describing a pump message. (1: The packet type)(2: The message type)(3: The message address)(4: The message data */ +"PumpMessage(%1$@, %2$@, %3$@, %4$@)" = "泵的信息(%1$@, %2$@, %3$@, %4$@)"; + +/* Describing the reservoir insulin data source */ +"Reservoir" = "储药器"; + +/* Error description */ +"RileyLink radio tune failed" = "RileyLink调频失败"; + +/* The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in minutes) */ +"Temporary Basal: %1$.3f U/hour" = "临时基础率: %1$.3f U/小时"; + +/* The format string description of a TempBasalDurationPumpEvent. (1: The duration of the temp basal in minutes) */ +"Temporary Basal: %1$d min" = "临时基础率: %1$d 分钟"; + +/* The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in percent) */ +"Temporary Basal: %1$d%%" = "临时基础率: %1$d%%"; + +/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ +"Unknown pump error code: %1$@" = "未知的泵错误代码 %1$@"; + +/* No comment provided by engineer. */ +"Unknown pump model: %@" = "未知的泵型号 %@"; + +/* Format string for an unknown response. (1: The operation being performed) (2: The response data) */ +"Unknown response during %1$@: %2$@" = "未知的响应错误 %1$@: %2$@"; + +/* Describing the worldwide pump region */ +"World-Wide" = "全球"; + diff --git a/MinimedKitTests/de.lproj/InfoPlist.strings b/MinimedKitTests/de.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKitTests/de.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKitTests/es.lproj/InfoPlist.strings b/MinimedKitTests/es.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKitTests/es.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKitTests/fr.lproj/InfoPlist.strings b/MinimedKitTests/fr.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKitTests/fr.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKitTests/it.lproj/InfoPlist.strings b/MinimedKitTests/it.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKitTests/it.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKitTests/nb.lproj/InfoPlist.strings b/MinimedKitTests/nb.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKitTests/nb.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKitTests/nl.lproj/InfoPlist.strings b/MinimedKitTests/nl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKitTests/nl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKitTests/ru.lproj/InfoPlist.strings b/MinimedKitTests/ru.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKitTests/ru.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKitTests/zh-Hans.lproj/InfoPlist.strings b/MinimedKitTests/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKitTests/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKitUI/Base.lproj/Localizable.strings b/MinimedKitUI/Base.lproj/Localizable.strings new file mode 100644 index 000000000..c25a160ce --- /dev/null +++ b/MinimedKitUI/Base.lproj/Localizable.strings @@ -0,0 +1,195 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ +"%1$@ %2$@/%3$@ %4$@" = "%1$@ %2$@/%3$@ %4$@"; + +/* The format string describing number of basal schedule entries: (1: number of entries) */ +"%1$@ basal schedule entries\n" = "%1$@ basal schedule entries\n"; + +/* The format string describing units of insulin remaining: (1: number of units) */ +"%1$@ Units of insulin remaining\n" = "%1$@ Units of insulin remaining\n"; + +/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ +"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; + +/* Instructions on selecting battery chemistry type */ +"Alkaline and Lithium batteries decay at differing rates. Alkaline tend to have a linear voltage drop over time whereas lithium cell batteries tend to maintain voltage until halfway through their lifespan. Under normal usage in a Non-MySentry compatible Minimed (x22/x15) insulin pump running Loop, Alkaline batteries last approximately 4 to 5 days. Lithium batteries last between 1-2 weeks. This selection will use different battery voltage decay rates for each of the battery chemistry types and alert the user when a battery is approximately 8 to 10 hours from failure." = "Alkaline and Lithium batteries decay at differing rates. Alkaline tend to have a linear voltage drop over time whereas lithium cell batteries tend to maintain voltage until halfway through their lifespan. Under normal usage in a Non-MySentry compatible Minimed (x22/x15) insulin pump running Loop, Alkaline batteries last approximately 4 to 5 days. Lithium batteries last between 1-2 weeks. This selection will use different battery voltage decay rates for each of the battery chemistry types and alert the user when a battery is approximately 8 to 10 hours from failure."; + +/* Confirmation message for deleting a pump */ +"Are you sure you want to delete this pump?" = "Are you sure you want to delete this pump?"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Awake Until"; + +/* The title text for the basal rate schedule */ +"Basal Rates" = "Basal Rates"; + +/* The format string describing pump battery voltage: (1: battery voltage) */ +"Battery: %1$@ volts\n" = "Battery: %1$@ volts\n"; + +/* The label indicating the best radio frequency */ +"Best Frequency" = "Best Frequency"; + +/* The format string describing pump bolusing state: (1: bolusing) */ +"Bolusing: %1$@\n" = "Bolusing: %1$@\n"; + +/* The title of the cancel action in an action sheet */ +"Cancel" = "Cancel"; + +/* The title of the command to change pump time */ +"Change Time" = "Change Time"; + +/* The title of the command to change pump time zone */ +"Change Time Zone" = "Change Time Zone"; + +/* Progress message for changing pump time. */ +"Changing time…" = "Changing time…"; + +/* The title of the section describing commands */ +"Commands" = "Commands"; + +/* The title of the configuration section in settings */ +"Configuration" = "Configuration"; + +/* Button title to connect to pump during setup */ +"Connect" = "Connect"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Connection State"; + +/* Button title to delete pump + Title text for the button to remove a pump from Loop */ +"Delete Pump" = "Delete Pump"; + +/* Title text for delivery limits */ +"Delivery Limits" = "Delivery Limits"; + +/* The title of the section describing the device */ +"Device" = "Device"; + +/* The title of the command to discover commands */ +"Discover Commands" = "Discover Commands"; + +/* Progress message for discovering commands. */ +"Discovering commands…" = "Discovering commands…"; + +/* The title of the command to enable diagnostic LEDs */ +"Enable Diagnostic LEDs" = "Enable Diagnostic LEDs"; + +/* Progress message for enabling diagnostic LEDs */ +"Enabled Diagnostic LEDs" = "Enabled Diagnostic LEDs"; + +/* The title of the command to fetch recent glucose */ +"Fetch Enlite Glucose" = "Fetch Enlite Glucose"; + +/* The title of the command to fetch recent history */ +"Fetch Recent History" = "Fetch Recent History"; + +/* Progress message for fetching pump glucose. */ +"Fetching glucose…" = "Fetching glucose…"; + +/* Progress message for fetching pump history. */ +"Fetching history…" = "Fetching history…"; + +/* Progress message for fetching pump model. */ +"Fetching pump model…" = "Fetching pump model…"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Firmware"; + +/* The title of the command to get pump model */ +"Get Pump Model" = "Get Pump Model"; + +/* Progress message for getting statistics. */ +"Get Statistics…" = "Get Statistics…"; + +/* Instructions on selecting an insulin data source */ +"Insulin delivery can be determined from the pump by either interpreting the event history or comparing the reservoir volume over time. Reading event history allows for a more accurate status graph and uploading up-to-date treatment data to Nightscout, at the cost of faster pump battery drain and the possibility of a higher radio error rate compared to reading only reservoir volume. If the selected source cannot be used for any reason, the system will attempt to fall back to the other option." = "Insulin delivery can be determined from the pump by either interpreting the event history or comparing the reservoir volume over time. Reading event history allows for a more accurate status graph and uploading up-to-date treatment data to Nightscout, at the cost of faster pump battery drain and the possibility of a higher radio error rate compared to reading only reservoir volume. If the selected source cannot be used for any reason, the system will attempt to fall back to the other option."; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "Last Awake"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Listening Off"; + +/* The title of the command to pair with mysentry */ +"MySentry Pair" = "MySentry Pair"; + +/* The title of the cell showing device name */ +"Name" = "Name"; + +/* Message display when no response from tuning pump */ +"No response" = "No response"; + +/* The title of the cell showing the last idle */ +"On Idle" = "On Idle"; + +/* The title text for the preferred insulin data source config */ +"Preferred Data Source" = "Preferred Data Source"; + +/* The title of the section describing the pump */ +"Pump" = "Pump"; + +/* The title text for the battery type value */ +"Pump Battery Type" = "Pump Battery Type"; + +/* The title of the cell showing pump ID + The title text for the pump ID config value */ +"Pump ID" = "Pump ID"; + +/* The title of the cell showing the pump model number */ +"Pump Model" = "Pump Model"; + +/* Title of the pump settings view controller */ +"Pump Settings" = "Pump Settings"; + +/* The title of the command to read basal schedule */ +"Read Basal Schedule" = "Read Basal Schedule"; + +/* The title of the command to read pump status */ +"Read Pump Status" = "Read Pump Status"; + +/* Progress message for reading basal schedule */ +"Reading basal schedule…" = "Reading basal schedule…"; + +/* Progress message for reading pump status */ +"Reading pump status…" = "Reading pump status…"; + +/* Button title to retry sentry setup */ +"Retry" = "Retry"; + +/* The title of the command to fetch RileyLink statistics */ +"RileyLink Statistics" = "RileyLink Statistics"; + +/* Title of button to save basal profile to pump + Title of button to save delivery limit settings to pump */ +"Save to Pump…" = "Save to Pump…"; + +/* The title of the command to send a button press */ +"Send Button Press" = "Send Button Press"; + +/* Progress message for sending button press to pump. */ +"Sending button press…" = "Sending button press…"; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Signal Strength"; + +/* A message indicating a command succeeded */ +"Succeeded" = "Succeeded"; + +/* The format string describing pump suspended state: (1: suspended) */ +"Suspended: %1$@\n" = "Suspended: %1$@\n"; + +/* The label indicating the results of each frequency trial */ +"Trials" = "Trials"; + +/* The title of the command to re-tune the radio */ +"Tune Radio Frequency" = "Tune Radio Frequency"; + +/* Progress message for tuning radio */ +"Tuning radio…" = "Tuning radio…"; + +/* The detail text for an unknown pump model */ +"Unknown" = "Unknown"; + diff --git a/MinimedKitUI/CommandResponseViewController.swift b/MinimedKitUI/CommandResponseViewController.swift index 979e96957..5c2352f46 100644 --- a/MinimedKitUI/CommandResponseViewController.swift +++ b/MinimedKitUI/CommandResponseViewController.swift @@ -16,7 +16,7 @@ import RileyLinkBLEKit extension CommandResponseViewController { typealias T = CommandResponseViewController - private static let successText = NSLocalizedString("Succeeded", comment: "A message indicating a command succeeded") + private static let successText = LocalizedString("Succeeded", comment: "A message indicating a command succeeded") static func changeTime(ops: PumpOps?, device: RileyLinkDevice) -> T { return T { (completionHandler) -> String in @@ -34,7 +34,7 @@ extension CommandResponseViewController { } } - return NSLocalizedString("Changing time…", comment: "Progress message for changing pump time.") + return LocalizedString("Changing time…", comment: "Progress message for changing pump time.") } } @@ -58,7 +58,7 @@ extension CommandResponseViewController { } } - return NSLocalizedString("Changing time…", comment: "Progress message for changing pump time.") + return LocalizedString("Changing time…", comment: "Progress message for changing pump time.") } } @@ -72,7 +72,7 @@ extension CommandResponseViewController { }) } - return NSLocalizedString("Discovering commands…", comment: "Progress message for discovering commands.") + return LocalizedString("Discovering commands…", comment: "Progress message for discovering commands.") } } @@ -92,7 +92,7 @@ extension CommandResponseViewController { } } - return NSLocalizedString("Get Statistics…", comment: "Progress message for getting statistics.") + return LocalizedString("Get Statistics…", comment: "Progress message for getting statistics.") } } @@ -121,7 +121,7 @@ extension CommandResponseViewController { } } - return NSLocalizedString("Fetching history…", comment: "Progress message for fetching pump history.") + return LocalizedString("Fetching history…", comment: "Progress message for fetching pump history.") } } @@ -149,7 +149,7 @@ extension CommandResponseViewController { } } - return NSLocalizedString("Fetching glucose…", comment: "Progress message for fetching pump glucose.") + return LocalizedString("Fetching glucose…", comment: "Progress message for fetching pump glucose.") } } @@ -169,7 +169,7 @@ extension CommandResponseViewController { } } - return NSLocalizedString("Fetching pump model…", comment: "Progress message for fetching pump model.") + return LocalizedString("Fetching pump model…", comment: "Progress message for fetching pump model.") } } @@ -193,7 +193,7 @@ extension CommandResponseViewController { } } - return NSLocalizedString( + return LocalizedString( "On your pump, go to the Find Device screen and select \"Find Device\"." + "\n" + "\nMain Menu >" + @@ -223,7 +223,7 @@ extension CommandResponseViewController { } } - return NSLocalizedString("Sending button press…", comment: "Progress message for sending button press to pump.") + return LocalizedString("Sending button press…", comment: "Progress message for sending button press to pump.") } } @@ -233,7 +233,7 @@ extension CommandResponseViewController { let response: String do { let schedule = try session.getBasalSchedule(for: .profileB) - var str = String(format: NSLocalizedString("%1$@ basal schedule entries\n", comment: "The format string describing number of basal schedule entries: (1: number of entries)"), integerFormatter.string(from: NSNumber(value: schedule?.entries.count ?? 0))!) + var str = String(format: LocalizedString("%1$@ basal schedule entries\n", comment: "The format string describing number of basal schedule entries: (1: number of entries)"), integerFormatter.string(from: NSNumber(value: schedule?.entries.count ?? 0))!) for entry in schedule?.entries ?? [] { str += "\(String(describing: entry))\n" } @@ -247,7 +247,7 @@ extension CommandResponseViewController { } } - return NSLocalizedString("Reading basal schedule…", comment: "Progress message for reading basal schedule") + return LocalizedString("Reading basal schedule…", comment: "Progress message for reading basal schedule") } } @@ -268,7 +268,7 @@ extension CommandResponseViewController { } } - return NSLocalizedString("Enabled Diagnostic LEDs", comment: "Progress message for enabling diagnostic LEDs") + return LocalizedString("Enabled Diagnostic LEDs", comment: "Progress message for enabling diagnostic LEDs") } } @@ -279,10 +279,10 @@ extension CommandResponseViewController { do { let status = try session.getCurrentPumpStatus() - var str = String(format: NSLocalizedString("%1$@ Units of insulin remaining\n", comment: "The format string describing units of insulin remaining: (1: number of units)"), measurementFormatter.numberFormatter.string(from: NSNumber(value: status.reservoir))!) - str += String(format: NSLocalizedString("Battery: %1$@ volts\n", comment: "The format string describing pump battery voltage: (1: battery voltage)"), measurementFormatter.string(from: status.batteryVolts)) - str += String(format: NSLocalizedString("Suspended: %1$@\n", comment: "The format string describing pump suspended state: (1: suspended)"), String(describing: status.suspended)) - str += String(format: NSLocalizedString("Bolusing: %1$@\n", comment: "The format string describing pump bolusing state: (1: bolusing)"), String(describing: status.bolusing)) + var str = String(format: LocalizedString("%1$@ Units of insulin remaining\n", comment: "The format string describing units of insulin remaining: (1: number of units)"), measurementFormatter.numberFormatter.string(from: NSNumber(value: status.reservoir))!) + str += String(format: LocalizedString("Battery: %1$@ volts\n", comment: "The format string describing pump battery voltage: (1: battery voltage)"), measurementFormatter.string(from: status.batteryVolts)) + str += String(format: LocalizedString("Suspended: %1$@\n", comment: "The format string describing pump suspended state: (1: suspended)"), String(describing: status.suspended)) + str += String(format: LocalizedString("Bolusing: %1$@\n", comment: "The format string describing pump bolusing state: (1: bolusing)"), String(describing: status.bolusing)) response = str } catch let error { response = String(describing: error) @@ -293,7 +293,7 @@ extension CommandResponseViewController { } } - return NSLocalizedString("Reading pump status…", comment: "Progress message for reading pump status") + return LocalizedString("Reading pump status…", comment: "Progress message for reading pump status") } } @@ -318,10 +318,10 @@ extension CommandResponseViewController { var resultDict: [String: Any] = [:] let intFormatter = NumberFormatter() - let formatString = NSLocalizedString("%1$@ %2$@/%3$@ %4$@", comment: "The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI)") + let formatString = LocalizedString("%1$@ %2$@/%3$@ %4$@", comment: "The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI)") - resultDict[NSLocalizedString("Best Frequency", comment: "The label indicating the best radio frequency")] = measurementFormatter.string(from: scanResult.bestFrequency) - resultDict[NSLocalizedString("Trials", comment: "The label indicating the results of each frequency trial")] = scanResult.trials.map({ (trial) -> String in + resultDict[LocalizedString("Best Frequency", comment: "The label indicating the best radio frequency")] = measurementFormatter.string(from: scanResult.bestFrequency) + resultDict[LocalizedString("Trials", comment: "The label indicating the results of each frequency trial")] = scanResult.trials.map({ (trial) -> String in return String( format: formatString, @@ -337,7 +337,7 @@ extension CommandResponseViewController { if let data = try? JSONSerialization.data(withJSONObject: resultDict, options: .prettyPrinted), let string = String(data: data, encoding: .utf8) { responseText = string } else { - responseText = NSLocalizedString("No response", comment: "Message display when no response from tuning pump") + responseText = LocalizedString("No response", comment: "Message display when no response from tuning pump") } response = responseText @@ -350,7 +350,7 @@ extension CommandResponseViewController { } } - return NSLocalizedString("Tuning radio…", comment: "Progress message for tuning radio") + return LocalizedString("Tuning radio…", comment: "Progress message for tuning radio") } } } diff --git a/MinimedKitUI/MinimedPumpManager+UI.swift b/MinimedKitUI/MinimedPumpManager+UI.swift index 071ef41ed..da9ccb9f5 100644 --- a/MinimedKitUI/MinimedPumpManager+UI.swift +++ b/MinimedKitUI/MinimedPumpManager+UI.swift @@ -54,7 +54,7 @@ extension MinimedPumpManager { } public func syncButtonTitle(for viewController: DeliveryLimitSettingsTableViewController) -> String { - return NSLocalizedString("Save to Pump…", comment: "Title of button to save delivery limit settings to pump") + return LocalizedString("Save to Pump…", comment: "Title of button to save delivery limit settings to pump") } public func syncButtonDetailText(for viewController: DeliveryLimitSettingsTableViewController) -> String? { @@ -89,7 +89,7 @@ extension MinimedPumpManager { } public func syncButtonTitle(for viewController: SingleValueScheduleTableViewController) -> String { - return NSLocalizedString("Save to Pump…", comment: "Title of button to save basal profile to pump") + return LocalizedString("Save to Pump…", comment: "Title of button to save basal profile to pump") } public func syncButtonDetailText(for viewController: SingleValueScheduleTableViewController) -> String? { diff --git a/MinimedKitUI/MinimedPumpSettingsViewController.swift b/MinimedKitUI/MinimedPumpSettingsViewController.swift index b8f8474a0..f895ccd70 100644 --- a/MinimedKitUI/MinimedPumpSettingsViewController.swift +++ b/MinimedKitUI/MinimedPumpSettingsViewController.swift @@ -27,7 +27,7 @@ class MinimedPumpSettingsViewController: RileyLinkSettingsViewController { override func viewDidLoad() { super.viewDidLoad() - title = NSLocalizedString("Pump Settings", comment: "Title of the pump settings view controller") + title = LocalizedString("Pump Settings", comment: "Title of the pump settings view controller") tableView.rowHeight = UITableViewAutomaticDimension tableView.estimatedRowHeight = 44 @@ -105,7 +105,7 @@ class MinimedPumpSettingsViewController: RileyLinkSettingsViewController { case .info: return nil case .settings: - return NSLocalizedString("Configuration", comment: "The title of the configuration section in settings") + return LocalizedString("Configuration", comment: "The title of the configuration section in settings") case .rileyLinks: return super.tableView(tableView, titleForHeaderInSection: section) case .delete: @@ -128,12 +128,12 @@ class MinimedPumpSettingsViewController: RileyLinkSettingsViewController { switch InfoRow(rawValue: indexPath.row)! { case .pumpID: let cell = tableView.dequeueReusableCell(withIdentifier: SettingsTableViewCell.className, for: indexPath) - cell.textLabel?.text = NSLocalizedString("Pump ID", comment: "The title text for the pump ID config value") + cell.textLabel?.text = LocalizedString("Pump ID", comment: "The title text for the pump ID config value") cell.detailTextLabel?.text = pumpManager.state.pumpID return cell case .pumpModel: let cell = tableView.dequeueReusableCell(withIdentifier: SettingsTableViewCell.className, for: indexPath) - cell.textLabel?.text = NSLocalizedString("Pump Model", comment: "The title of the cell showing the pump model number") + cell.textLabel?.text = LocalizedString("Pump Model", comment: "The title of the cell showing the pump model number") cell.detailTextLabel?.text = String(describing: pumpManager.state.pumpModel) return cell } @@ -142,13 +142,13 @@ class MinimedPumpSettingsViewController: RileyLinkSettingsViewController { switch SettingsRow(rawValue: indexPath.row)! { case .batteryChemistry: - cell.textLabel?.text = NSLocalizedString("Pump Battery Type", comment: "The title text for the battery type value") + cell.textLabel?.text = LocalizedString("Pump Battery Type", comment: "The title text for the battery type value") cell.detailTextLabel?.text = String(describing: pumpManager.batteryChemistry) case .preferredInsulinDataSource: - cell.textLabel?.text = NSLocalizedString("Preferred Data Source", comment: "The title text for the preferred insulin data source config") + cell.textLabel?.text = LocalizedString("Preferred Data Source", comment: "The title text for the preferred insulin data source config") cell.detailTextLabel?.text = String(describing: pumpManager.preferredInsulinDataSource) case .timeZoneOffset: - cell.textLabel?.text = NSLocalizedString("Change Time Zone", comment: "The title of the command to change pump time zone") + cell.textLabel?.text = LocalizedString("Change Time Zone", comment: "The title of the command to change pump time zone") let localTimeZone = TimeZone.current let localTimeZoneName = localTimeZone.abbreviation() ?? localTimeZone.identifier @@ -158,7 +158,7 @@ class MinimedPumpSettingsViewController: RileyLinkSettingsViewController { formatter.allowedUnits = [.hour, .minute] let diffString = timeZoneDiff != 0 ? formatter.string(from: abs(timeZoneDiff)) ?? String(abs(timeZoneDiff)) : "" - cell.detailTextLabel?.text = String(format: NSLocalizedString("%1$@%2$@%3$@", comment: "The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00)"), localTimeZoneName, timeZoneDiff != 0 ? (timeZoneDiff < 0 ? "-" : "+") : "", diffString) + cell.detailTextLabel?.text = String(format: LocalizedString("%1$@%2$@%3$@", comment: "The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00)"), localTimeZoneName, timeZoneDiff != 0 ? (timeZoneDiff < 0 ? "-" : "+") : "", diffString) } cell.accessoryType = .disclosureIndicator @@ -168,7 +168,7 @@ class MinimedPumpSettingsViewController: RileyLinkSettingsViewController { case .delete: let cell = tableView.dequeueReusableCell(withIdentifier: TextButtonTableViewCell.className, for: indexPath) as! TextButtonTableViewCell - cell.textLabel?.text = NSLocalizedString("Delete Pump", comment: "Title text for the button to remove a pump from Loop") + cell.textLabel?.text = LocalizedString("Delete Pump", comment: "Title text for the button to remove a pump from Loop") cell.textLabel?.textAlignment = .center cell.tintColor = .deleteColor cell.isEnabled = true @@ -294,19 +294,19 @@ private extension UIAlertController { convenience init(pumpDeletionHandler handler: @escaping () -> Void) { self.init( title: nil, - message: NSLocalizedString("Are you sure you want to delete this pump?", comment: "Confirmation message for deleting a pump"), + message: LocalizedString("Are you sure you want to delete this pump?", comment: "Confirmation message for deleting a pump"), preferredStyle: .actionSheet ) addAction(UIAlertAction( - title: NSLocalizedString("Delete Pump", comment: "Button title to delete pump"), + title: LocalizedString("Delete Pump", comment: "Button title to delete pump"), style: .destructive, handler: { (_) in handler() } )) - let cancel = NSLocalizedString("Cancel", comment: "The title of the cancel action in an action sheet") + let cancel = LocalizedString("Cancel", comment: "The title of the cancel action in an action sheet") addAction(UIAlertAction(title: cancel, style: .cancel, handler: nil)) } } diff --git a/MinimedKitUI/RadioSelectionTableViewController.swift b/MinimedKitUI/RadioSelectionTableViewController.swift index 754541a8b..098734861 100644 --- a/MinimedKitUI/RadioSelectionTableViewController.swift +++ b/MinimedKitUI/RadioSelectionTableViewController.swift @@ -19,7 +19,7 @@ extension RadioSelectionTableViewController: IdentifiableClass { vc.selectedIndex = value.rawValue vc.options = (0..<2).compactMap({ InsulinDataSource(rawValue: $0) }).map { String(describing: $0) } - vc.contextHelp = NSLocalizedString("Insulin delivery can be determined from the pump by either interpreting the event history or comparing the reservoir volume over time. Reading event history allows for a more accurate status graph and uploading up-to-date treatment data to Nightscout, at the cost of faster pump battery drain and the possibility of a higher radio error rate compared to reading only reservoir volume. If the selected source cannot be used for any reason, the system will attempt to fall back to the other option.", comment: "Instructions on selecting an insulin data source") + vc.contextHelp = LocalizedString("Insulin delivery can be determined from the pump by either interpreting the event history or comparing the reservoir volume over time. Reading event history allows for a more accurate status graph and uploading up-to-date treatment data to Nightscout, at the cost of faster pump battery drain and the possibility of a higher radio error rate compared to reading only reservoir volume. If the selected source cannot be used for any reason, the system will attempt to fall back to the other option.", comment: "Instructions on selecting an insulin data source") return vc } @@ -29,7 +29,7 @@ extension RadioSelectionTableViewController: IdentifiableClass { vc.selectedIndex = value.rawValue vc.options = (0..<2).compactMap({ BatteryChemistryType(rawValue: $0) }).map { String(describing: $0) } - vc.contextHelp = NSLocalizedString("Alkaline and Lithium batteries decay at differing rates. Alkaline tend to have a linear voltage drop over time whereas lithium cell batteries tend to maintain voltage until halfway through their lifespan. Under normal usage in a Non-MySentry compatible Minimed (x22/x15) insulin pump running Loop, Alkaline batteries last approximately 4 to 5 days. Lithium batteries last between 1-2 weeks. This selection will use different battery voltage decay rates for each of the battery chemistry types and alert the user when a battery is approximately 8 to 10 hours from failure.", comment: "Instructions on selecting battery chemistry type") + vc.contextHelp = LocalizedString("Alkaline and Lithium batteries decay at differing rates. Alkaline tend to have a linear voltage drop over time whereas lithium cell batteries tend to maintain voltage until halfway through their lifespan. Under normal usage in a Non-MySentry compatible Minimed (x22/x15) insulin pump running Loop, Alkaline batteries last approximately 4 to 5 days. Lithium batteries last between 1-2 weeks. This selection will use different battery voltage decay rates for each of the battery chemistry types and alert the user when a battery is approximately 8 to 10 hours from failure.", comment: "Instructions on selecting battery chemistry type") return vc } diff --git a/MinimedKitUI/RileyLinkMinimedDeviceTableViewController.swift b/MinimedKitUI/RileyLinkMinimedDeviceTableViewController.swift index ff0325be3..1365708c2 100644 --- a/MinimedKitUI/RileyLinkMinimedDeviceTableViewController.swift +++ b/MinimedKitUI/RileyLinkMinimedDeviceTableViewController.swift @@ -278,30 +278,30 @@ public class RileyLinkMinimedDeviceTableViewController: UITableViewController { case .device: switch DeviceRow(rawValue: indexPath.row)! { case .customName: - cell.textLabel?.text = NSLocalizedString("Name", comment: "The title of the cell showing device name") + cell.textLabel?.text = LocalizedString("Name", comment: "The title of the cell showing device name") cell.detailTextLabel?.text = device.name cell.accessoryType = .disclosureIndicator case .version: - cell.textLabel?.text = NSLocalizedString("Firmware", comment: "The title of the cell showing firmware version") + cell.textLabel?.text = LocalizedString("Firmware", comment: "The title of the cell showing firmware version") cell.detailTextLabel?.text = firmwareVersion case .connection: - cell.textLabel?.text = NSLocalizedString("Connection State", comment: "The title of the cell showing BLE connection state") + cell.textLabel?.text = LocalizedString("Connection State", comment: "The title of the cell showing BLE connection state") cell.detailTextLabel?.text = device.peripheralState.description case .rssi: - cell.textLabel?.text = NSLocalizedString("Signal Strength", comment: "The title of the cell showing BLE signal strength (RSSI)") + cell.textLabel?.text = LocalizedString("Signal Strength", comment: "The title of the cell showing BLE signal strength (RSSI)") cell.setDetailRSSI(bleRSSI, formatter: integerFormatter) case .idleStatus: - cell.textLabel?.text = NSLocalizedString("On Idle", comment: "The title of the cell showing the last idle") + cell.textLabel?.text = LocalizedString("On Idle", comment: "The title of the cell showing the last idle") cell.setDetailDate(lastIdle, formatter: dateFormatter) } case .pump: switch PumpRow(rawValue: indexPath.row)! { case .id: - cell.textLabel?.text = NSLocalizedString("Pump ID", comment: "The title of the cell showing pump ID") + cell.textLabel?.text = LocalizedString("Pump ID", comment: "The title of the cell showing pump ID") cell.detailTextLabel?.text = ops.pumpSettings.pumpID case .model: - cell.textLabel?.text = NSLocalizedString("Pump Model", comment: "The title of the cell showing the pump model number") + cell.textLabel?.text = LocalizedString("Pump Model", comment: "The title of the cell showing the pump model number") cell.setPumpModel(pumpState?.pumpModel) case .awake: cell.setAwakeUntil(pumpState?.awakeUntil, formatter: dateFormatter) @@ -317,11 +317,11 @@ public class RileyLinkMinimedDeviceTableViewController: UITableViewController { cell.textLabel?.text = measurementFormatter.string(from: frequency) cell.setDetailDate(date, formatter: dateFormatter) default: - cell.textLabel?.text = NSLocalizedString("Tune Radio Frequency", comment: "The title of the command to re-tune the radio") + cell.textLabel?.text = LocalizedString("Tune Radio Frequency", comment: "The title of the command to re-tune the radio") } case .changeTime: - cell.textLabel?.text = NSLocalizedString("Change Time", comment: "The title of the command to change pump time") + cell.textLabel?.text = LocalizedString("Change Time", comment: "The title of the command to change pump time") let localTimeZone = TimeZone.current let localTimeZoneName = localTimeZone.abbreviation() ?? localTimeZone.identifier @@ -332,39 +332,39 @@ public class RileyLinkMinimedDeviceTableViewController: UITableViewController { formatter.allowedUnits = [.hour, .minute] let diffString = timeZoneDiff != 0 ? formatter.string(from: abs(timeZoneDiff)) ?? String(abs(timeZoneDiff)) : "" - cell.detailTextLabel?.text = String(format: NSLocalizedString("%1$@%2$@%3$@", comment: "The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00)"), localTimeZoneName, timeZoneDiff != 0 ? (timeZoneDiff < 0 ? "-" : "+") : "", diffString) + cell.detailTextLabel?.text = String(format: LocalizedString("%1$@%2$@%3$@", comment: "The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00)"), localTimeZoneName, timeZoneDiff != 0 ? (timeZoneDiff < 0 ? "-" : "+") : "", diffString) } else { cell.detailTextLabel?.text = localTimeZoneName } case .mySentryPair: - cell.textLabel?.text = NSLocalizedString("MySentry Pair", comment: "The title of the command to pair with mysentry") + cell.textLabel?.text = LocalizedString("MySentry Pair", comment: "The title of the command to pair with mysentry") case .dumpHistory: - cell.textLabel?.text = NSLocalizedString("Fetch Recent History", comment: "The title of the command to fetch recent history") + cell.textLabel?.text = LocalizedString("Fetch Recent History", comment: "The title of the command to fetch recent history") case .fetchGlucose: - cell.textLabel?.text = NSLocalizedString("Fetch Enlite Glucose", comment: "The title of the command to fetch recent glucose") + cell.textLabel?.text = LocalizedString("Fetch Enlite Glucose", comment: "The title of the command to fetch recent glucose") case .getPumpModel: - cell.textLabel?.text = NSLocalizedString("Get Pump Model", comment: "The title of the command to get pump model") + cell.textLabel?.text = LocalizedString("Get Pump Model", comment: "The title of the command to get pump model") case .pressDownButton: - cell.textLabel?.text = NSLocalizedString("Send Button Press", comment: "The title of the command to send a button press") + cell.textLabel?.text = LocalizedString("Send Button Press", comment: "The title of the command to send a button press") case .readPumpStatus: - cell.textLabel?.text = NSLocalizedString("Read Pump Status", comment: "The title of the command to read pump status") + cell.textLabel?.text = LocalizedString("Read Pump Status", comment: "The title of the command to read pump status") case .readBasalSchedule: - cell.textLabel?.text = NSLocalizedString("Read Basal Schedule", comment: "The title of the command to read basal schedule") + cell.textLabel?.text = LocalizedString("Read Basal Schedule", comment: "The title of the command to read basal schedule") case .enableLED: - cell.textLabel?.text = NSLocalizedString("Enable Diagnostic LEDs", comment: "The title of the command to enable diagnostic LEDs") + cell.textLabel?.text = LocalizedString("Enable Diagnostic LEDs", comment: "The title of the command to enable diagnostic LEDs") case .discoverCommands: - cell.textLabel?.text = NSLocalizedString("Discover Commands", comment: "The title of the command to discover commands") + cell.textLabel?.text = LocalizedString("Discover Commands", comment: "The title of the command to discover commands") case .getStatistics: - cell.textLabel?.text = NSLocalizedString("RileyLink Statistics", comment: "The title of the command to fetch RileyLink statistics") + cell.textLabel?.text = LocalizedString("RileyLink Statistics", comment: "The title of the command to fetch RileyLink statistics") } } @@ -374,11 +374,11 @@ public class RileyLinkMinimedDeviceTableViewController: UITableViewController { public override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { switch Section(rawValue: section)! { case .device: - return NSLocalizedString("Device", comment: "The title of the section describing the device") + return LocalizedString("Device", comment: "The title of the section describing the device") case .pump: - return NSLocalizedString("Pump", comment: "The title of the section describing the pump") + return LocalizedString("Pump", comment: "The title of the section describing the pump") case .commands: - return NSLocalizedString("Commands", comment: "The title of the section describing commands") + return LocalizedString("Commands", comment: "The title of the section describing commands") } } @@ -499,13 +499,13 @@ private extension UITableViewCell { func setAwakeUntil(_ awakeUntil: Date?, formatter: DateFormatter) { switch awakeUntil { case let until? where until.timeIntervalSinceNow < 0: - textLabel?.text = NSLocalizedString("Last Awake", comment: "The title of the cell describing an awake radio") + textLabel?.text = LocalizedString("Last Awake", comment: "The title of the cell describing an awake radio") setDetailDate(until, formatter: formatter) case let until?: - textLabel?.text = NSLocalizedString("Awake Until", comment: "The title of the cell describing an awake radio") + textLabel?.text = LocalizedString("Awake Until", comment: "The title of the cell describing an awake radio") setDetailDate(until, formatter: formatter) default: - textLabel?.text = NSLocalizedString("Listening Off", comment: "The title of the cell describing no radio awake data") + textLabel?.text = LocalizedString("Listening Off", comment: "The title of the cell describing no radio awake data") detailTextLabel?.text = nil } } @@ -514,7 +514,7 @@ private extension UITableViewCell { if let pumpModel = pumpModel { detailTextLabel?.text = String(describing: pumpModel) } else { - detailTextLabel?.text = NSLocalizedString("Unknown", comment: "The detail text for an unknown pump model") + detailTextLabel?.text = LocalizedString("Unknown", comment: "The detail text for an unknown pump model") } } } diff --git a/MinimedKitUI/Setup/MinimedPumpIDSetupViewController.swift b/MinimedKitUI/Setup/MinimedPumpIDSetupViewController.swift index f29034ee5..142186749 100644 --- a/MinimedKitUI/Setup/MinimedPumpIDSetupViewController.swift +++ b/MinimedKitUI/Setup/MinimedPumpIDSetupViewController.swift @@ -434,6 +434,6 @@ class RegionAndColorPickerTableViewCell: UITableViewCell { private extension SetupButton { func setConnectTitle() { - setTitle(NSLocalizedString("Connect", comment: "Button title to connect to pump during setup"), for: .normal) + setTitle(LocalizedString("Connect", comment: "Button title to connect to pump during setup"), for: .normal) } } diff --git a/MinimedKitUI/Setup/MinimedPumpSentrySetupViewController.swift b/MinimedKitUI/Setup/MinimedPumpSentrySetupViewController.swift index e13a71c95..52cdb68e6 100644 --- a/MinimedKitUI/Setup/MinimedPumpSentrySetupViewController.swift +++ b/MinimedKitUI/Setup/MinimedPumpSentrySetupViewController.swift @@ -61,7 +61,7 @@ class MinimedPumpSentrySetupViewController: SetupTableViewController { case .notStarted: footerView.primaryButton.isEnabled = true activityIndicator.state = .hidden - footerView.primaryButton.setTitle(NSLocalizedString("Retry", comment: "Button title to retry sentry setup"), for: .normal) + footerView.primaryButton.setTitle(LocalizedString("Retry", comment: "Button title to retry sentry setup"), for: .normal) case .listening: lastError = nil activityIndicator.state = .loading diff --git a/MinimedKitUI/Setup/MinimedPumpSettingsSetupViewController.swift b/MinimedKitUI/Setup/MinimedPumpSettingsSetupViewController.swift index b6898e0e9..da4465acb 100644 --- a/MinimedKitUI/Setup/MinimedPumpSettingsSetupViewController.swift +++ b/MinimedKitUI/Setup/MinimedPumpSettingsSetupViewController.swift @@ -79,7 +79,7 @@ class MinimedPumpSettingsSetupViewController: SetupTableViewController { switch ConfigurationRow(rawValue: indexPath.row)! { case .basalRates: - cell.textLabel?.text = NSLocalizedString("Basal Rates", comment: "The title text for the basal rate schedule") + cell.textLabel?.text = LocalizedString("Basal Rates", comment: "The title text for the basal rate schedule") if let basalRateSchedule = setupViewController?.basalSchedule { let unit = HKUnit.internationalUnit() @@ -89,7 +89,7 @@ class MinimedPumpSettingsSetupViewController: SetupTableViewController { cell.detailTextLabel?.text = SettingsTableViewCell.TapToSetString } case .deliveryLimits: - cell.textLabel?.text = NSLocalizedString("Delivery Limits", comment: "Title text for delivery limits") + cell.textLabel?.text = LocalizedString("Delivery Limits", comment: "Title text for delivery limits") if setupViewController?.maxBolusUnits == nil || setupViewController?.maxBasalRateUnitsPerHour == nil { cell.detailTextLabel?.text = SettingsTableViewCell.TapToSetString diff --git a/MinimedKitUI/de.lproj/InfoPlist.strings b/MinimedKitUI/de.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKitUI/de.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKitUI/de.lproj/Localizable.strings b/MinimedKitUI/de.lproj/Localizable.strings new file mode 100644 index 000000000..2f50eec3d --- /dev/null +++ b/MinimedKitUI/de.lproj/Localizable.strings @@ -0,0 +1,195 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ +"%1$@ %2$@/%3$@ %4$@" = "%1$@ %2$@/%3$@ %4$@"; + +/* The format string describing number of basal schedule entries: (1: number of entries) */ +"%1$@ basal schedule entries\n" = "%1$@ basale Zeitplaneinträge\n"; + +/* The format string describing units of insulin remaining: (1: number of units) */ +"%1$@ Units of insulin remaining\n" = "%1$@ Insulineinheiten verbleiben\n"; + +/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ +"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; + +/* Instructions on selecting battery chemistry type */ +"Alkaline and Lithium batteries decay at differing rates. Alkaline tend to have a linear voltage drop over time whereas lithium cell batteries tend to maintain voltage until halfway through their lifespan. Under normal usage in a Non-MySentry compatible Minimed (x22/x15) insulin pump running Loop, Alkaline batteries last approximately 4 to 5 days. Lithium batteries last between 1-2 weeks. This selection will use different battery voltage decay rates for each of the battery chemistry types and alert the user when a battery is approximately 8 to 10 hours from failure." = "Alkali- und Lithiumbatterien zerfallen unterschiedlich schnell. Alkaline neigen dazu, einen linearen Spannungsabfall im Laufe der Zeit zu haben, während Lithium-Zellen-Batterien neigen dazu, die Spannung bis zur Hälfte ihrer Lebensdauer beizubehalten. Bei normaler Verwendung in einer Nicht-MySentry-kompatiblen Minimed (x22 / x15) Insulinpumpe, die Loop läuft, halten Alkali-Batterien etwa 4 bis 5 Tage. Lithium-Batterien halten zwischen 1-2 Wochen. Diese Auswahl verwendet unterschiedliche Batteriespannungs-Abnahmeraten für jeden der Batteriechemietypen und warnt den Benutzer, wenn eine Batterie ungefähr 8 bis 10 Stunden nach einem Fehler liegt."; + +/* Confirmation message for deleting a pump */ +"Are you sure you want to delete this pump?" = "Sind Sie sicher dass sie diese Pumpe loeschen wollen?"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Aktiv bis"; + +/* The title text for the basal rate schedule */ +"Basal Rates" = "Basalraten"; + +/* The format string describing pump battery voltage: (1: battery voltage) */ +"Battery: %1$@ volts\n" = "Batterie: %1$@ Volt\n"; + +/* The label indicating the best radio frequency */ +"Best Frequency" = "Beste Frequenz"; + +/* The format string describing pump bolusing state: (1: bolusing) */ +"Bolusing: %1$@\n" = "Bolusing: %1$@\n"; + +/* The title of the cancel action in an action sheet */ +"Cancel" = "Abbrechen"; + +/* The title of the command to change pump time */ +"Change Time" = "Zeit ändern"; + +/* The title of the command to change pump time zone */ +"Change Time Zone" = "Zeitzone Aendern"; + +/* Progress message for changing pump time. */ +"Changing time…" = "Zeit ändern…"; + +/* The title of the section describing commands */ +"Commands" = "Befehle"; + +/* The title of the configuration section in settings */ +"Configuration" = "Konfiguration"; + +/* Button title to connect to pump during setup */ +"Connect" = "Verbinden"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Verbindungsstatus"; + +/* Button title to delete pump + Title text for the button to remove a pump from Loop */ +"Delete Pump" = "Pumpe loeschen"; + +/* Title text for delivery limits */ +"Delivery Limits" = "Insulin Abgabelimits"; + +/* The title of the section describing the device */ +"Device" = "Gerät"; + +/* The title of the command to discover commands */ +"Discover Commands" = "Befehle entdecken"; + +/* Progress message for discovering commands. */ +"Discovering commands…" = "Befehle werden entdeckt…"; + +/* The title of the command to enable diagnostic LEDs */ +"Enable Diagnostic LEDs" = "Diagnostische LEDs Aktivieren"; + +/* Progress message for enabling diagnostic LEDs */ +"Enabled Diagnostic LEDs" = "Diagnostische LEDs aktiviert"; + +/* The title of the command to fetch recent glucose */ +"Fetch Enlite Glucose" = "Fetch Enlite Glucose"; + +/* The title of the command to fetch recent history */ +"Fetch Recent History" = "Recuperar Historia Reciente"; + +/* Progress message for fetching pump glucose. */ +"Fetching glucose…" = "Recuperar glucosa…"; + +/* Progress message for fetching pump history. */ +"Fetching history…" = "Recuperar historial…"; + +/* Progress message for fetching pump model. */ +"Fetching pump model…" = "Recuperar modelo de microinfusora…"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Firmware"; + +/* The title of the command to get pump model */ +"Get Pump Model" = "Pumpmodell erhalten"; + +/* Progress message for getting statistics. */ +"Get Statistics…" = "Statistiken abrufen…"; + +/* Instructions on selecting an insulin data source */ +"Insulin delivery can be determined from the pump by either interpreting the event history or comparing the reservoir volume over time. Reading event history allows for a more accurate status graph and uploading up-to-date treatment data to Nightscout, at the cost of faster pump battery drain and the possibility of a higher radio error rate compared to reading only reservoir volume. If the selected source cannot be used for any reason, the system will attempt to fall back to the other option." = "Die Insulinabgabe kann von der Pumpe bestimmt werden, indem entweder die Ereignishistorie interpretiert wird oder das Reservoirvolumen über die Zeit verglichen wird. Das Lesen der Ereignishistorie ermöglicht eine genauere Statusgrafik und das Hochladen aktueller Behandlungsdaten in Nightscout, auf Kosten einer schnelleren Pumpenbatterieentleerung und der Möglichkeit einer höheren Funkfehlerrate im Vergleich zum Lesen des Reservoirvolumens. Wenn das ausgewählte Gerät aus irgendeinem Grund nicht verwendet werden kann, versucht das System, auf die andere Option zurückzugreifen."; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "Zuletzt aktiv"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Signal aus"; + +/* The title of the command to pair with mysentry */ +"MySentry Pair" = "Verbinden MySentry"; + +/* The title of the cell showing device name */ +"Name" = "Name"; + +/* Message display when no response from tuning pump */ +"No response" = "Keine Antwort"; + +/* The title of the cell showing the last idle */ +"On Idle" = "im Leerlauf"; + +/* The title text for the preferred insulin data source config */ +"Preferred Data Source" = "Bevorzugte Datenquelle"; + +/* The title of the section describing the pump */ +"Pump" = "Pumpe"; + +/* The title text for the battery type value */ +"Pump Battery Type" = "Typ Pumpenbatterie"; + +/* The title of the cell showing pump ID + The title text for the pump ID config value */ +"Pump ID" = "Pumpen-ID"; + +/* The title of the cell showing the pump model number */ +"Pump Model" = "Pumpenmodell"; + +/* Title of the pump settings view controller */ +"Pump Settings" = "Pumpeneinstellungen"; + +/* The title of the command to read basal schedule */ +"Read Basal Schedule" = "Basalzeitplan lesen"; + +/* The title of the command to read pump status */ +"Read Pump Status" = "Pumpenstatus lesen"; + +/* Progress message for reading basal schedule */ +"Reading basal schedule…" = "Basalzeitplan lesen…"; + +/* Progress message for reading pump status */ +"Reading pump status…" = "Pumpenstand lesen…"; + +/* Button title to retry sentry setup */ +"Retry" = "Wiederholen"; + +/* The title of the command to fetch RileyLink statistics */ +"RileyLink Statistics" = "RileyLink Statistik"; + +/* Title of button to save basal profile to pump + Title of button to save delivery limit settings to pump */ +"Save to Pump…" = "In der Pumpe abspeichern…"; + +/* The title of the command to send a button press */ +"Send Button Press" = "Sende Knopf drücken"; + +/* Progress message for sending button press to pump. */ +"Sending button press…" = "Senden der Taste drücken…"; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Signalstärke"; + +/* A message indicating a command succeeded */ +"Succeeded" = "Erfolgreich"; + +/* The format string describing pump suspended state: (1: suspended) */ +"Suspended: %1$@\n" = "Suspendiert: %1$@\n"; + +/* The label indicating the results of each frequency trial */ +"Trials" = "Versuche"; + +/* The title of the command to re-tune the radio */ +"Tune Radio Frequency" = "Stellen Sie die Radiofrequenz ein"; + +/* Progress message for tuning radio */ +"Tuning radio…" = "Radio abstimmen…"; + +/* The detail text for an unknown pump model */ +"Unknown" = "Unbekannt"; + diff --git a/MinimedKitUI/de.lproj/MinimedPumpManager.strings b/MinimedKitUI/de.lproj/MinimedPumpManager.strings new file mode 100644 index 000000000..012177982 --- /dev/null +++ b/MinimedKitUI/de.lproj/MinimedPumpManager.strings @@ -0,0 +1,72 @@ +/* Class = "UITableViewController"; title = "RileyLink Setup"; ObjectID = "0MV-2k-Dty"; */ +"0MV-2k-Dty.title" = "RileyLink Setup"; + +/* Class = "UILabel"; text = "Find Device"; ObjectID = "1fp-45-qWK"; */ +"1fp-45-qWK.text" = "Gerät finden"; + +/* Class = "UILabel"; text = "Other Devices"; ObjectID = "A6i-Cb-baR"; */ +"A6i-Cb-baR.text" = "Andere Geräte"; + +/* Class = "UILabel"; text = "Do not change the time using your pumpʼs menu."; ObjectID = "Bdb-j4-WcR"; */ +"Bdb-j4-WcR.text" = "Ändern Sie nicht die Zeit in Ihrem Pumpenmenü."; + +/* Class = "UILabel"; text = "Utilities"; ObjectID = "c7t-pZ-WqY"; */ +"c7t-pZ-WqY.text" = "Utilities"; + +/* Class = "UILabel"; text = "Connect Devices"; ObjectID = "erq-yb-anx"; */ +"erq-yb-anx.text" = "Connect Devices"; + +/* Class = "UITableViewController"; title = "Pump Clock"; ObjectID = "Fps-h3-V4K"; */ +"Fps-h3-V4K.title" = "Uhrzeit der Pumpe"; + +/* Class = "UITableViewSection"; footerTitle = "The pump ID is the 6-digit numerical portion of the serial number (labeled as SN or S/N)."; ObjectID = "fVG-pl-jT9"; */ +"fVG-pl-jT9.footerTitle" = "The pump ID is the 6-digit numerical portion of the serial number (labeled as SN or S/N)."; + +/* Class = "UITableViewSection"; headerTitle = "Pump ID"; ObjectID = "fVG-pl-jT9"; */ +"fVG-pl-jT9.headerTitle" = "Pump ID"; + +/* Class = "UILabel"; text = "Your pump is ready for use."; ObjectID = "g1m-3k-XI3"; */ +"g1m-3k-XI3.text" = "Your pump is ready for use."; + +/* Class = "UITextField"; placeholder = "Enter the 6-digit pump ID"; ObjectID = "HeG-VF-L5P"; */ +"HeG-VF-L5P.placeholder" = "Geben Sie die 6-stellige Pumpen-ID ein"; + +/* Class = "UILabel"; text = "Review your pump settings below. You can change these settings at any time in Loopʼs Settings screen."; ObjectID = "HfQ-fG-8vO"; */ +"HfQ-fG-8vO.text" = "Überprüfen Sie die unten stehenden Pumpeneinstellungen. Sie können diese Einstellungen jederzeit im Einstellungsmenü von Loop ändern."; + +/* Class = "UILabel"; text = "If you travel to a different time zone for an extended period of time, you can change the pumpʼs time zone at any time in Loopʼs Settings screen."; ObjectID = "HuY-fE-vM8"; */ +"HuY-fE-vM8.text" = "Wenn Sie für längere Zeit in eine andere Zeitzone verreisen, kann die Zeitzone der Pumpe jederzeit über das Einstellungsmenü von Loop geändert werden."; + +/* Class = "UILabel"; text = "Loop will keep your pumpʼs clock synchronized with your phone in the time zone youʼre in now."; ObjectID = "IQ5-53-x9s"; */ +"IQ5-53-x9s.text" = "Loop will keep your pumpʼs clock synchronized with your phone in the time zone youʼre in now."; + +/* Class = "UITableViewController"; title = "Pump Settings"; ObjectID = "iQZ-kT-QUm"; */ +"iQZ-kT-QUm.title" = "Pump Settings"; + +/* Class = "UITableViewSection"; footerTitle = "The pump region and color are denoted as the last 3 letters of the the model number (labeled as REF)."; ObjectID = "lGI-LD-xR7"; */ +"lGI-LD-xR7.footerTitle" = "The pump region and color are denoted as the last 3 letters of the the model number (labeled as REF)."; + +/* Class = "UITableViewSection"; headerTitle = "Region and Color"; ObjectID = "lGI-LD-xR7"; */ +"lGI-LD-xR7.headerTitle" = "Region and Color"; + +/* Class = "UITableViewController"; title = "Setup Complete"; ObjectID = "Nwf-TJ-KmJ"; */ +"Nwf-TJ-KmJ.title" = "Setup Complete"; + +/* Class = "UITableViewController"; title = "Pump Broadcasts"; ObjectID = "oBL-lh-SHI"; */ +"oBL-lh-SHI.title" = "Pump Broadcasts"; + +/* Class = "UILabel"; text = "On"; ObjectID = "ojQ-ob-gBx"; */ +"ojQ-ob-gBx.text" = "On"; + +/* Class = "UITableViewController"; title = "Pump Setup"; ObjectID = "OZk-Db-KCs"; */ +"OZk-Db-KCs.title" = "Pump Setup"; + +/* Class = "UILabel"; text = "Enter the pump region"; ObjectID = "tGa-FP-JqD"; */ +"tGa-FP-JqD.text" = "Enter the pump region"; + +/* Class = "UILabel"; text = "Loop will listen for status messages sent by your pump. Follow the steps below on your pump to enable these messages:"; ObjectID = "yLn-Ya-p1R"; */ +"yLn-Ya-p1R.text" = "Loop will listen for status messages sent by your pump. Follow the steps below on your pump to enable these messages:"; + +/* Class = "UITableViewSection"; headerTitle = "Main Menu"; ObjectID = "ZnF-zy-5gR"; */ +"ZnF-zy-5gR.headerTitle" = "Main Menu"; + diff --git a/MinimedKitUI/es.lproj/InfoPlist.strings b/MinimedKitUI/es.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKitUI/es.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKitUI/es.lproj/Localizable.strings b/MinimedKitUI/es.lproj/Localizable.strings new file mode 100644 index 000000000..3c551fa97 --- /dev/null +++ b/MinimedKitUI/es.lproj/Localizable.strings @@ -0,0 +1,195 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ +"%1$@ %2$@/%3$@ %4$@" = "%1$@ %2$@/%3$@ %4$@"; + +/* The format string describing number of basal schedule entries: (1: number of entries) */ +"%1$@ basal schedule entries\n" = "%1$@ entradas de configuración basal\n"; + +/* The format string describing units of insulin remaining: (1: number of units) */ +"%1$@ Units of insulin remaining\n" = "%1$@ Unidades de insulina restantes\n"; + +/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ +"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; + +/* Instructions on selecting battery chemistry type */ +"Alkaline and Lithium batteries decay at differing rates. Alkaline tend to have a linear voltage drop over time whereas lithium cell batteries tend to maintain voltage until halfway through their lifespan. Under normal usage in a Non-MySentry compatible Minimed (x22/x15) insulin pump running Loop, Alkaline batteries last approximately 4 to 5 days. Lithium batteries last between 1-2 weeks. This selection will use different battery voltage decay rates for each of the battery chemistry types and alert the user when a battery is approximately 8 to 10 hours from failure." = "Las baterías alcalinas y de litio se degradan en ritmos distintos. La alcalinas tienden a tener una baja de voltaje linear en el tiempo mientras que las de litio tienden a mantener un voltaje hasta que pasan la mitad de su tiempo de vida. Bajo condiciones normales en una micro-infusora no compatible con MySentry ( x22/x15) siendo utilizado con Loop, las baterías alcalinas durarán aproximadamente de 4 a 5 días. Las baterías de litio durarán de una a dos semanas. Esta selección utilizará diferentes rangos de decadencia para el voltaje de cada una de las bataerías y alertará al usuario cuando la batería tenga aproximadamente de 8 a 10 horas restantes de vida."; + +/* Confirmation message for deleting a pump */ +"Are you sure you want to delete this pump?" = "¿Estás seguro de querer eliminar esta microinfusora?"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Despierto hasta"; + +/* The title text for the basal rate schedule */ +"Basal Rates" = "Perfil Basal"; + +/* The format string describing pump battery voltage: (1: battery voltage) */ +"Battery: %1$@ volts\n" = "Batería: %1$@ voltios\n"; + +/* The label indicating the best radio frequency */ +"Best Frequency" = "Mejor frecuencia"; + +/* The format string describing pump bolusing state: (1: bolusing) */ +"Bolusing: %1$@\n" = "Bolo en progreso: %1$@\n"; + +/* The title of the cancel action in an action sheet */ +"Cancel" = "Cancelar"; + +/* The title of the command to change pump time */ +"Change Time" = "Cambiar Hora"; + +/* The title of the command to change pump time zone */ +"Change Time Zone" = "Cambiar Zona Horaria"; + +/* Progress message for changing pump time. */ +"Changing time…" = "Cambiando hora…"; + +/* The title of the section describing commands */ +"Commands" = "Comandos"; + +/* The title of the configuration section in settings */ +"Configuration" = "Configuración"; + +/* Button title to connect to pump during setup */ +"Connect" = "Conectar"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Estado de Conexión"; + +/* Button title to delete pump + Title text for the button to remove a pump from Loop */ +"Delete Pump" = "Eliminar Microinfusora"; + +/* Title text for delivery limits */ +"Delivery Limits" = "Límites de Dosificación"; + +/* The title of the section describing the device */ +"Device" = "Dispositivo"; + +/* The title of the command to discover commands */ +"Discover Commands" = "Descubrir Comandos"; + +/* Progress message for discovering commands. */ +"Discovering commands…" = "Descubriendo comandos…"; + +/* The title of the command to enable diagnostic LEDs */ +"Enable Diagnostic LEDs" = "Habilitar diagnóstico LEDs"; + +/* Progress message for enabling diagnostic LEDs */ +"Enabled Diagnostic LEDs" = "Diagnóstico LEDs Habilitado"; + +/* The title of the command to fetch recent glucose */ +"Fetch Enlite Glucose" = "Obtener Enlite Glucose"; + +/* The title of the command to fetch recent history */ +"Fetch Recent History" = "Obtener Historia Reciente"; + +/* Progress message for fetching pump glucose. */ +"Fetching glucose…" = "Obtener glucosa…"; + +/* Progress message for fetching pump history. */ +"Fetching history…" = "Obtener historial…"; + +/* Progress message for fetching pump model. */ +"Fetching pump model…" = "Obtener modelo de microinfusora…"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Firmware"; + +/* The title of the command to get pump model */ +"Get Pump Model" = "Obtener modelo de Microinfusora"; + +/* Progress message for getting statistics. */ +"Get Statistics…" = "Obtener Estadísticas…"; + +/* Instructions on selecting an insulin data source */ +"Insulin delivery can be determined from the pump by either interpreting the event history or comparing the reservoir volume over time. Reading event history allows for a more accurate status graph and uploading up-to-date treatment data to Nightscout, at the cost of faster pump battery drain and the possibility of a higher radio error rate compared to reading only reservoir volume. If the selected source cannot be used for any reason, the system will attempt to fall back to the other option." = "La entrega de insulina puede ser determinada por la microinfusora interpretando los eventos históricos o comparando el volúmen del reservorio sobre el tiempo. Leer los eventos históricos permite una gráfica de status mas exacta y permite subir tratamientos actualizados a Nightscout, con el costo de una menor duración de la batería y la posiblidad de mayores errores de radio comparado con leer solamente el volúmen del reservorio. Si la fuente seleccionada no puede ser utilizada por cualquier motivo, el sistema intentará utilizar la otra opción."; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "Último Despierto"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Escuchando Apagado"; + +/* The title of the command to pair with mysentry */ +"MySentry Pair" = "Junta de MySentry"; + +/* The title of the cell showing device name */ +"Name" = "Nombre"; + +/* Message display when no response from tuning pump */ +"No response" = "No respuesta"; + +/* The title of the cell showing the last idle */ +"On Idle" = "En Inactivo"; + +/* The title text for the preferred insulin data source config */ +"Preferred Data Source" = "Fuente de Datos Preferida"; + +/* The title of the section describing the pump */ +"Pump" = "Microinfusadora"; + +/* The title text for the battery type value */ +"Pump Battery Type" = "Tipo de batería de microinfusora"; + +/* The title of the cell showing pump ID + The title text for the pump ID config value */ +"Pump ID" = "ID de Microinfusadora"; + +/* The title of the cell showing the pump model number */ +"Pump Model" = "Modelo de Microinfusadora"; + +/* Title of the pump settings view controller */ +"Pump Settings" = "Configuración de Microinfusora"; + +/* The title of the command to read basal schedule */ +"Read Basal Schedule" = "Obtener prefil basal"; + +/* The title of the command to read pump status */ +"Read Pump Status" = "Obtener estada de microinfusadora"; + +/* Progress message for reading basal schedule */ +"Reading basal schedule…" = "Obteniendo perfil basal…"; + +/* Progress message for reading pump status */ +"Reading pump status…" = "Obteniendo estada de microinfusadora…"; + +/* Button title to retry sentry setup */ +"Retry" = "Reintentar"; + +/* The title of the command to fetch RileyLink statistics */ +"RileyLink Statistics" = "Estadísticas de RileyLink"; + +/* Title of button to save basal profile to pump + Title of button to save delivery limit settings to pump */ +"Save to Pump…" = "Guardar en Microinfusora…"; + +/* The title of the command to send a button press */ +"Send Button Press" = "Enviar presion de botón"; + +/* Progress message for sending button press to pump. */ +"Sending button press…" = "Enviando presion de botón…"; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Intensidad de señal"; + +/* A message indicating a command succeeded */ +"Succeeded" = "Éxito"; + +/* The format string describing pump suspended state: (1: suspended) */ +"Suspended: %1$@\n" = "Suspendido: %1$@\n"; + +/* The label indicating the results of each frequency trial */ +"Trials" = "Pruebas"; + +/* The title of the command to re-tune the radio */ +"Tune Radio Frequency" = "Sintonizar frecuencia de radio"; + +/* Progress message for tuning radio */ +"Tuning radio…" = "Sintonizando frecuencia de radio…"; + +/* The detail text for an unknown pump model */ +"Unknown" = "Desconocido"; + diff --git a/MinimedKitUI/es.lproj/MinimedPumpManager.strings b/MinimedKitUI/es.lproj/MinimedPumpManager.strings new file mode 100644 index 000000000..a062b7ae8 --- /dev/null +++ b/MinimedKitUI/es.lproj/MinimedPumpManager.strings @@ -0,0 +1,72 @@ +/* Class = "UITableViewController"; title = "RileyLink Setup"; ObjectID = "0MV-2k-Dty"; */ +"0MV-2k-Dty.title" = "Configuración de RileyLink"; + +/* Class = "UILabel"; text = "Find Device"; ObjectID = "1fp-45-qWK"; */ +"1fp-45-qWK.text" = "Encontrar Dispositivo"; + +/* Class = "UILabel"; text = "Other Devices"; ObjectID = "A6i-Cb-baR"; */ +"A6i-Cb-baR.text" = "Otros Dispositivos"; + +/* Class = "UILabel"; text = "Do not change the time using your pumpʼs menu."; ObjectID = "Bdb-j4-WcR"; */ +"Bdb-j4-WcR.text" = "No cambies la hora utilizando el menú de tu microinfusora."; + +/* Class = "UILabel"; text = "Utilities"; ObjectID = "c7t-pZ-WqY"; */ +"c7t-pZ-WqY.text" = "Utilidades"; + +/* Class = "UILabel"; text = "Connect Devices"; ObjectID = "erq-yb-anx"; */ +"erq-yb-anx.text" = "Conectar Dispositivos"; + +/* Class = "UITableViewController"; title = "Pump Clock"; ObjectID = "Fps-h3-V4K"; */ +"Fps-h3-V4K.title" = "Reloj de Microinfusora"; + +/* Class = "UITableViewSection"; footerTitle = "The pump ID is the 6-digit numerical portion of the serial number (labeled as SN or S/N)."; ObjectID = "fVG-pl-jT9"; */ +"fVG-pl-jT9.footerTitle" = "El número de ID de la microinfusora es la porción de 6 dígitos del número serial (indicados como SN o S/N)."; + +/* Class = "UITableViewSection"; headerTitle = "Pump ID"; ObjectID = "fVG-pl-jT9"; */ +"fVG-pl-jT9.headerTitle" = "ID de Microinfusora"; + +/* Class = "UILabel"; text = "Your pump is ready for use."; ObjectID = "g1m-3k-XI3"; */ +"g1m-3k-XI3.text" = "Tu microinfusora está lista para usarse."; + +/* Class = "UITextField"; placeholder = "Enter the 6-digit pump ID"; ObjectID = "HeG-VF-L5P"; */ +"HeG-VF-L5P.placeholder" = "Ingresa el número de ID de 6 dígitos de tu microinfusora"; + +/* Class = "UILabel"; text = "Review your pump settings below. You can change these settings at any time in Loopʼs Settings screen."; ObjectID = "HfQ-fG-8vO"; */ +"HfQ-fG-8vO.text" = "Revisa la configuración de tu microinfusora debajo. Puedes cambiar esta configuración en cualquier momento en la pantalla de Configuración de Loop."; + +/* Class = "UILabel"; text = "If you travel to a different time zone for an extended period of time, you can change the pumpʼs time zone at any time in Loopʼs Settings screen."; ObjectID = "HuY-fE-vM8"; */ +"HuY-fE-vM8.text" = "En caso de viajar a una zona horaria distinta por un periodo extendido de tiempo, podrás cambiar la zona horaria de la microinfusora en cualquier momento a través de la pantalla de Configuración de Loop."; + +/* Class = "UILabel"; text = "Loop will keep your pumpʼs clock synchronized with your phone in the time zone youʼre in now."; ObjectID = "IQ5-53-x9s"; */ +"IQ5-53-x9s.text" = "Loop mantendrá el reloj de tu microinfusora sincronizado con tu teléfono en la zona horaria en la que te encuentres ahora."; + +/* Class = "UITableViewController"; title = "Pump Settings"; ObjectID = "iQZ-kT-QUm"; */ +"iQZ-kT-QUm.title" = "Configuración de la Microinfusora"; + +/* Class = "UITableViewSection"; footerTitle = "The pump region and color are denoted as the last 3 letters of the the model number (labeled as REF)."; ObjectID = "lGI-LD-xR7"; */ +"lGI-LD-xR7.footerTitle" = "La región de la microinfusora y el color están indicados en las tres últimas letras del número de modelo (indicados como REF)."; + +/* Class = "UITableViewSection"; headerTitle = "Region and Color"; ObjectID = "lGI-LD-xR7"; */ +"lGI-LD-xR7.headerTitle" = "Región y Color"; + +/* Class = "UITableViewController"; title = "Setup Complete"; ObjectID = "Nwf-TJ-KmJ"; */ +"Nwf-TJ-KmJ.title" = "Configuración Completa"; + +/* Class = "UITableViewController"; title = "Pump Broadcasts"; ObjectID = "oBL-lh-SHI"; */ +"oBL-lh-SHI.title" = "Pump Broadcasts"; + +/* Class = "UILabel"; text = "On"; ObjectID = "ojQ-ob-gBx"; */ +"ojQ-ob-gBx.text" = "Encendido"; + +/* Class = "UITableViewController"; title = "Pump Setup"; ObjectID = "OZk-Db-KCs"; */ +"OZk-Db-KCs.title" = "Configuración de Microinfusora"; + +/* Class = "UILabel"; text = "Enter the pump region"; ObjectID = "tGa-FP-JqD"; */ +"tGa-FP-JqD.text" = "Ingresa la región de la Microinfusora"; + +/* Class = "UILabel"; text = "Loop will listen for status messages sent by your pump. Follow the steps below on your pump to enable these messages:"; ObjectID = "yLn-Ya-p1R"; */ +"yLn-Ya-p1R.text" = "Loop escuchará mensajes de estado enviados por tu microinfusora. Sigue los pasos enlistados a continuación en tu microinfusora para habilitar estos mensajes:"; + +/* Class = "UITableViewSection"; headerTitle = "Main Menu"; ObjectID = "ZnF-zy-5gR"; */ +"ZnF-zy-5gR.headerTitle" = "Menú Principal"; + diff --git a/MinimedKitUI/fr.lproj/InfoPlist.strings b/MinimedKitUI/fr.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKitUI/fr.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKitUI/fr.lproj/Localizable.strings b/MinimedKitUI/fr.lproj/Localizable.strings new file mode 100644 index 000000000..1d6470edc --- /dev/null +++ b/MinimedKitUI/fr.lproj/Localizable.strings @@ -0,0 +1,195 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ +"%1$@ %2$@/%3$@ %4$@" = "%1$@ %2$@/%3$@ %4$@"; + +/* The format string describing number of basal schedule entries: (1: number of entries) */ +"%1$@ basal schedule entries\n" = "%1$@ entrées du profil basal\n"; + +/* The format string describing units of insulin remaining: (1: number of units) */ +"%1$@ Units of insulin remaining\n" = "%1$@ unités d’insuline restantes\n"; + +/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ +"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; + +/* Instructions on selecting battery chemistry type */ +"Alkaline and Lithium batteries decay at differing rates. Alkaline tend to have a linear voltage drop over time whereas lithium cell batteries tend to maintain voltage until halfway through their lifespan. Under normal usage in a Non-MySentry compatible Minimed (x22/x15) insulin pump running Loop, Alkaline batteries last approximately 4 to 5 days. Lithium batteries last between 1-2 weeks. This selection will use different battery voltage decay rates for each of the battery chemistry types and alert the user when a battery is approximately 8 to 10 hours from failure." = "Les piles Alkaline et Lithium se vident à des vitesses différentes. Les Alkalines tendent à avoir une tension qui décroit de façon linéaire alors que les piles Lithium maintiennent leur tension jusqu’à la moitiée de leur durée de vie. Lors d’un usage normale de Loop avec pompe compatible Non-MySentry Minimed (x22/x15), les piles Alkalines durent environ 4-5 jours. Les piles Lithium durent 1-2 semaines. Cette option utilisera différents modèles en fonction du type de pile et alertera l’utilisateur quand la pile sera à 8-10 heures de sa fin de vie. "; + +/* Confirmation message for deleting a pump */ +"Are you sure you want to delete this pump?" = "Êtes-vous sûr de vouloir supprimer cette pompe?"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Réveillé jusqu’à"; + +/* The title text for the basal rate schedule */ +"Basal Rates" = "Débits basal"; + +/* The format string describing pump battery voltage: (1: battery voltage) */ +"Battery: %1$@ volts\n" = "Pile: %1$@ volts\n"; + +/* The label indicating the best radio frequency */ +"Best Frequency" = "Meilleure Fréquence"; + +/* The format string describing pump bolusing state: (1: bolusing) */ +"Bolusing: %1$@\n" = "Bolus en cours: %1$@\n"; + +/* The title of the cancel action in an action sheet */ +"Cancel" = "Annuler"; + +/* The title of the command to change pump time */ +"Change Time" = "Changer l’heure"; + +/* The title of the command to change pump time zone */ +"Change Time Zone" = "Changer le fuseau horaire"; + +/* Progress message for changing pump time. */ +"Changing time…" = "Changement d’heure…"; + +/* The title of the section describing commands */ +"Commands" = "Commandes"; + +/* The title of the configuration section in settings */ +"Configuration" = "Configuration"; + +/* Button title to connect to pump during setup */ +"Connect" = "Relier"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Etat de connexion"; + +/* Button title to delete pump + Title text for the button to remove a pump from Loop */ +"Delete Pump" = "Supprimer la pompe"; + +/* Title text for delivery limits */ +"Delivery Limits" = "Limites d'administration"; + +/* The title of the section describing the device */ +"Device" = "Dispositif"; + +/* The title of the command to discover commands */ +"Discover Commands" = "Découvrir les commandes"; + +/* Progress message for discovering commands. */ +"Discovering commands…" = "Découverte des commandes…"; + +/* The title of the command to enable diagnostic LEDs */ +"Enable Diagnostic LEDs" = "Activer les LEDs de diagnostique"; + +/* Progress message for enabling diagnostic LEDs */ +"Enabled Diagnostic LEDs" = "Activation des LEDs de diagnostique"; + +/* The title of the command to fetch recent glucose */ +"Fetch Enlite Glucose" = "Obtenir glycémie Enlite"; + +/* The title of the command to fetch recent history */ +"Fetch Recent History" = "Obtenir historique récente"; + +/* Progress message for fetching pump glucose. */ +"Fetching glucose…" = "Obtention des glycémies …"; + +/* Progress message for fetching pump history. */ +"Fetching history…" = "Obtention de l’historique …"; + +/* Progress message for fetching pump model. */ +"Fetching pump model…" = "Obtention du modèle de pompe…"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Firmware"; + +/* The title of the command to get pump model */ +"Get Pump Model" = "Obtenir le modèle de pompe"; + +/* Progress message for getting statistics. */ +"Get Statistics…" = "Obtenir les statistiques…"; + +/* Instructions on selecting an insulin data source */ +"Insulin delivery can be determined from the pump by either interpreting the event history or comparing the reservoir volume over time. Reading event history allows for a more accurate status graph and uploading up-to-date treatment data to Nightscout, at the cost of faster pump battery drain and the possibility of a higher radio error rate compared to reading only reservoir volume. If the selected source cannot be used for any reason, the system will attempt to fall back to the other option." = "Les données d’administration de l’insuline sont obtenus de la pompe soit en regardant l’historique des événements, soit en comparant le niveau du réservoir avant/après. Regardant l’historique des événements permet un graphique des donnés plus fiable ainsi qu’un téléchargement plus à jour sur Nightscout, au prix d’une baisse plus rapide du niveau de la pile et de plus de probabilité d’erreur de radio comparé à la lecture du niveau du réservoir. Si une de ces options ne marche pas, le système essayera de revenir à l’autre option par défaut."; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "Dernier réveille"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "L’écoute désactivée"; + +/* The title of the command to pair with mysentry */ +"MySentry Pair" = "Jumelage MySentry"; + +/* The title of the cell showing device name */ +"Name" = "Nom"; + +/* Message display when no response from tuning pump */ +"No response" = "Pas de réponse"; + +/* The title of the cell showing the last idle */ +"On Idle" = "Au Repos"; + +/* The title text for the preferred insulin data source config */ +"Preferred Data Source" = "Source de données préférée"; + +/* The title of the section describing the pump */ +"Pump" = "Pompe"; + +/* The title text for the battery type value */ +"Pump Battery Type" = "Type de pile dans la pompe"; + +/* The title of the cell showing pump ID + The title text for the pump ID config value */ +"Pump ID" = "Identifiant de la pompe"; + +/* The title of the cell showing the pump model number */ +"Pump Model" = "Modèle de pompe"; + +/* Title of the pump settings view controller */ +"Pump Settings" = "Paramètres de la pompe"; + +/* The title of the command to read basal schedule */ +"Read Basal Schedule" = "Lire profil basal"; + +/* The title of the command to read pump status */ +"Read Pump Status" = "Lire l’état de la pompe"; + +/* Progress message for reading basal schedule */ +"Reading basal schedule…" = "Lecture du profil basal…"; + +/* Progress message for reading pump status */ +"Reading pump status…" = "Lecture de l’état de la pompe…"; + +/* Button title to retry sentry setup */ +"Retry" = "Nouvel essai"; + +/* The title of the command to fetch RileyLink statistics */ +"RileyLink Statistics" = "Statistiques RileyLink"; + +/* Title of button to save basal profile to pump + Title of button to save delivery limit settings to pump */ +"Save to Pump…" = "Enregistrer dans la pompe…"; + +/* The title of the command to send a button press */ +"Send Button Press" = "Envoyer appui de bouton"; + +/* Progress message for sending button press to pump. */ +"Sending button press…" = "Envoie de l’appui de bouton…"; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Force du signal"; + +/* A message indicating a command succeeded */ +"Succeeded" = "Réussi"; + +/* The format string describing pump suspended state: (1: suspended) */ +"Suspended: %1$@\n" = "Suspendu: %1$@\n"; + +/* The label indicating the results of each frequency trial */ +"Trials" = "Essais"; + +/* The title of the command to re-tune the radio */ +"Tune Radio Frequency" = "Régler la fréquence radio"; + +/* Progress message for tuning radio */ +"Tuning radio…" = "Regulation de la fréquence radio…"; + +/* The detail text for an unknown pump model */ +"Unknown" = "Inconnu"; + diff --git a/MinimedKitUI/fr.lproj/MinimedPumpManager.strings b/MinimedKitUI/fr.lproj/MinimedPumpManager.strings new file mode 100644 index 000000000..2198f6209 --- /dev/null +++ b/MinimedKitUI/fr.lproj/MinimedPumpManager.strings @@ -0,0 +1,72 @@ +/* Class = "UITableViewController"; title = "RileyLink Setup"; ObjectID = "0MV-2k-Dty"; */ +"0MV-2k-Dty.title" = "Configuration de RileyLink"; + +/* Class = "UILabel"; text = "Find Device"; ObjectID = "1fp-45-qWK"; */ +"1fp-45-qWK.text" = "Découvrir dispositif"; + +/* Class = "UILabel"; text = "Other Devices"; ObjectID = "A6i-Cb-baR"; */ +"A6i-Cb-baR.text" = "Autres dispositifs"; + +/* Class = "UILabel"; text = "Do not change the time using your pumpʼs menu."; ObjectID = "Bdb-j4-WcR"; */ +"Bdb-j4-WcR.text" = "Ne changez pas l’heure en utilisant le menu de votre pompe."; + +/* Class = "UILabel"; text = "Utilities"; ObjectID = "c7t-pZ-WqY"; */ +"c7t-pZ-WqY.text" = "Utilitaires"; + +/* Class = "UILabel"; text = "Connect Devices"; ObjectID = "erq-yb-anx"; */ +"erq-yb-anx.text" = "Connecter des dispositifs"; + +/* Class = "UITableViewController"; title = "Pump Clock"; ObjectID = "Fps-h3-V4K"; */ +"Fps-h3-V4K.title" = "Horloge à Pompe"; + +/* Class = "UITableViewSection"; footerTitle = "The pump ID is the 6-digit numerical portion of the serial number (labeled as SN or S/N)."; ObjectID = "fVG-pl-jT9"; */ +"fVG-pl-jT9.footerTitle" = "L’ID de la pompe correspond à la partie numérique à 6 chiffres du numéro de série (étiquetée SN ou S/N)."; + +/* Class = "UITableViewSection"; headerTitle = "Pump ID"; ObjectID = "fVG-pl-jT9"; */ +"fVG-pl-jT9.headerTitle" = "ID de la Pompe"; + +/* Class = "UILabel"; text = "Your pump is ready for use."; ObjectID = "g1m-3k-XI3"; */ +"g1m-3k-XI3.text" = "Votre pompe est prête à l’emploi."; + +/* Class = "UITextField"; placeholder = "Enter the 6-digit pump ID"; ObjectID = "HeG-VF-L5P"; */ +"HeG-VF-L5P.placeholder" = "Entrez l’ID de la pompe à 6 chiffres"; + +/* Class = "UILabel"; text = "Review your pump settings below. You can change these settings at any time in Loopʼs Settings screen."; ObjectID = "HfQ-fG-8vO"; */ +"HfQ-fG-8vO.text" = "Vérifiez vos paramètres de pompe ci-dessous. Vous pouvez modifier ces paramètres à tout moment dans l’écran Paramètres de boucle."; + +/* Class = "UILabel"; text = "If you travel to a different time zone for an extended period of time, you can change the pumpʼs time zone at any time in Loopʼs Settings screen."; ObjectID = "HuY-fE-vM8"; */ +"HuY-fE-vM8.text" = "Si vous voyagez dans un fuseau horaire différent pendant une période prolongée, vous pouvez modifier le fuseau horaire de la pompe à tout moment dans l’écran Paramètres de Loop."; + +/* Class = "UILabel"; text = "Loop will keep your pumpʼs clock synchronized with your phone in the time zone youʼre in now."; ObjectID = "IQ5-53-x9s"; */ +"IQ5-53-x9s.text" = "Loop gardera l’horloge de votre pompe synchronisée avec votre téléphone dans le fuseau horaire où vous vous trouvez maintenant."; + +/* Class = "UITableViewController"; title = "Pump Settings"; ObjectID = "iQZ-kT-QUm"; */ +"iQZ-kT-QUm.title" = "Paramètres de la Pompe"; + +/* Class = "UITableViewSection"; footerTitle = "The pump region and color are denoted as the last 3 letters of the the model number (labeled as REF)."; ObjectID = "lGI-LD-xR7"; */ +"lGI-LD-xR7.footerTitle" = "La région et la couleur de la pompe sont désignées par les 3 dernières lettres du numéro de modèle (étiquetées REF)."; + +/* Class = "UITableViewSection"; headerTitle = "Region and Color"; ObjectID = "lGI-LD-xR7"; */ +"lGI-LD-xR7.headerTitle" = "Région et Couleur"; + +/* Class = "UITableViewController"; title = "Setup Complete"; ObjectID = "Nwf-TJ-KmJ"; */ +"Nwf-TJ-KmJ.title" = "L’installation est terminée"; + +/* Class = "UITableViewController"; title = "Pump Broadcasts"; ObjectID = "oBL-lh-SHI"; */ +"oBL-lh-SHI.title" = "Transmissions de Pompes"; + +/* Class = "UILabel"; text = "On"; ObjectID = "ojQ-ob-gBx"; */ +"ojQ-ob-gBx.text" = "Éveillé"; + +/* Class = "UITableViewController"; title = "Pump Setup"; ObjectID = "OZk-Db-KCs"; */ +"OZk-Db-KCs.title" = "Configuration de la Pompe"; + +/* Class = "UILabel"; text = "Enter the pump region"; ObjectID = "tGa-FP-JqD"; */ +"tGa-FP-JqD.text" = "Entrez la région des pompes"; + +/* Class = "UILabel"; text = "Loop will listen for status messages sent by your pump. Follow the steps below on your pump to enable these messages:"; ObjectID = "yLn-Ya-p1R"; */ +"yLn-Ya-p1R.text" = "Loop écoutera les messages d’état envoyés par votre pompe. Suivez les étapes ci-dessous sur votre pompe pour activer ces messages:"; + +/* Class = "UITableViewSection"; headerTitle = "Main Menu"; ObjectID = "ZnF-zy-5gR"; */ +"ZnF-zy-5gR.headerTitle" = "Menu Principal"; + diff --git a/MinimedKitUI/it.lproj/InfoPlist.strings b/MinimedKitUI/it.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKitUI/it.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKitUI/it.lproj/Localizable.strings b/MinimedKitUI/it.lproj/Localizable.strings new file mode 100644 index 000000000..5a0e351ae --- /dev/null +++ b/MinimedKitUI/it.lproj/Localizable.strings @@ -0,0 +1,195 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ +"%1$@ %2$@/%3$@ %4$@" = "%1$@ %2$@/%3$@ %4$@"; + +/* The format string describing number of basal schedule entries: (1: number of entries) */ +"%1$@ basal schedule entries\n" = "%1$@ inserimento basale\n"; + +/* The format string describing units of insulin remaining: (1: number of units) */ +"%1$@ Units of insulin remaining\n" = "%1$@ Unità insulina residua\n"; + +/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ +"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; + +/* Instructions on selecting battery chemistry type */ +"Alkaline and Lithium batteries decay at differing rates. Alkaline tend to have a linear voltage drop over time whereas lithium cell batteries tend to maintain voltage until halfway through their lifespan. Under normal usage in a Non-MySentry compatible Minimed (x22/x15) insulin pump running Loop, Alkaline batteries last approximately 4 to 5 days. Lithium batteries last between 1-2 weeks. This selection will use different battery voltage decay rates for each of the battery chemistry types and alert the user when a battery is approximately 8 to 10 hours from failure." = "Le batterie alcaline e al litio decadono a velocità diverse. Le batterie alcaline tendono ad avere una caduta di tensione lineare nel tempo mentre le batterie al litio tendono a mantenere la tensione fino a metà della loro durata. In condizioni di utilizzo normali con in esecuzione Loop, in un microinfusore d'insulina non compatibile con MySentry (x22/x15), le batterie alcaline durano dai 4 ai 5 giorni circa. Le batterie al litio durano tra 1-2 settimane. Questa selezione utilizzerà diverse velocità di decadimento della tensione della batteria per ciascuno dei tipi di chimica della batteria e avviserà l'utente quando una batteria si trova a circa 8-10 ore dall'esaurimento."; + +/* Confirmation message for deleting a pump */ +"Are you sure you want to delete this pump?" = "Sei sicuro di voler eliminare questo microinfusore?"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Attivo sino"; + +/* The title text for the basal rate schedule */ +"Basal Rates" = "Quantita' Basali"; + +/* The format string describing pump battery voltage: (1: battery voltage) */ +"Battery: %1$@ volts\n" = "Batteria: %1$@ volts\n"; + +/* The label indicating the best radio frequency */ +"Best Frequency" = "La migliore Frequenza"; + +/* The format string describing pump bolusing state: (1: bolusing) */ +"Bolusing: %1$@\n" = "Bolo in corso: %1$@\n"; + +/* The title of the cancel action in an action sheet */ +"Cancel" = "Cancella"; + +/* The title of the command to change pump time */ +"Change Time" = "Cambia Orario"; + +/* The title of the command to change pump time zone */ +"Change Time Zone" = "Cambia Fuso Orario"; + +/* Progress message for changing pump time. */ +"Changing time…" = "Modifica Orario…"; + +/* The title of the section describing commands */ +"Commands" = "Comandi"; + +/* The title of the configuration section in settings */ +"Configuration" = "Configurazione"; + +/* Button title to connect to pump during setup */ +"Connect" = "Collegarsi"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Stato di Connessione"; + +/* Button title to delete pump + Title text for the button to remove a pump from Loop */ +"Delete Pump" = "Elimina Microinfusore"; + +/* Title text for delivery limits */ +"Delivery Limits" = "Limiti di Consegna"; + +/* The title of the section describing the device */ +"Device" = "Dispositivo"; + +/* The title of the command to discover commands */ +"Discover Commands" = "Scopri i Comandi"; + +/* Progress message for discovering commands. */ +"Discovering commands…" = "Scoperta dei comandi…"; + +/* The title of the command to enable diagnostic LEDs */ +"Enable Diagnostic LEDs" = "Abilita LED Diagnostici"; + +/* Progress message for enabling diagnostic LEDs */ +"Enabled Diagnostic LEDs" = "LED Diagnostici Abilitati"; + +/* The title of the command to fetch recent glucose */ +"Fetch Enlite Glucose" = "Sincronizzare Glicemie Enlite"; + +/* The title of the command to fetch recent history */ +"Fetch Recent History" = "Sincronizzare Storia Recente"; + +/* Progress message for fetching pump glucose. */ +"Fetching glucose…" = "Recupero glicemie…"; + +/* Progress message for fetching pump history. */ +"Fetching history…" = "Recupero della cronologia…"; + +/* Progress message for fetching pump model. */ +"Fetching pump model…" = "Recupero modello microinfusore…"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Firmware"; + +/* The title of the command to get pump model */ +"Get Pump Model" = "Ottieni Modello del Microinfusore"; + +/* Progress message for getting statistics. */ +"Get Statistics…" = "Ottieni Statistiche…"; + +/* Instructions on selecting an insulin data source */ +"Insulin delivery can be determined from the pump by either interpreting the event history or comparing the reservoir volume over time. Reading event history allows for a more accurate status graph and uploading up-to-date treatment data to Nightscout, at the cost of faster pump battery drain and the possibility of a higher radio error rate compared to reading only reservoir volume. If the selected source cannot be used for any reason, the system will attempt to fall back to the other option." = "L'insulina somministrata può essere determinata dalla pompa sia interpretando la cronologia eventi o confrontando il volume del serbatoio nel tempo. La lettura della cronologia degli eventi consente una statistica più accurata e trasmette dati sempre aggiornati a Nightscout, a discapito di un maggiore consumo di batteria e con la possibilità di incorrere in un maggior tasso di errore di comunicazione rispetto alla sola lettura del volume del serbatoio. Se la sorgente selezionata non può essere utilizzata per qualsiasi ragione, il sistema tenterà di ripiegare sull'altra opzione."; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "Ultimo risveglio"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Ricevendo"; + +/* The title of the command to pair with mysentry */ +"MySentry Pair" = "Accoppia MySentry"; + +/* The title of the cell showing device name */ +"Name" = "Nome"; + +/* Message display when no response from tuning pump */ +"No response" = "Nessuna risposta"; + +/* The title of the cell showing the last idle */ +"On Idle" = "Inattivo"; + +/* The title text for the preferred insulin data source config */ +"Preferred Data Source" = "Fonte Dati"; + +/* The title of the section describing the pump */ +"Pump" = "Microinfusore"; + +/* The title text for the battery type value */ +"Pump Battery Type" = "Tipo Batteria Microinfusore"; + +/* The title of the cell showing pump ID + The title text for the pump ID config value */ +"Pump ID" = "ID microinfusore"; + +/* The title of the cell showing the pump model number */ +"Pump Model" = "Modello Microinfusore"; + +/* Title of the pump settings view controller */ +"Pump Settings" = "Impostazioni Microinfusore"; + +/* The title of the command to read basal schedule */ +"Read Basal Schedule" = "Leggi programma basale"; + +/* The title of the command to read pump status */ +"Read Pump Status" = "Leggi stato microinfusore"; + +/* Progress message for reading basal schedule */ +"Reading basal schedule…" = "Lettura programma basale…"; + +/* Progress message for reading pump status */ +"Reading pump status…" = "Lettura stato microinfusore…"; + +/* Button title to retry sentry setup */ +"Retry" = "Riprova"; + +/* The title of the command to fetch RileyLink statistics */ +"RileyLink Statistics" = "Statistiche RileyLink"; + +/* Title of button to save basal profile to pump + Title of button to save delivery limit settings to pump */ +"Save to Pump…" = "Salva su Microinfusore…"; + +/* The title of the command to send a button press */ +"Send Button Press" = "Invia prova pressione Pulsante"; + +/* Progress message for sending button press to pump. */ +"Sending button press…" = "Inviando prova pressione pulsante…"; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Potenza Segnale"; + +/* A message indicating a command succeeded */ +"Succeeded" = "Operazione eseguita con successo"; + +/* The format string describing pump suspended state: (1: suspended) */ +"Suspended: %1$@\n" = "Sospeso: %1$@\n"; + +/* The label indicating the results of each frequency trial */ +"Trials" = "Prove"; + +/* The title of the command to re-tune the radio */ +"Tune Radio Frequency" = "Sintonizzare la frequenza radio"; + +/* Progress message for tuning radio */ +"Tuning radio…" = "Sintonizzazione radio…"; + +/* The detail text for an unknown pump model */ +"Unknown" = "Sconosciuto"; + diff --git a/MinimedKitUI/it.lproj/MinimedPumpManager.strings b/MinimedKitUI/it.lproj/MinimedPumpManager.strings new file mode 100644 index 000000000..7d2e31d96 --- /dev/null +++ b/MinimedKitUI/it.lproj/MinimedPumpManager.strings @@ -0,0 +1,72 @@ +/* Class = "UITableViewController"; title = "RileyLink Setup"; ObjectID = "0MV-2k-Dty"; */ +"0MV-2k-Dty.title" = "Impostazioni RileyLink"; + +/* Class = "UILabel"; text = "Find Device"; ObjectID = "1fp-45-qWK"; */ +"1fp-45-qWK.text" = "Trova Device"; + +/* Class = "UILabel"; text = "Other Devices"; ObjectID = "A6i-Cb-baR"; */ +"A6i-Cb-baR.text" = "Altri Device"; + +/* Class = "UILabel"; text = "Do not change the time using your pumpʼs menu."; ObjectID = "Bdb-j4-WcR"; */ +"Bdb-j4-WcR.text" = "Non cambiare l'ora corrente attraverso il menu sul microinfusore."; + +/* Class = "UILabel"; text = "Utilities"; ObjectID = "c7t-pZ-WqY"; */ +"c7t-pZ-WqY.text" = "Utilita'"; + +/* Class = "UILabel"; text = "Connect Devices"; ObjectID = "erq-yb-anx"; */ +"erq-yb-anx.text" = "Connetti Device"; + +/* Class = "UITableViewController"; title = "Pump Clock"; ObjectID = "Fps-h3-V4K"; */ +"Fps-h3-V4K.title" = "Ora Microinfusore"; + +/* Class = "UITableViewSection"; footerTitle = "The pump ID is the 6-digit numerical portion of the serial number (labeled as SN or S/N)."; ObjectID = "fVG-pl-jT9"; */ +"fVG-pl-jT9.footerTitle" = "L'ID del microinfusore e' il numero di 6 cifre del SN o S/N)."; + +/* Class = "UITableViewSection"; headerTitle = "Pump ID"; ObjectID = "fVG-pl-jT9"; */ +"fVG-pl-jT9.headerTitle" = "ID Microinfusore"; + +/* Class = "UILabel"; text = "Your pump is ready for use."; ObjectID = "g1m-3k-XI3"; */ +"g1m-3k-XI3.text" = "il tuo microinfusore e' pronto all'uso."; + +/* Class = "UITextField"; placeholder = "Enter the 6-digit pump ID"; ObjectID = "HeG-VF-L5P"; */ +"HeG-VF-L5P.placeholder" = "Inserisci il SN (numero di 6 cifre) del microinfusore"; + +/* Class = "UILabel"; text = "Review your pump settings below. You can change these settings at any time in Loopʼs Settings screen."; ObjectID = "HfQ-fG-8vO"; */ +"HfQ-fG-8vO.text" = "Controlla le impostazioni del tuo microinfusore qui sotto. Puoi cambiarli quando vuoi nel menu' Impostazioni di Loop."; + +/* Class = "UILabel"; text = "If you travel to a different time zone for an extended period of time, you can change the pumpʼs time zone at any time in Loopʼs Settings screen."; ObjectID = "HuY-fE-vM8"; */ +"HuY-fE-vM8.text" = "Se stai viaggiando in un paese con un differente fuso orario, puoi cambiare il fuso orario del tuo microinfusore quando vuoi nel menu' impostazioni di Loop."; + +/* Class = "UILabel"; text = "Loop will keep your pumpʼs clock synchronized with your phone in the time zone youʼre in now."; ObjectID = "IQ5-53-x9s"; */ +"IQ5-53-x9s.text" = "Loop sincronizzera' automaticamente l'orario impostato sul tuo microinfusore con quello del paese in cui ti trovi."; + +/* Class = "UITableViewController"; title = "Pump Settings"; ObjectID = "iQZ-kT-QUm"; */ +"iQZ-kT-QUm.title" = "Impostazioni Microinfusore"; + +/* Class = "UITableViewSection"; footerTitle = "The pump region and color are denoted as the last 3 letters of the the model number (labeled as REF)."; ObjectID = "lGI-LD-xR7"; */ +"lGI-LD-xR7.footerTitle" = "La provenienza del microinfusore ed il colore sono descritti nelle ultime tre lettere del modello del tuo microinfusore (REF)."; + +/* Class = "UITableViewSection"; headerTitle = "Region and Color"; ObjectID = "lGI-LD-xR7"; */ +"lGI-LD-xR7.headerTitle" = "Provenienza e colore"; + +/* Class = "UITableViewController"; title = "Setup Complete"; ObjectID = "Nwf-TJ-KmJ"; */ +"Nwf-TJ-KmJ.title" = "Settaggio completato"; + +/* Class = "UITableViewController"; title = "Pump Broadcasts"; ObjectID = "oBL-lh-SHI"; */ +"oBL-lh-SHI.title" = "Trasmissione Microinfusore"; + +/* Class = "UILabel"; text = "On"; ObjectID = "ojQ-ob-gBx"; */ +"ojQ-ob-gBx.text" = "Acceso"; + +/* Class = "UITableViewController"; title = "Pump Setup"; ObjectID = "OZk-Db-KCs"; */ +"OZk-Db-KCs.title" = "Impostazione Microinfusore"; + +/* Class = "UILabel"; text = "Enter the pump region"; ObjectID = "tGa-FP-JqD"; */ +"tGa-FP-JqD.text" = "Inserisci la provenienza del microinfusore"; + +/* Class = "UILabel"; text = "Loop will listen for status messages sent by your pump. Follow the steps below on your pump to enable these messages:"; ObjectID = "yLn-Ya-p1R"; */ +"yLn-Ya-p1R.text" = "Loop sara' in attesa di messaggi di stato inviati dal microinfusore. Segui i successivi passaggi per abilitare questi messaggi:"; + +/* Class = "UITableViewSection"; headerTitle = "Main Menu"; ObjectID = "ZnF-zy-5gR"; */ +"ZnF-zy-5gR.headerTitle" = "Menu Principale"; + diff --git a/MinimedKitUI/nb.lproj/InfoPlist.strings b/MinimedKitUI/nb.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKitUI/nb.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKitUI/nb.lproj/Localizable.strings b/MinimedKitUI/nb.lproj/Localizable.strings new file mode 100644 index 000000000..c985c608c --- /dev/null +++ b/MinimedKitUI/nb.lproj/Localizable.strings @@ -0,0 +1,195 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ +"%1$@ %2$@/%3$@ %4$@" = "%1$@ %2$@/%3$@ %4$@"; + +/* The format string describing number of basal schedule entries: (1: number of entries) */ +"%1$@ basal schedule entries\n" = "%1$@ basalsprofilinnslag"; + +/* The format string describing units of insulin remaining: (1: number of units) */ +"%1$@ Units of insulin remaining\n" = "Gjenstående %1$@ Enheter med insulin"; + +/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ +"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; + +/* Instructions on selecting battery chemistry type */ +"Alkaline and Lithium batteries decay at differing rates. Alkaline tend to have a linear voltage drop over time whereas lithium cell batteries tend to maintain voltage until halfway through their lifespan. Under normal usage in a Non-MySentry compatible Minimed (x22/x15) insulin pump running Loop, Alkaline batteries last approximately 4 to 5 days. Lithium batteries last between 1-2 weeks. This selection will use different battery voltage decay rates for each of the battery chemistry types and alert the user when a battery is approximately 8 to 10 hours from failure." = "Alkaliske- og lithiumbatterier mister spenning med forskjellige kurver. Alkaliske har som regel en lineært minskende spenning, mens lithiumbatterier pleier å holde på spenningen gjennom omtrent halvparten av levetiden. Ved normalt bruk i en Non-MySentry kompatibel Minimed (x22/x15) insulinpumpe som kjører Loop, pleier alkaliske batterier å holde i 4 til 5 dager. Lithiumbatterier holder som regel 1-2 uker. Dette valget vil bruke forskjellige kurver for nedgang i batterispenning for hver av de forskjellige batteritypene, og varsle brukeren når batteriet er omtrent 8 til 10 timer fra å være tomt."; + +/* Confirmation message for deleting a pump */ +"Are you sure you want to delete this pump?" = "Er du sikker på at du vil slette denne pumpen?"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Aktiv til"; + +/* The title text for the basal rate schedule */ +"Basal Rates" = "Basaldose"; + +/* The format string describing pump battery voltage: (1: battery voltage) */ +"Battery: %1$@ volts\n" = "Batteri: %1$@ volt\n"; + +/* The label indicating the best radio frequency */ +"Best Frequency" = "Beste frekvens"; + +/* The format string describing pump bolusing state: (1: bolusing) */ +"Bolusing: %1$@\n" = "Gir bolus: %1$@\n"; + +/* The title of the cancel action in an action sheet */ +"Cancel" = "Avbryt"; + +/* The title of the command to change pump time */ +"Change Time" = "Endre tid"; + +/* The title of the command to change pump time zone */ +"Change Time Zone" = "Endre tidssone"; + +/* Progress message for changing pump time. */ +"Changing time…" = "Endrer tid…"; + +/* The title of the section describing commands */ +"Commands" = "Kommandoer"; + +/* The title of the configuration section in settings */ +"Configuration" = "Konfigurasjon"; + +/* Button title to connect to pump during setup */ +"Connect" = "Koble til"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Tilkoblingsstatus"; + +/* Button title to delete pump + Title text for the button to remove a pump from Loop */ +"Delete Pump" = "Slette pumpe"; + +/* Title text for delivery limits */ +"Delivery Limits" = "Dosegrense"; + +/* The title of the section describing the device */ +"Device" = "Enhet"; + +/* The title of the command to discover commands */ +"Discover Commands" = "Oppdage kommandoer"; + +/* Progress message for discovering commands. */ +"Discovering commands…" = "Oppdager kommandoer…"; + +/* The title of the command to enable diagnostic LEDs */ +"Enable Diagnostic LEDs" = "Tilgjengeligjør diagnostiske LEDs"; + +/* Progress message for enabling diagnostic LEDs */ +"Enabled Diagnostic LEDs" = "Tilgjengeligjort diagnostiske LEDs"; + +/* The title of the command to fetch recent glucose */ +"Fetch Enlite Glucose" = "Hent enlite blodsukker"; + +/* The title of the command to fetch recent history */ +"Fetch Recent History" = "Hent nylig historikk"; + +/* Progress message for fetching pump glucose. */ +"Fetching glucose…" = "Henter glukose…"; + +/* Progress message for fetching pump history. */ +"Fetching history…" = "Henter historikk…"; + +/* Progress message for fetching pump model. */ +"Fetching pump model…" = "Henter pumpemodell…"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Firmware"; + +/* The title of the command to get pump model */ +"Get Pump Model" = "Hent pumpemodell"; + +/* Progress message for getting statistics. */ +"Get Statistics…" = "Hent statistikk…"; + +/* Instructions on selecting an insulin data source */ +"Insulin delivery can be determined from the pump by either interpreting the event history or comparing the reservoir volume over time. Reading event history allows for a more accurate status graph and uploading up-to-date treatment data to Nightscout, at the cost of faster pump battery drain and the possibility of a higher radio error rate compared to reading only reservoir volume. If the selected source cannot be used for any reason, the system will attempt to fall back to the other option." = "Insulintilførsel kan hentes fra pumpa, enten ved å tolke hendelsehistorikken, eller ved å sammenligne reservoarvolumet over tid. Ved å lese hendelsehistorikken får man mer nøyaktig statuskurve og kan laste opp oppdaterte hendelser til Nightscout. Ulempen er høyere batteriforbruk i pumpa, og muligheten for større antall feil ved radiokommunikasjon - sammenlignet med å bare lese reservoarvolumet. Hvis den valgte kilden av noen grunn ikke kan brukes, vill systemet prøve den andre måten."; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "Sist aktiv"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Radio inaktiv"; + +/* The title of the command to pair with mysentry */ +"MySentry Pair" = "MySentry pair"; + +/* The title of the cell showing device name */ +"Name" = "Navn"; + +/* Message display when no response from tuning pump */ +"No response" = "Ingen svar"; + +/* The title of the cell showing the last idle */ +"On Idle" = "På Vent"; + +/* The title text for the preferred insulin data source config */ +"Preferred Data Source" = "Foretrukken datakilde"; + +/* The title of the section describing the pump */ +"Pump" = "Pumpe"; + +/* The title text for the battery type value */ +"Pump Battery Type" = "Type pumpebatteri"; + +/* The title of the cell showing pump ID + The title text for the pump ID config value */ +"Pump ID" = "Pumpe ID"; + +/* The title of the cell showing the pump model number */ +"Pump Model" = "Pumpemodell"; + +/* Title of the pump settings view controller */ +"Pump Settings" = "Pumpeinnstillinger"; + +/* The title of the command to read basal schedule */ +"Read Basal Schedule" = "Les basalplan"; + +/* The title of the command to read pump status */ +"Read Pump Status" = "Les pumpestatus"; + +/* Progress message for reading basal schedule */ +"Reading basal schedule…" = "Leser basalplan…"; + +/* Progress message for reading pump status */ +"Reading pump status…" = "Leser pumpestatus…"; + +/* Button title to retry sentry setup */ +"Retry" = "Prøv igjen"; + +/* The title of the command to fetch RileyLink statistics */ +"RileyLink Statistics" = "RileyLink statistikk"; + +/* Title of button to save basal profile to pump + Title of button to save delivery limit settings to pump */ +"Save to Pump…" = "Lagre til pumpe…"; + +/* The title of the command to send a button press */ +"Send Button Press" = "Send tastetrykk"; + +/* Progress message for sending button press to pump. */ +"Sending button press…" = "Sender tastetrykk…"; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Signalstyrke"; + +/* A message indicating a command succeeded */ +"Succeeded" = "Vellykket"; + +/* The format string describing pump suspended state: (1: suspended) */ +"Suspended: %1$@\n" = "Pauset: %1$@\n"; + +/* The label indicating the results of each frequency trial */ +"Trials" = "Forsøk"; + +/* The title of the command to re-tune the radio */ +"Tune Radio Frequency" = "Still radiofrekvens"; + +/* Progress message for tuning radio */ +"Tuning radio…" = "Stiller radiofrekvens…"; + +/* The detail text for an unknown pump model */ +"Unknown" = "Ukjent"; + diff --git a/MinimedKitUI/nb.lproj/MinimedPumpManager.strings b/MinimedKitUI/nb.lproj/MinimedPumpManager.strings new file mode 100644 index 000000000..c6864d270 --- /dev/null +++ b/MinimedKitUI/nb.lproj/MinimedPumpManager.strings @@ -0,0 +1,72 @@ +/* Class = "UITableViewController"; title = "RileyLink Setup"; ObjectID = "0MV-2k-Dty"; */ +"0MV-2k-Dty.title" = "RileyLink-innstillinger"; + +/* Class = "UILabel"; text = "Find Device"; ObjectID = "1fp-45-qWK"; */ +"1fp-45-qWK.text" = "Finn enhet"; + +/* Class = "UILabel"; text = "Other Devices"; ObjectID = "A6i-Cb-baR"; */ +"A6i-Cb-baR.text" = "Andre enheter"; + +/* Class = "UILabel"; text = "Do not change the time using your pumpʼs menu."; ObjectID = "Bdb-j4-WcR"; */ +"Bdb-j4-WcR.text" = "Ikke endre tiden via pumpemenyen."; + +/* Class = "UILabel"; text = "Utilities"; ObjectID = "c7t-pZ-WqY"; */ +"c7t-pZ-WqY.text" = "Tilbehør"; + +/* Class = "UILabel"; text = "Connect Devices"; ObjectID = "erq-yb-anx"; */ +"erq-yb-anx.text" = "Tilkoble enheter"; + +/* Class = "UITableViewController"; title = "Pump Clock"; ObjectID = "Fps-h3-V4K"; */ +"Fps-h3-V4K.title" = "Pumpeklokke"; + +/* Class = "UITableViewSection"; footerTitle = "The pump ID is the 6-digit numerical portion of the serial number (labeled as SN or S/N)."; ObjectID = "fVG-pl-jT9"; */ +"fVG-pl-jT9.footerTitle" = "Pumpe-ID er den 6-siffrede (tall) delen av serienummeret (merket som SN eller S/N)."; + +/* Class = "UITableViewSection"; headerTitle = "Pump ID"; ObjectID = "fVG-pl-jT9"; */ +"fVG-pl-jT9.headerTitle" = "Pumpe-ID"; + +/* Class = "UILabel"; text = "Your pump is ready for use."; ObjectID = "g1m-3k-XI3"; */ +"g1m-3k-XI3.text" = "Din pumpe er klar for bruk."; + +/* Class = "UITextField"; placeholder = "Enter the 6-digit pump ID"; ObjectID = "HeG-VF-L5P"; */ +"HeG-VF-L5P.placeholder" = "Tast den 6-siffrede pumpe ID'n."; + +/* Class = "UILabel"; text = "Review your pump settings below. You can change these settings at any time in Loopʼs Settings screen."; ObjectID = "HfQ-fG-8vO"; */ +"HfQ-fG-8vO.text" = "Gjennomgå dine pumpeinnstillinger nedenfor. Du kan endre disse innstillingene når som helst under innstillinger i Loop."; + +/* Class = "UILabel"; text = "If you travel to a different time zone for an extended period of time, you can change the pumpʼs time zone at any time in Loopʼs Settings screen."; ObjectID = "HuY-fE-vM8"; */ +"HuY-fE-vM8.text" = "Hvis du reiser til en annen tidssone for en lenger tid, kan du endre pumpens tidssone når som helst under innstillinger i Loop."; + +/* Class = "UILabel"; text = "Loop will keep your pumpʼs clock synchronized with your phone in the time zone youʼre in now."; ObjectID = "IQ5-53-x9s"; */ +"IQ5-53-x9s.text" = "Loop holder din pumpes klokke synkronisert med din telefon til den tidssone du er i nå."; + +/* Class = "UITableViewController"; title = "Pump Settings"; ObjectID = "iQZ-kT-QUm"; */ +"iQZ-kT-QUm.title" = "Pumpeinnstillinger"; + +/* Class = "UITableViewSection"; footerTitle = "The pump region and color are denoted as the last 3 letters of the the model number (labeled as REF)."; ObjectID = "lGI-LD-xR7"; */ +"lGI-LD-xR7.footerTitle" = "Pumperegionen og farge er angitt som de 3 siste bokstavene i modellnummeret (merket som REF)."; + +/* Class = "UITableViewSection"; headerTitle = "Region and Color"; ObjectID = "lGI-LD-xR7"; */ +"lGI-LD-xR7.headerTitle" = "Region og farge"; + +/* Class = "UITableViewController"; title = "Setup Complete"; ObjectID = "Nwf-TJ-KmJ"; */ +"Nwf-TJ-KmJ.title" = "Innstillinger ferdige"; + +/* Class = "UITableViewController"; title = "Pump Broadcasts"; ObjectID = "oBL-lh-SHI"; */ +"oBL-lh-SHI.title" = "Pumpe sender"; + +/* Class = "UILabel"; text = "On"; ObjectID = "ojQ-ob-gBx"; */ +"ojQ-ob-gBx.text" = "På"; + +/* Class = "UITableViewController"; title = "Pump Setup"; ObjectID = "OZk-Db-KCs"; */ +"OZk-Db-KCs.title" = "Pumpeinnstillinger"; + +/* Class = "UILabel"; text = "Enter the pump region"; ObjectID = "tGa-FP-JqD"; */ +"tGa-FP-JqD.text" = "Angi pumperegionen"; + +/* Class = "UILabel"; text = "Loop will listen for status messages sent by your pump. Follow the steps below on your pump to enable these messages:"; ObjectID = "yLn-Ya-p1R"; */ +"yLn-Ya-p1R.text" = "Loop hører etter statusmeldinger sendt fra din pumpe. Følg trinnene nedenfor på din pumpe for å gjøre disse meldingene tilgjengelige:"; + +/* Class = "UITableViewSection"; headerTitle = "Main Menu"; ObjectID = "ZnF-zy-5gR"; */ +"ZnF-zy-5gR.headerTitle" = "Hovedmenu"; + diff --git a/MinimedKitUI/nl.lproj/InfoPlist.strings b/MinimedKitUI/nl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKitUI/nl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKitUI/nl.lproj/Localizable.strings b/MinimedKitUI/nl.lproj/Localizable.strings new file mode 100644 index 000000000..a13a2b342 --- /dev/null +++ b/MinimedKitUI/nl.lproj/Localizable.strings @@ -0,0 +1,195 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ +"%1$@ %2$@/%3$@ %4$@" = "%1$@ %2$@/%3$@ %4$@"; + +/* The format string describing number of basal schedule entries: (1: number of entries) */ +"%1$@ basal schedule entries\n" = "%1$@ basaal schemas\n"; + +/* The format string describing units of insulin remaining: (1: number of units) */ +"%1$@ Units of insulin remaining\n" = "%1$@ Eenheden insuline resterend\n"; + +/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ +"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; + +/* Instructions on selecting battery chemistry type */ +"Alkaline and Lithium batteries decay at differing rates. Alkaline tend to have a linear voltage drop over time whereas lithium cell batteries tend to maintain voltage until halfway through their lifespan. Under normal usage in a Non-MySentry compatible Minimed (x22/x15) insulin pump running Loop, Alkaline batteries last approximately 4 to 5 days. Lithium batteries last between 1-2 weeks. This selection will use different battery voltage decay rates for each of the battery chemistry types and alert the user when a battery is approximately 8 to 10 hours from failure." = "Alkaline en Lithium batterijen werken na verloop van tijd minder goed. Alkaline heeft de neiging om in de loop van de tijd een lineair spanningsverlies te hebben, terwijl lithium batterijen de neiging hebben om hun spanning te behouden tot halverwege hun levensduur. Bij normaal gebruik in een niet-MySentry-compatibele Minimed (x22 / x15) insulinepomp met Loop, gaan Alkaline batterijen ongeveer 4 tot 5 dagen mee. Lithiumbatterijen gaan tussen de 1 tot 2 weken mee. Deze selectie gebruikt verschillende leegloop snelheden voor batterijvoltage voor elk van de typen batterijen en waarschuwt de gebruiker wanneer een batterij ongeveer in 8 tot 10 uur leeg is."; + +/* Confirmation message for deleting a pump */ +"Are you sure you want to delete this pump?" = "Weet u zeker dat u deze pomp wilt verwijderen?"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Actief tot"; + +/* The title text for the basal rate schedule */ +"Basal Rates" = "Basaal waardes"; + +/* The format string describing pump battery voltage: (1: battery voltage) */ +"Battery: %1$@ volts\n" = "Batterij: %1$@ Volt\n"; + +/* The label indicating the best radio frequency */ +"Best Frequency" = "Beste frequentie"; + +/* The format string describing pump bolusing state: (1: bolusing) */ +"Bolusing: %1$@\n" = "Bolussen: %1$@\n"; + +/* The title of the cancel action in an action sheet */ +"Cancel" = "Annuleer"; + +/* The title of the command to change pump time */ +"Change Time" = "Tijd aanpassen"; + +/* The title of the command to change pump time zone */ +"Change Time Zone" = "Verander tijdzone"; + +/* Progress message for changing pump time. */ +"Changing time…" = "Tijd aan het aanpassen…"; + +/* The title of the section describing commands */ +"Commands" = "Commando's"; + +/* The title of the configuration section in settings */ +"Configuration" = "Configuratie"; + +/* Button title to connect to pump during setup */ +"Connect" = "Verbinden"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Verbindingsstatus"; + +/* Button title to delete pump + Title text for the button to remove a pump from Loop */ +"Delete Pump" = "Verwijder de pomp"; + +/* Title text for delivery limits */ +"Delivery Limits" = "Insuline toediening limiet"; + +/* The title of the section describing the device */ +"Device" = "Apparaat"; + +/* The title of the command to discover commands */ +"Discover Commands" = "Commando’s opzoeken"; + +/* Progress message for discovering commands. */ +"Discovering commands…" = "Opdrachten opzoeken…"; + +/* The title of the command to enable diagnostic LEDs */ +"Enable Diagnostic LEDs" = "Diagnostische LEDs aanzetten"; + +/* Progress message for enabling diagnostic LEDs */ +"Enabled Diagnostic LEDs" = "Diagnostische LEDs aangezet"; + +/* The title of the command to fetch recent glucose */ +"Fetch Enlite Glucose" = "Ophalen enlite glucose"; + +/* The title of the command to fetch recent history */ +"Fetch Recent History" = "Lees recente pompgeschiedenis"; + +/* Progress message for fetching pump glucose. */ +"Fetching glucose…" = "Glucosegegevens aan het ophalen…"; + +/* Progress message for fetching pump history. */ +"Fetching history…" = "Haal geschiedenis op…"; + +/* Progress message for fetching pump model. */ +"Fetching pump model…" = "Haal pompmodel op…"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Firmware"; + +/* The title of the command to get pump model */ +"Get Pump Model" = "Lees pompmodel"; + +/* Progress message for getting statistics. */ +"Get Statistics…" = "Statistieken ophalen…"; + +/* Instructions on selecting an insulin data source */ +"Insulin delivery can be determined from the pump by either interpreting the event history or comparing the reservoir volume over time. Reading event history allows for a more accurate status graph and uploading up-to-date treatment data to Nightscout, at the cost of faster pump battery drain and the possibility of a higher radio error rate compared to reading only reservoir volume. If the selected source cannot be used for any reason, the system will attempt to fall back to the other option." = "De toediening van insuline kan worden vastgesteld aan de hand van de pomp door de pomp historie te interpreteren of door het reservoir volume in de loop van de tijd te vergelijken. Het lezen van de pomp historie zorgt voor een meer accurate statusgrafiek en het uploaden van up-to-date behandelingsgegevens naar Nightscout. Dit gaat ten koste van de batterij en de mogelijkheid van een hogere radiofout snelheid vergeleken met het alleen lezen van het reservoir volume. Als de geselecteerde bron om welke reden dan ook niet kan worden gebruikt, probeert het systeem terug te vallen op de andere optie."; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "Laatst actief"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Luisteren Uit"; + +/* The title of the command to pair with mysentry */ +"MySentry Pair" = "MySentry verbinden"; + +/* The title of the cell showing device name */ +"Name" = "Naam"; + +/* Message display when no response from tuning pump */ +"No response" = "Geen reactie"; + +/* The title of the cell showing the last idle */ +"On Idle" = "Inactief"; + +/* The title text for the preferred insulin data source config */ +"Preferred Data Source" = "Voorkeur databron"; + +/* The title of the section describing the pump */ +"Pump" = "Pomp"; + +/* The title text for the battery type value */ +"Pump Battery Type" = "Pomp batterij type"; + +/* The title of the cell showing pump ID + The title text for the pump ID config value */ +"Pump ID" = "Pomp ID"; + +/* The title of the cell showing the pump model number */ +"Pump Model" = "Pompmodel"; + +/* Title of the pump settings view controller */ +"Pump Settings" = "Pomp instellingen"; + +/* The title of the command to read basal schedule */ +"Read Basal Schedule" = "Lees basaal schema"; + +/* The title of the command to read pump status */ +"Read Pump Status" = "Lees pompstatus"; + +/* Progress message for reading basal schedule */ +"Reading basal schedule…" = "Lees basaal schema…"; + +/* Progress message for reading pump status */ +"Reading pump status…" = "Lees pomp gegevens…"; + +/* Button title to retry sentry setup */ +"Retry" = "Opnieuw proberen"; + +/* The title of the command to fetch RileyLink statistics */ +"RileyLink Statistics" = "RileyLink statistieken"; + +/* Title of button to save basal profile to pump + Title of button to save delivery limit settings to pump */ +"Save to Pump…" = "Opslaan in pomp…"; + +/* The title of the command to send a button press */ +"Send Button Press" = "Verstuur signaal induwen knop"; + +/* Progress message for sending button press to pump. */ +"Sending button press…" = "Versturen induwen knop…"; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Signaalsterkte"; + +/* A message indicating a command succeeded */ +"Succeeded" = "Geslaagd"; + +/* The format string describing pump suspended state: (1: suspended) */ +"Suspended: %1$@\n" = "Onderbroken: %1$@\n"; + +/* The label indicating the results of each frequency trial */ +"Trials" = "Pogingen"; + +/* The title of the command to re-tune the radio */ +"Tune Radio Frequency" = "Stel radiofrequentie in"; + +/* Progress message for tuning radio */ +"Tuning radio…" = "Radio instellen…"; + +/* The detail text for an unknown pump model */ +"Unknown" = "Onbekend"; + diff --git a/MinimedKitUI/nl.lproj/MinimedPumpManager.strings b/MinimedKitUI/nl.lproj/MinimedPumpManager.strings new file mode 100644 index 000000000..a92b773b8 --- /dev/null +++ b/MinimedKitUI/nl.lproj/MinimedPumpManager.strings @@ -0,0 +1,72 @@ +/* Class = "UITableViewController"; title = "RileyLink Setup"; ObjectID = "0MV-2k-Dty"; */ +"0MV-2k-Dty.title" = "RileyLink instellingen"; + +/* Class = "UILabel"; text = "Find Device"; ObjectID = "1fp-45-qWK"; */ +"1fp-45-qWK.text" = "Zoek apparaat"; + +/* Class = "UILabel"; text = "Other Devices"; ObjectID = "A6i-Cb-baR"; */ +"A6i-Cb-baR.text" = "Andere apparaten"; + +/* Class = "UILabel"; text = "Do not change the time using your pumpʼs menu."; ObjectID = "Bdb-j4-WcR"; */ +"Bdb-j4-WcR.text" = "Verander de tijd niet via het menu van de pomp."; + +/* Class = "UILabel"; text = "Utilities"; ObjectID = "c7t-pZ-WqY"; */ +"c7t-pZ-WqY.text" = "Hulpprogramma's"; + +/* Class = "UILabel"; text = "Connect Devices"; ObjectID = "erq-yb-anx"; */ +"erq-yb-anx.text" = "Koppel apparaten"; + +/* Class = "UITableViewController"; title = "Pump Clock"; ObjectID = "Fps-h3-V4K"; */ +"Fps-h3-V4K.title" = "Pomp klok"; + +/* Class = "UITableViewSection"; footerTitle = "The pump ID is the 6-digit numerical portion of the serial number (labeled as SN or S/N)."; ObjectID = "fVG-pl-jT9"; */ +"fVG-pl-jT9.footerTitle" = "Het ID van de pomp is het 6-cijferige gedeelte van het serienummer (aangegeven als SN of S/N)."; + +/* Class = "UITableViewSection"; headerTitle = "Pump ID"; ObjectID = "fVG-pl-jT9"; */ +"fVG-pl-jT9.headerTitle" = "Pomp ID"; + +/* Class = "UILabel"; text = "Your pump is ready for use."; ObjectID = "g1m-3k-XI3"; */ +"g1m-3k-XI3.text" = "De pomp is klaar voor gebruik."; + +/* Class = "UITextField"; placeholder = "Enter the 6-digit pump ID"; ObjectID = "HeG-VF-L5P"; */ +"HeG-VF-L5P.placeholder" = "Voer het 6-cijferige ID van de pomp in"; + +/* Class = "UILabel"; text = "Review your pump settings below. You can change these settings at any time in Loopʼs Settings screen."; ObjectID = "HfQ-fG-8vO"; */ +"HfQ-fG-8vO.text" = "Bekijk de pompinstellingen hieronder. Je kunt deze altijd veranderen via het instellingenscherm van Loop."; + +/* Class = "UILabel"; text = "If you travel to a different time zone for an extended period of time, you can change the pumpʼs time zone at any time in Loopʼs Settings screen."; ObjectID = "HuY-fE-vM8"; */ +"HuY-fE-vM8.text" = "Als je voor een langere periode in een andere tijdzone verblijft, dan kun je altijd de tijdzone van de pomp veranderen in het instellingenscherm van Loop."; + +/* Class = "UILabel"; text = "Loop will keep your pumpʼs clock synchronized with your phone in the time zone youʼre in now."; ObjectID = "IQ5-53-x9s"; */ +"IQ5-53-x9s.text" = "Loop zorgt ervoor dat de klok van uw pomp gesynchroniseerd blijft met uw telefoon in de tijdzone waarin u zich nu bevindt."; + +/* Class = "UITableViewController"; title = "Pump Settings"; ObjectID = "iQZ-kT-QUm"; */ +"iQZ-kT-QUm.title" = "Pomp instellingen"; + +/* Class = "UITableViewSection"; footerTitle = "The pump region and color are denoted as the last 3 letters of the the model number (labeled as REF)."; ObjectID = "lGI-LD-xR7"; */ +"lGI-LD-xR7.footerTitle" = "De regio en kleur van de pomp worden aangeduid in de laatste 3 letters van het modelnummer (gelabeld als REF)"; + +/* Class = "UITableViewSection"; headerTitle = "Region and Color"; ObjectID = "lGI-LD-xR7"; */ +"lGI-LD-xR7.headerTitle" = "Regio en kleur"; + +/* Class = "UITableViewController"; title = "Setup Complete"; ObjectID = "Nwf-TJ-KmJ"; */ +"Nwf-TJ-KmJ.title" = "Configuratie voltooid"; + +/* Class = "UITableViewController"; title = "Pump Broadcasts"; ObjectID = "oBL-lh-SHI"; */ +"oBL-lh-SHI.title" = "Pomp connectiviteit"; + +/* Class = "UILabel"; text = "On"; ObjectID = "ojQ-ob-gBx"; */ +"ojQ-ob-gBx.text" = "Aan"; + +/* Class = "UITableViewController"; title = "Pump Setup"; ObjectID = "OZk-Db-KCs"; */ +"OZk-Db-KCs.title" = "Pomp configuratie"; + +/* Class = "UILabel"; text = "Enter the pump region"; ObjectID = "tGa-FP-JqD"; */ +"tGa-FP-JqD.text" = "Voer regio van de pomp in"; + +/* Class = "UILabel"; text = "Loop will listen for status messages sent by your pump. Follow the steps below on your pump to enable these messages:"; ObjectID = "yLn-Ya-p1R"; */ +"yLn-Ya-p1R.text" = "Loop luistert naar statusberichten die door de pomp worden verzonden. Volg de stappen hieronder op de pomp om deze statusberichten in te schakelen:"; + +/* Class = "UITableViewSection"; headerTitle = "Main Menu"; ObjectID = "ZnF-zy-5gR"; */ +"ZnF-zy-5gR.headerTitle" = "Hoofdmenu"; + diff --git a/MinimedKitUI/ru.lproj/InfoPlist.strings b/MinimedKitUI/ru.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKitUI/ru.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKitUI/ru.lproj/Localizable.strings b/MinimedKitUI/ru.lproj/Localizable.strings new file mode 100644 index 000000000..fb8581cea --- /dev/null +++ b/MinimedKitUI/ru.lproj/Localizable.strings @@ -0,0 +1,195 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ +"%1$@ %2$@/%3$@ %4$@" = "%1$@ %2$@/%3$@ %4$@"; + +/* The format string describing number of basal schedule entries: (1: number of entries) */ +"%1$@ basal schedule entries\n" = "%1$@ записи графика подачи базала\n"; + +/* The format string describing units of insulin remaining: (1: number of units) */ +"%1$@ Units of insulin remaining\n" = "%1$@ Осталось единиц инсулина\n"; + +/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ +"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; + +/* Instructions on selecting battery chemistry type */ +"Alkaline and Lithium batteries decay at differing rates. Alkaline tend to have a linear voltage drop over time whereas lithium cell batteries tend to maintain voltage until halfway through their lifespan. Under normal usage in a Non-MySentry compatible Minimed (x22/x15) insulin pump running Loop, Alkaline batteries last approximately 4 to 5 days. Lithium batteries last between 1-2 weeks. This selection will use different battery voltage decay rates for each of the battery chemistry types and alert the user when a battery is approximately 8 to 10 hours from failure." = "Щелочные и литиевые батарейки садятся с различной скоростью. У щелочных падение линейное, в то время как литиевые сохраняют напряжение в течение половины срока службы. При нормальном пользовании в помпе Minimed без Mysentry (x22/x15) с применением алгоритма ИПЖ щелочные батарейки служат примерно от 4 до 5 дней. Литиевые служат от 1 до 2 недель. Эта настройка будет использовать разную скорость падения напряжения батареек в зависимости от их химического типа и предупреждать пользователя за 8-10 часов до отказа "; + +/* Confirmation message for deleting a pump */ +"Are you sure you want to delete this pump?" = "Вы уверены, что хотите удалить эту помпу?"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Рабочее состояние до"; + +/* The title text for the basal rate schedule */ +"Basal Rates" = "Скорости базала"; + +/* The format string describing pump battery voltage: (1: battery voltage) */ +"Battery: %1$@ volts\n" = "Батарея: %1$@ вольт\n"; + +/* The label indicating the best radio frequency */ +"Best Frequency" = "Лучшая частота"; + +/* The format string describing pump bolusing state: (1: bolusing) */ +"Bolusing: %1$@\n" = "Болюс: %1$@\n"; + +/* The title of the cancel action in an action sheet */ +"Cancel" = "Отмена"; + +/* The title of the command to change pump time */ +"Change Time" = "Изменить время"; + +/* The title of the command to change pump time zone */ +"Change Time Zone" = "Изменить временной пояс"; + +/* Progress message for changing pump time. */ +"Changing time…" = "Изменяется время…"; + +/* The title of the section describing commands */ +"Commands" = "Команды"; + +/* The title of the configuration section in settings */ +"Configuration" = "Конфигурация"; + +/* Button title to connect to pump during setup */ +"Connect" = "Соединение с помпой"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Состояние соединения"; + +/* Button title to delete pump + Title text for the button to remove a pump from Loop */ +"Delete Pump" = "Удалить помпу"; + +/* Title text for delivery limits */ +"Delivery Limits" = "Лимит подачи"; + +/* The title of the section describing the device */ +"Device" = "устройство"; + +/* The title of the command to discover commands */ +"Discover Commands" = "Обнаружить команды"; + +/* Progress message for discovering commands. */ +"Discovering commands…" = "Обнаружение команд…"; + +/* The title of the command to enable diagnostic LEDs */ +"Enable Diagnostic LEDs" = "Включить LED лампочки диагностики"; + +/* Progress message for enabling diagnostic LEDs */ +"Enabled Diagnostic LEDs" = "LED лампочки диагностики включены"; + +/* The title of the command to fetch recent glucose */ +"Fetch Enlite Glucose" = "Получить данные гликемии с Enlite"; + +/* The title of the command to fetch recent history */ +"Fetch Recent History" = "Получить логи недавней истории"; + +/* Progress message for fetching pump glucose. */ +"Fetching glucose…" = "Получаю гликемию…"; + +/* Progress message for fetching pump history. */ +"Fetching history…" = "Получаю логи…"; + +/* Progress message for fetching pump model. */ +"Fetching pump model…" = "Получаю модель помпы…"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Прошивка"; + +/* The title of the command to get pump model */ +"Get Pump Model" = "Получить модель помпы"; + +/* Progress message for getting statistics. */ +"Get Statistics…" = "Получить статистику…"; + +/* Instructions on selecting an insulin data source */ +"Insulin delivery can be determined from the pump by either interpreting the event history or comparing the reservoir volume over time. Reading event history allows for a more accurate status graph and uploading up-to-date treatment data to Nightscout, at the cost of faster pump battery drain and the possibility of a higher radio error rate compared to reading only reservoir volume. If the selected source cannot be used for any reason, the system will attempt to fall back to the other option." = "Подача инсулина может определяться с помпы путем интерпретации истории событий или сравнением изменения объемов резервуара за прошедшее время. Чтение истории событий позволяет вычертить более точный график состояния и загрузить в Nightscout актуальные данные лечения/назначений (за счет более быстрого истощения батареи помпы и более высокого процента ошибок радиосвязи) по сравнению со считыванием данных только об объеме резервуара."; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "Недавнее состояние активности"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Получаю данные от"; + +/* The title of the command to pair with mysentry */ +"MySentry Pair" = "Сопряжение с MySentry "; + +/* The title of the cell showing device name */ +"Name" = "Название"; + +/* Message display when no response from tuning pump */ +"No response" = "Нет ответа"; + +/* The title of the cell showing the last idle */ +"On Idle" = "Бездействие"; + +/* The title text for the preferred insulin data source config */ +"Preferred Data Source" = "Предпочтительный источник данных"; + +/* The title of the section describing the pump */ +"Pump" = "Помпа"; + +/* The title text for the battery type value */ +"Pump Battery Type" = "Тип батареи помпы"; + +/* The title of the cell showing pump ID + The title text for the pump ID config value */ +"Pump ID" = "Инд номер помпы"; + +/* The title of the cell showing the pump model number */ +"Pump Model" = "Модель помпы"; + +/* Title of the pump settings view controller */ +"Pump Settings" = "Настройки помпы"; + +/* The title of the command to read basal schedule */ +"Read Basal Schedule" = "Прочитать график базала"; + +/* The title of the command to read pump status */ +"Read Pump Status" = "Прочитать статус помпы"; + +/* Progress message for reading basal schedule */ +"Reading basal schedule…" = "Чтение графика базала…"; + +/* Progress message for reading pump status */ +"Reading pump status…" = "Чтение статуса помпы…"; + +/* Button title to retry sentry setup */ +"Retry" = "Повторить попытку"; + +/* The title of the command to fetch RileyLink statistics */ +"RileyLink Statistics" = "Статистика RileyLink"; + +/* Title of button to save basal profile to pump + Title of button to save delivery limit settings to pump */ +"Save to Pump…" = "Сохранить на помпе…"; + +/* The title of the command to send a button press */ +"Send Button Press" = "Отправить команду нажать кнопку"; + +/* Progress message for sending button press to pump. */ +"Sending button press…" = "Отправляется команда нажать кнопку…"; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Уровень сигнала"; + +/* A message indicating a command succeeded */ +"Succeeded" = "Успешно"; + +/* The format string describing pump suspended state: (1: suspended) */ +"Suspended: %1$@\n" = "Приостановлено: %1$@\n"; + +/* The label indicating the results of each frequency trial */ +"Trials" = "Попытки"; + +/* The title of the command to re-tune the radio */ +"Tune Radio Frequency" = "Настроить радиочастоту"; + +/* Progress message for tuning radio */ +"Tuning radio…" = "Настраивается радиочастота…"; + +/* The detail text for an unknown pump model */ +"Unknown" = "Неизвестно"; + diff --git a/MinimedKitUI/ru.lproj/MinimedPumpManager.strings b/MinimedKitUI/ru.lproj/MinimedPumpManager.strings new file mode 100644 index 000000000..026a5f1fb --- /dev/null +++ b/MinimedKitUI/ru.lproj/MinimedPumpManager.strings @@ -0,0 +1,72 @@ +/* Class = "UITableViewController"; title = "RileyLink Setup"; ObjectID = "0MV-2k-Dty"; */ +"0MV-2k-Dty.title" = "Настройки RileyLink"; + +/* Class = "UILabel"; text = "Find Device"; ObjectID = "1fp-45-qWK"; */ +"1fp-45-qWK.text" = "Найти устройство"; + +/* Class = "UILabel"; text = "Other Devices"; ObjectID = "A6i-Cb-baR"; */ +"A6i-Cb-baR.text" = "Другие устройства"; + +/* Class = "UILabel"; text = "Do not change the time using your pumpʼs menu."; ObjectID = "Bdb-j4-WcR"; */ +"Bdb-j4-WcR.text" = "Не меняйте настройки времени через меню помпы."; + +/* Class = "UILabel"; text = "Utilities"; ObjectID = "c7t-pZ-WqY"; */ +"c7t-pZ-WqY.text" = "Утилиты"; + +/* Class = "UILabel"; text = "Connect Devices"; ObjectID = "erq-yb-anx"; */ +"erq-yb-anx.text" = "Соединить устройства"; + +/* Class = "UITableViewController"; title = "Pump Clock"; ObjectID = "Fps-h3-V4K"; */ +"Fps-h3-V4K.title" = "Часы помпы"; + +/* Class = "UITableViewSection"; footerTitle = "The pump ID is the 6-digit numerical portion of the serial number (labeled as SN or S/N)."; ObjectID = "fVG-pl-jT9"; */ +"fVG-pl-jT9.footerTitle" = "ID помпы это 6-значная цифровая часть серийного номера (обозначаемого SN or S/N)."; + +/* Class = "UITableViewSection"; headerTitle = "Pump ID"; ObjectID = "fVG-pl-jT9"; */ +"fVG-pl-jT9.headerTitle" = "идентификатор ID помпы"; + +/* Class = "UILabel"; text = "Your pump is ready for use."; ObjectID = "g1m-3k-XI3"; */ +"g1m-3k-XI3.text" = "Помпа готова к работе."; + +/* Class = "UITextField"; placeholder = "Enter the 6-digit pump ID"; ObjectID = "HeG-VF-L5P"; */ +"HeG-VF-L5P.placeholder" = "Введите 6-значный идентификатор ID помпы"; + +/* Class = "UILabel"; text = "Review your pump settings below. You can change these settings at any time in Loopʼs Settings screen."; ObjectID = "HfQ-fG-8vO"; */ +"HfQ-fG-8vO.text" = "Проверьте настройки помпы ниже. Эти настройки можно поменять в любое время через экран общих настроек Loop."; + +/* Class = "UILabel"; text = "If you travel to a different time zone for an extended period of time, you can change the pumpʼs time zone at any time in Loopʼs Settings screen."; ObjectID = "HuY-fE-vM8"; */ +"HuY-fE-vM8.text" = "Если вы перемещаетесь в другой часовой пояс на длительное время, вы можете изменить часовой пояс в любое время через экран общих настроек Loop."; + +/* Class = "UILabel"; text = "Loop will keep your pumpʼs clock synchronized with your phone in the time zone youʼre in now."; ObjectID = "IQ5-53-x9s"; */ +"IQ5-53-x9s.text" = "Loop будет синхронизировать часы помпы с часами телефона в том часовом поясе, в котором вы сейчас находитесь."; + +/* Class = "UITableViewController"; title = "Pump Settings"; ObjectID = "iQZ-kT-QUm"; */ +"iQZ-kT-QUm.title" = "Настройки помпы"; + +/* Class = "UITableViewSection"; footerTitle = "The pump region and color are denoted as the last 3 letters of the the model number (labeled as REF)."; ObjectID = "lGI-LD-xR7"; */ +"lGI-LD-xR7.footerTitle" = "Регион помпы и ее цвет обозначаются тремя последними цифрами номера модели (маркируется как REF)."; + +/* Class = "UITableViewSection"; headerTitle = "Region and Color"; ObjectID = "lGI-LD-xR7"; */ +"lGI-LD-xR7.headerTitle" = "Регион и цвет"; + +/* Class = "UITableViewController"; title = "Setup Complete"; ObjectID = "Nwf-TJ-KmJ"; */ +"Nwf-TJ-KmJ.title" = "Установка завершена"; + +/* Class = "UITableViewController"; title = "Pump Broadcasts"; ObjectID = "oBL-lh-SHI"; */ +"oBL-lh-SHI.title" = "Помпа передает"; + +/* Class = "UILabel"; text = "On"; ObjectID = "ojQ-ob-gBx"; */ +"ojQ-ob-gBx.text" = "Вкл"; + +/* Class = "UITableViewController"; title = "Pump Setup"; ObjectID = "OZk-Db-KCs"; */ +"OZk-Db-KCs.title" = "Настройки помпы"; + +/* Class = "UILabel"; text = "Enter the pump region"; ObjectID = "tGa-FP-JqD"; */ +"tGa-FP-JqD.text" = "Введите регион помпы"; + +/* Class = "UILabel"; text = "Loop will listen for status messages sent by your pump. Follow the steps below on your pump to enable these messages:"; ObjectID = "yLn-Ya-p1R"; */ +"yLn-Ya-p1R.text" = "Loop будет отслеживать сообщения о состоянии с помпы. Выполните следующие шаги на помпе чтобы активировать такие сообщения"; + +/* Class = "UITableViewSection"; headerTitle = "Main Menu"; ObjectID = "ZnF-zy-5gR"; */ +"ZnF-zy-5gR.headerTitle" = "Главное меню"; + diff --git a/MinimedKitUI/zh-Hans.lproj/InfoPlist.strings b/MinimedKitUI/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKitUI/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKitUI/zh-Hans.lproj/Localizable.strings b/MinimedKitUI/zh-Hans.lproj/Localizable.strings new file mode 100644 index 000000000..453262040 --- /dev/null +++ b/MinimedKitUI/zh-Hans.lproj/Localizable.strings @@ -0,0 +1,195 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ +"%1$@ %2$@/%3$@ %4$@" = "%1$@ %2$@/%3$@ %4$@"; + +/* The format string describing number of basal schedule entries: (1: number of entries) */ +"%1$@ basal schedule entries\n" = "%1$@ 基础率\n"; + +/* The format string describing units of insulin remaining: (1: number of units) */ +"%1$@ Units of insulin remaining\n" = "胰岛素剩余量 %1$@ U \n"; + +/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ +"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; + +/* Instructions on selecting battery chemistry type */ +"Alkaline and Lithium batteries decay at differing rates. Alkaline tend to have a linear voltage drop over time whereas lithium cell batteries tend to maintain voltage until halfway through their lifespan. Under normal usage in a Non-MySentry compatible Minimed (x22/x15) insulin pump running Loop, Alkaline batteries last approximately 4 to 5 days. Lithium batteries last between 1-2 weeks. This selection will use different battery voltage decay rates for each of the battery chemistry types and alert the user when a battery is approximately 8 to 10 hours from failure." = "碱性电池和锂电池以不同的速率衰减。随着时间的推移,碱性电池往往具有线性电压降,而锂电池电池则随时间呈线性下降的电压一直保持到其寿命的一半。在非MySentry兼容Minimed(x22 / x15)的胰岛素泵运行Loop时,正常使用情况下,碱性电池可持续大约4至5天,锂电池持续1-2周。此选择将针对每种电池化学类型使用不同的电池电压衰减速率,并在电池电量耗尽前8至10小时前提醒用户。"; + +/* Confirmation message for deleting a pump */ +"Are you sure you want to delete this pump?" = "确定删除该泵?"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "唤醒 "; + +/* The title text for the basal rate schedule */ +"Basal Rates" = "基础率"; + +/* The format string describing pump battery voltage: (1: battery voltage) */ +"Battery: %1$@ volts\n" = "电池:%1$@ V\n"; + +/* The label indicating the best radio frequency */ +"Best Frequency" = "最优频率"; + +/* The format string describing pump bolusing state: (1: bolusing) */ +"Bolusing: %1$@\n" = "大剂量: %1$@\n"; + +/* The title of the cancel action in an action sheet */ +"Cancel" = "取消"; + +/* The title of the command to change pump time */ +"Change Time" = "修改时间"; + +/* The title of the command to change pump time zone */ +"Change Time Zone" = "改变时区"; + +/* Progress message for changing pump time. */ +"Changing time…" = "正在修改时间…"; + +/* The title of the section describing commands */ +"Commands" = "命令"; + +/* The title of the configuration section in settings */ +"Configuration" = "配置"; + +/* Button title to connect to pump during setup */ +"Connect" = "连接"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "连接状态"; + +/* Button title to delete pump + Title text for the button to remove a pump from Loop */ +"Delete Pump" = "删除泵"; + +/* Title text for delivery limits */ +"Delivery Limits" = "输注限制"; + +/* The title of the section describing the device */ +"Device" = "设备"; + +/* The title of the command to discover commands */ +"Discover Commands" = "搜索"; + +/* Progress message for discovering commands. */ +"Discovering commands…" = "正在搜索…"; + +/* The title of the command to enable diagnostic LEDs */ +"Enable Diagnostic LEDs" = "开启状态LED指示灯"; + +/* Progress message for enabling diagnostic LEDs */ +"Enabled Diagnostic LEDs" = "正在打开状态LED指示灯"; + +/* The title of the command to fetch recent glucose */ +"Fetch Enlite Glucose" = "获取Enlite葡萄糖"; + +/* The title of the command to fetch recent history */ +"Fetch Recent History" = "获取最近的历史数据"; + +/* Progress message for fetching pump glucose. */ +"Fetching glucose…" = "正在获取葡萄糖信息…"; + +/* Progress message for fetching pump history. */ +"Fetching history…" = "正在获取历史数据…"; + +/* Progress message for fetching pump model. */ +"Fetching pump model…" = "正在获取胰岛素泵型号…"; + +/* The title of the cell showing firmware version */ +"Firmware" = "固件"; + +/* The title of the command to get pump model */ +"Get Pump Model" = "获取胰岛素泵型号"; + +/* Progress message for getting statistics. */ +"Get Statistics…" = "正在获取数据…"; + +/* Instructions on selecting an insulin data source */ +"Insulin delivery can be determined from the pump by either interpreting the event history or comparing the reservoir volume over time. Reading event history allows for a more accurate status graph and uploading up-to-date treatment data to Nightscout, at the cost of faster pump battery drain and the possibility of a higher radio error rate compared to reading only reservoir volume. If the selected source cannot be used for any reason, the system will attempt to fall back to the other option." = "可以通过解释事件历史记录或比较随时间推移的储存容量来确定胰岛素输注总量。阅读事件历史记录可以获得更精确的胰岛素输注量并将最新的数据上传到Nightscout,但该方式会造成更快的电池消耗以及可能造成Rileylink通信失败概率增大。如果选中的方式无法正常工作,系统将自动尝试运行另一个方案。"; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "最近唤醒"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "监听关闭"; + +/* The title of the command to pair with mysentry */ +"MySentry Pair" = "MySentry配对"; + +/* The title of the cell showing device name */ +"Name" = "设备名称"; + +/* Message display when no response from tuning pump */ +"No response" = "无响应"; + +/* The title of the cell showing the last idle */ +"On Idle" = "空闲"; + +/* The title text for the preferred insulin data source config */ +"Preferred Data Source" = "首选数据源"; + +/* The title of the section describing the pump */ +"Pump" = "胰岛素泵"; + +/* The title text for the battery type value */ +"Pump Battery Type" = "胰岛素泵电池类型"; + +/* The title of the cell showing pump ID + The title text for the pump ID config value */ +"Pump ID" = "胰岛素泵序列号"; + +/* The title of the cell showing the pump model number */ +"Pump Model" = "泵型号"; + +/* Title of the pump settings view controller */ +"Pump Settings" = "泵设置"; + +/* The title of the command to read basal schedule */ +"Read Basal Schedule" = "读取基础率配置文件"; + +/* The title of the command to read pump status */ +"Read Pump Status" = "读取胰岛素泵状态"; + +/* Progress message for reading basal schedule */ +"Reading basal schedule…" = "正在读取基础率配置文件…"; + +/* Progress message for reading pump status */ +"Reading pump status…" = "正在读取胰岛素泵状态…"; + +/* Button title to retry sentry setup */ +"Retry" = "重试"; + +/* The title of the command to fetch RileyLink statistics */ +"RileyLink Statistics" = "RileyLink数据"; + +/* Title of button to save basal profile to pump + Title of button to save delivery limit settings to pump */ +"Save to Pump…" = "同步设置到泵…"; + +/* The title of the command to send a button press */ +"Send Button Press" = "发送亮屏指令"; + +/* Progress message for sending button press to pump. */ +"Sending button press…" = "正在发送亮屏指令…"; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "信号强度"; + +/* A message indicating a command succeeded */ +"Succeeded" = "成功"; + +/* The format string describing pump suspended state: (1: suspended) */ +"Suspended: %1$@\n" = "暂停: %1$@\n"; + +/* The label indicating the results of each frequency trial */ +"Trials" = "尝试"; + +/* The title of the command to re-tune the radio */ +"Tune Radio Frequency" = "调频"; + +/* Progress message for tuning radio */ +"Tuning radio…" = "正在调频…"; + +/* The detail text for an unknown pump model */ +"Unknown" = "未知"; + diff --git a/MinimedKitUI/zh-Hans.lproj/MinimedPumpManager.strings b/MinimedKitUI/zh-Hans.lproj/MinimedPumpManager.strings new file mode 100644 index 000000000..e2a66c57d --- /dev/null +++ b/MinimedKitUI/zh-Hans.lproj/MinimedPumpManager.strings @@ -0,0 +1,72 @@ +/* Class = "UITableViewController"; title = "RileyLink Setup"; ObjectID = "0MV-2k-Dty"; */ +"0MV-2k-Dty.title" = "RileyLink设置"; + +/* Class = "UILabel"; text = "Find Device"; ObjectID = "1fp-45-qWK"; */ +"1fp-45-qWK.text" = "发现设备"; + +/* Class = "UILabel"; text = "Other Devices"; ObjectID = "A6i-Cb-baR"; */ +"A6i-Cb-baR.text" = "其他设备"; + +/* Class = "UILabel"; text = "Do not change the time using your pumpʼs menu."; ObjectID = "Bdb-j4-WcR"; */ +"Bdb-j4-WcR.text" = "不要通过胰岛素泵来修改时间"; + +/* Class = "UILabel"; text = "Utilities"; ObjectID = "c7t-pZ-WqY"; */ +"c7t-pZ-WqY.text" = "功能"; + +/* Class = "UILabel"; text = "Connect Devices"; ObjectID = "erq-yb-anx"; */ +"erq-yb-anx.text" = "连接设备"; + +/* Class = "UITableViewController"; title = "Pump Clock"; ObjectID = "Fps-h3-V4K"; */ +"Fps-h3-V4K.title" = "泵时钟"; + +/* Class = "UITableViewSection"; footerTitle = "The pump ID is the 6-digit numerical portion of the serial number (labeled as SN or S/N)."; ObjectID = "fVG-pl-jT9"; */ +"fVG-pl-jT9.footerTitle" = "泵的ID是6位数字的序列号(标签为SN或S/N)"; + +/* Class = "UITableViewSection"; headerTitle = "Pump ID"; ObjectID = "fVG-pl-jT9"; */ +"fVG-pl-jT9.headerTitle" = "泵ID"; + +/* Class = "UILabel"; text = "Your pump is ready for use."; ObjectID = "g1m-3k-XI3"; */ +"g1m-3k-XI3.text" = "泵设置已完成"; + +/* Class = "UITextField"; placeholder = "Enter the 6-digit pump ID"; ObjectID = "HeG-VF-L5P"; */ +"HeG-VF-L5P.placeholder" = "输入六位数字的泵ID"; + +/* Class = "UILabel"; text = "Review your pump settings below. You can change these settings at any time in Loopʼs Settings screen."; ObjectID = "HfQ-fG-8vO"; */ +"HfQ-fG-8vO.text" = "检查以下泵选项设置,这些选项可以随时通过Loop来设置修改。"; + +/* Class = "UILabel"; text = "If you travel to a different time zone for an extended period of time, you can change the pumpʼs time zone at any time in Loopʼs Settings screen."; ObjectID = "HuY-fE-vM8"; */ +"HuY-fE-vM8.text" = "如果你在不同的时区旅行,可以通过Loops直接设置泵的时区。"; + +/* Class = "UILabel"; text = "Loop will keep your pumpʼs clock synchronized with your phone in the time zone youʼre in now."; ObjectID = "IQ5-53-x9s"; */ +"IQ5-53-x9s.text" = "Loop将会对泵和手机所处的时区保持一致"; + +/* Class = "UITableViewController"; title = "Pump Settings"; ObjectID = "iQZ-kT-QUm"; */ +"iQZ-kT-QUm.title" = "泵设置"; + +/* Class = "UITableViewSection"; footerTitle = "The pump region and color are denoted as the last 3 letters of the the model number (labeled as REF)."; ObjectID = "lGI-LD-xR7"; */ +"lGI-LD-xR7.footerTitle" = "泵的区域和颜色包含在设备型号的最后三个字母中(标记为REF)。"; + +/* Class = "UITableViewSection"; headerTitle = "Region and Color"; ObjectID = "lGI-LD-xR7"; */ +"lGI-LD-xR7.headerTitle" = "区域与颜色"; + +/* Class = "UITableViewController"; title = "Setup Complete"; ObjectID = "Nwf-TJ-KmJ"; */ +"Nwf-TJ-KmJ.title" = "设置完成"; + +/* Class = "UITableViewController"; title = "Pump Broadcasts"; ObjectID = "oBL-lh-SHI"; */ +"oBL-lh-SHI.title" = "泵广播"; + +/* Class = "UILabel"; text = "On"; ObjectID = "ojQ-ob-gBx"; */ +"ojQ-ob-gBx.text" = "开"; + +/* Class = "UITableViewController"; title = "Pump Setup"; ObjectID = "OZk-Db-KCs"; */ +"OZk-Db-KCs.title" = "泵设置"; + +/* Class = "UILabel"; text = "Enter the pump region"; ObjectID = "tGa-FP-JqD"; */ +"tGa-FP-JqD.text" = "输入泵区域"; + +/* Class = "UILabel"; text = "Loop will listen for status messages sent by your pump. Follow the steps below on your pump to enable these messages:"; ObjectID = "yLn-Ya-p1R"; */ +"yLn-Ya-p1R.text" = "Loop将监听泵的状态信息,并按照如下步骤操作胰岛素泵来开启此功能"; + +/* Class = "UITableViewSection"; headerTitle = "Main Menu"; ObjectID = "ZnF-zy-5gR"; */ +"ZnF-zy-5gR.headerTitle" = "主菜单"; + diff --git a/NightscoutUploadKit/de.lproj/InfoPlist.strings b/NightscoutUploadKit/de.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/NightscoutUploadKit/de.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/NightscoutUploadKit/es.lproj/InfoPlist.strings b/NightscoutUploadKit/es.lproj/InfoPlist.strings index f8e9a2b43..bbcf8f904 100644 --- a/NightscoutUploadKit/es.lproj/InfoPlist.strings +++ b/NightscoutUploadKit/es.lproj/InfoPlist.strings @@ -1,3 +1,3 @@ -/* (No Comment) */ +/* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; diff --git a/NightscoutUploadKit/fr.lproj/InfoPlist.strings b/NightscoutUploadKit/fr.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/NightscoutUploadKit/fr.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/NightscoutUploadKit/it.lproj/InfoPlist.strings b/NightscoutUploadKit/it.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/NightscoutUploadKit/it.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/NightscoutUploadKit/nb.lproj/InfoPlist.strings b/NightscoutUploadKit/nb.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/NightscoutUploadKit/nb.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/NightscoutUploadKit/nl.lproj/InfoPlist.strings b/NightscoutUploadKit/nl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/NightscoutUploadKit/nl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/NightscoutUploadKit/ru.lproj/InfoPlist.strings b/NightscoutUploadKit/ru.lproj/InfoPlist.strings index 874e8a453..bbcf8f904 100644 --- a/NightscoutUploadKit/ru.lproj/InfoPlist.strings +++ b/NightscoutUploadKit/ru.lproj/InfoPlist.strings @@ -1 +1,3 @@ -/* No Localized Strings */ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/NightscoutUploadKit/zh-Hans.lproj/InfoPlist.strings b/NightscoutUploadKit/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/NightscoutUploadKit/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/NightscoutUploadKitTests/de.lproj/InfoPlist.strings b/NightscoutUploadKitTests/de.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/NightscoutUploadKitTests/de.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/NightscoutUploadKitTests/es.lproj/InfoPlist.strings b/NightscoutUploadKitTests/es.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/NightscoutUploadKitTests/es.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/NightscoutUploadKitTests/fr.lproj/InfoPlist.strings b/NightscoutUploadKitTests/fr.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/NightscoutUploadKitTests/fr.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/NightscoutUploadKitTests/it.lproj/InfoPlist.strings b/NightscoutUploadKitTests/it.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/NightscoutUploadKitTests/it.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/NightscoutUploadKitTests/nb.lproj/InfoPlist.strings b/NightscoutUploadKitTests/nb.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/NightscoutUploadKitTests/nb.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/NightscoutUploadKitTests/nl.lproj/InfoPlist.strings b/NightscoutUploadKitTests/nl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/NightscoutUploadKitTests/nl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/NightscoutUploadKitTests/ru.lproj/InfoPlist.strings b/NightscoutUploadKitTests/ru.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/NightscoutUploadKitTests/ru.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/NightscoutUploadKitTests/zh-Hans.lproj/InfoPlist.strings b/NightscoutUploadKitTests/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/NightscoutUploadKitTests/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 65a28b611..c99a2233d 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -260,6 +260,30 @@ 54BC44B71DB81B5100340EED /* GetGlucosePageMessageBodyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54BC44B61DB81B5100340EED /* GetGlucosePageMessageBodyTests.swift */; }; 54BC44B91DB81D6100340EED /* GetGlucosePageMessageBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54BC44B81DB81D6100340EED /* GetGlucosePageMessageBody.swift */; }; 54DA4E851DFDC0A70007F489 /* SensorValueGlucoseEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54DA4E841DFDC0A70007F489 /* SensorValueGlucoseEvent.swift */; }; + 7D2366F0212527DA0028B67D /* LocalizedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2366EF212527DA0028B67D /* LocalizedString.swift */; }; + 7D2366F1212527DA0028B67D /* LocalizedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2366EF212527DA0028B67D /* LocalizedString.swift */; }; + 7D2366F2212527DA0028B67D /* LocalizedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2366EF212527DA0028B67D /* LocalizedString.swift */; }; + 7D2366F3212527DA0028B67D /* LocalizedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2366EF212527DA0028B67D /* LocalizedString.swift */; }; + 7D2366F4212527DA0028B67D /* LocalizedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2366EF212527DA0028B67D /* LocalizedString.swift */; }; + 7D2366F5212527DA0028B67D /* LocalizedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2366EF212527DA0028B67D /* LocalizedString.swift */; }; + 7D2366F6212527DA0028B67D /* LocalizedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2366EF212527DA0028B67D /* LocalizedString.swift */; }; + 7D2366F7212527DA0028B67D /* LocalizedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2366EF212527DA0028B67D /* LocalizedString.swift */; }; + 7D23674421252A5E0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674221252A5E0028B67D /* InfoPlist.strings */; }; + 7D23674721252A5E0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674521252A5E0028B67D /* InfoPlist.strings */; }; + 7D23674A21252A5E0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674821252A5E0028B67D /* InfoPlist.strings */; }; + 7D23674D21252A5E0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674B21252A5E0028B67D /* InfoPlist.strings */; }; + 7D23675021252A5E0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674E21252A5E0028B67D /* InfoPlist.strings */; }; + 7D23675321252A5E0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23675121252A5E0028B67D /* InfoPlist.strings */; }; + 7D23675621252A5E0028B67D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23675421252A5E0028B67D /* Localizable.strings */; }; + 7D23676121252A9D0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674821252A5E0028B67D /* InfoPlist.strings */; }; + 7D23676321252A9D0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674221252A5E0028B67D /* InfoPlist.strings */; }; + 7D23676521252A9D0028B67D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23675421252A5E0028B67D /* Localizable.strings */; }; + 7D23676721252A9D0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674521252A5E0028B67D /* InfoPlist.strings */; }; + 7D23676921252A9D0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674B21252A5E0028B67D /* InfoPlist.strings */; }; + 7D23676B21252A9D0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23675121252A5E0028B67D /* InfoPlist.strings */; }; + 7D23676D21252A9D0028B67D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23675421252A5E0028B67D /* Localizable.strings */; }; + 7D23679421252EBC0028B67D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23679221252EBC0028B67D /* Localizable.strings */; }; + 7D23679721252EBC0028B67D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23679521252EBC0028B67D /* Localizable.strings */; }; 7D70766D1FE092D4004AC8EA /* LoopKit.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D70766F1FE092D4004AC8EA /* LoopKit.strings */; }; 7D7076721FE092D5004AC8EA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D7076741FE092D5004AC8EA /* Localizable.strings */; }; 7D7076771FE092D6004AC8EA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D7076791FE092D6004AC8EA /* InfoPlist.strings */; }; @@ -833,6 +857,158 @@ 54BC44B61DB81B5100340EED /* GetGlucosePageMessageBodyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GetGlucosePageMessageBodyTests.swift; sourceTree = ""; }; 54BC44B81DB81D6100340EED /* GetGlucosePageMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GetGlucosePageMessageBody.swift; sourceTree = ""; }; 54DA4E841DFDC0A70007F489 /* SensorValueGlucoseEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SensorValueGlucoseEvent.swift; sourceTree = ""; }; + 7D2366EF212527DA0028B67D /* LocalizedString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizedString.swift; sourceTree = ""; }; + 7D2366F8212528560028B67D /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = ""; }; + 7D2366F9212528990028B67D /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = ""; }; + 7D2366FA212529510028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/MinimedPumpManager.strings; sourceTree = ""; }; + 7D2366FB212529510028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; + 7D2366FC212529510028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/LoopKit.strings; sourceTree = ""; }; + 7D2366FD212529520028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D2366FE212529520028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D2366FF212529520028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; + 7D236700212529520028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D236701212529520028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D236702212529520028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; + 7D236703212529520028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D236704212529530028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D236705212529530028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D2367062125297B0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/MinimedPumpManager.strings; sourceTree = ""; }; + 7D2367072125297B0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; + 7D2367082125297B0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/LoopKit.strings; sourceTree = ""; }; + 7D2367092125297B0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23670A2125297B0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23670B2125297B0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; + 7D23670C2125297B0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23670D2125297B0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23670E2125297C0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; + 7D23670F2125297C0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D2367102125297C0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D2367112125297C0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D236712212529810028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/MinimedPumpManager.strings"; sourceTree = ""; }; + 7D236713212529810028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; + 7D236714212529820028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/LoopKit.strings"; sourceTree = ""; }; + 7D236715212529820028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + 7D236716212529820028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + 7D236717212529820028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; + 7D236718212529820028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + 7D236719212529820028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + 7D23671A212529820028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; + 7D23671B212529820028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + 7D23671C212529830028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + 7D23671D212529830028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + 7D23671E212529890028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/MinimedPumpManager.strings; sourceTree = ""; }; + 7D23671F212529890028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; + 7D236720212529890028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/LoopKit.strings; sourceTree = ""; }; + 7D236721212529890028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D236722212529890028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D236723212529890028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; + 7D2367242125298A0028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D2367252125298A0028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D2367262125298A0028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; + 7D2367272125298A0028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D2367282125298A0028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D2367292125298A0028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23672A212529940028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/MinimedPumpManager.strings; sourceTree = ""; }; + 7D23672B212529950028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; + 7D23672C212529950028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/LoopKit.strings; sourceTree = ""; }; + 7D23672D212529950028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23672E212529950028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23672F212529950028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; + 7D236730212529950028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D236731212529950028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D236732212529950028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; + 7D236733212529950028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D236734212529960028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D236735212529960028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D2367362125299F0028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/MinimedPumpManager.strings; sourceTree = ""; }; + 7D2367372125299F0028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Localizable.strings; sourceTree = ""; }; + 7D236738212529A00028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/LoopKit.strings; sourceTree = ""; }; + 7D236739212529A00028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23673A212529A00028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23673B212529A00028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Localizable.strings; sourceTree = ""; }; + 7D23673C212529A00028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23673D212529A00028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23673E212529A00028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Localizable.strings; sourceTree = ""; }; + 7D23673F212529A00028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D236740212529A10028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D236741212529A10028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23674321252A5E0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23674621252A5E0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23674921252A5E0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23674C21252A5E0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23674F21252A5E0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23675221252A5E0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23675521252A5E0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; + 7D23675721252A5E0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/MinimedPumpManager.strings; sourceTree = ""; }; + 7D23675821252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23675921252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23675A21252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23675B21252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23675C21252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23675D21252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23675E21252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; + 7D23675F21252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/MinimedPumpManager.strings; sourceTree = ""; }; + 7D23676021252A9D0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23676221252A9D0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23676421252A9D0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23676621252A9D0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23676821252A9D0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23676A21252A9D0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23676C21252A9D0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; + 7D23676E21252AA80028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23676F21252AA80028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23677021252AA80028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23677121252AA80028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23677221252AA80028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23677321252AA80028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23677421252AA80028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; + 7D23677521252AB70028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23677621252AB70028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23677721252AB70028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23677821252AB70028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23677921252AB70028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23677A21252AB70028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23677B21252AB70028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; + 7D23677C21252AC40028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23677D21252AC40028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23677E21252AC40028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23677F21252AC40028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23678021252AC40028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23678121252AC40028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23678221252AC40028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Localizable.strings; sourceTree = ""; }; + 7D23678321252AD30028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23678421252AD30028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23678521252AD30028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23678621252AD30028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23678721252AD30028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23678821252AD30028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D23678921252AD40028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; + 7D23678A21252AE10028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + 7D23678B21252AE10028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + 7D23678C21252AE10028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + 7D23678D21252AE10028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + 7D23678E21252AE10028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + 7D23678F21252AE10028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + 7D23679021252AE10028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; + 7D23679121252BCC0028B67D /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = ""; }; + 7D23679321252EBC0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; + 7D23679621252EBC0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; + 7D23679821252F050028B67D /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = ""; }; + 7D23679921252F0D0028B67D /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = ""; }; + 7D23679A21252FF30028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; + 7D23679B21252FF30028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; + 7D23679C2125300A0028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; + 7D23679D2125300A0028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; + 7D23679E212530160028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; + 7D23679F212530160028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; + 7D2367A0212530230028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Localizable.strings; sourceTree = ""; }; + 7D2367A1212530230028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Localizable.strings; sourceTree = ""; }; + 7D2367A2212530300028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; + 7D2367A3212530300028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; + 7D2367A42125303D0028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; + 7D2367A52125303D0028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; + 7D2367A62125304D0028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; + 7D2367A72125304D0028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; 7D4F0A611F8F226F00A55FB2 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; 7D4F0A621F8F226F00A55FB2 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; 7D68AACB1FE31CE500522C49 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -1211,6 +1387,7 @@ children = ( 431CE7711F98564100255374 /* RileyLinkBLEKit.h */, 431CE7721F98564100255374 /* Info.plist */, + 7D23679221252EBC0028B67D /* Localizable.strings */, 7D7076881FE092D7004AC8EA /* InfoPlist.strings */, 431CE79D1F9BE73900255374 /* BLEFirmwareVersion.swift */, 431CE7A01F9D195600255374 /* CBCentralManager.swift */, @@ -1238,6 +1415,7 @@ 43047FC31FAEC70600508343 /* RadioFirmwareVersionTests.swift */, 4322B75520282DA60002837D /* ResponseBufferTests.swift */, 431CE7801F98564200255374 /* Info.plist */, + 7D23674821252A5E0028B67D /* InfoPlist.strings */, ); path = RileyLinkBLEKitTests; sourceTree = ""; @@ -1285,6 +1463,8 @@ children = ( 4352A72720DEC9B700CAC200 /* MinimedKitUI.h */, 4352A72820DEC9B700CAC200 /* Info.plist */, + 7D23675421252A5E0028B67D /* Localizable.strings */, + 7D23674E21252A5E0028B67D /* InfoPlist.strings */, 43709AC820DF1C9A00F941B3 /* MinimedKitUI.xcassets */, 43709AE020DF1D5400F941B3 /* MinimedPumpManager.storyboard */, 43709ACC20DF1CC900F941B3 /* Setup */, @@ -1331,6 +1511,7 @@ isa = PBXGroup; children = ( 43722FC01CB9F7640038B7F2 /* Info.plist */, + 7D23674521252A5E0028B67D /* InfoPlist.strings */, ); path = RileyLinkKitTests; sourceTree = ""; @@ -1351,6 +1532,8 @@ children = ( 43D5E7901FAF7BFB004ACDB7 /* RileyLinkKitUI.h */, 43D5E7911FAF7BFB004ACDB7 /* Info.plist */, + 7D23679521252EBC0028B67D /* Localizable.strings */, + 7D23674221252A5E0028B67D /* InfoPlist.strings */, 43709AEB20E0056F00F941B3 /* RileyLinkKitUI.xcassets */, C170C98D1CECD6F300F3D8E5 /* CBPeripheralState.swift */, C170C9961CECD80000F3D8E5 /* CommandResponseViewController.swift */, @@ -1416,6 +1599,7 @@ 43EBE4501EAD238C0073A0B5 /* TimeInterval.swift */, 4345D1CD1DA16AF300BAAD22 /* TimeZone.swift */, C14FFC601D3D75470049CF85 /* UIColor.swift */, + 7D2366EF212527DA0028B67D /* LocalizedString.swift */, ); path = Common; sourceTree = ""; @@ -1500,6 +1684,7 @@ 54BC44721DB46A5200340EED /* GlucosePageTests.swift */, C12198621C8DF4C800BC374C /* HistoryPageTests.swift */, C10D9BD31C8269D500378342 /* Info.plist */, + 7D23674B21252A5E0028B67D /* InfoPlist.strings */, C1C357901C92733A009BDD4F /* MeterMessageTests.swift */, C1F6EB8C1F89C45500CFE393 /* MinimedPacketTests.swift */, C1EAD6D31C826C43006DBA60 /* NSDataTests.swift */, @@ -1843,6 +2028,7 @@ children = ( C14C8A7F1C9CFBEE000F72C5 /* NightscoutPumpEventsTests.swift */, C1B3831D1CD0665D00CE7782 /* Info.plist */, + 7D23675121252A5E0028B67D /* InfoPlist.strings */, ); path = NightscoutUploadKitTests; sourceTree = ""; @@ -2267,6 +2453,7 @@ }; 43C246921D8918AE0031F8D1 = { CreatedOnToolsVersion = 8.0; + LastSwiftMigration = 0940; ProvisioningStyle = Manual; }; 43D5E78D1FAF7BFB004ACDB7 = { @@ -2313,6 +2500,12 @@ es, ru, Base, + fr, + de, + "zh-Hans", + it, + nl, + nb, ); mainGroup = C12EA22E198B436800309FA4; productRefGroup = C12EA238198B436800309FA4 /* Products */; @@ -2342,6 +2535,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7D23679421252EBC0028B67D /* Localizable.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2349,6 +2543,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7D23674A21252A5E0028B67D /* InfoPlist.strings in Resources */, + 7D23676121252A9D0028B67D /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2356,7 +2552,11 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7D23676521252A9D0028B67D /* Localizable.strings in Resources */, + 7D23676D21252A9D0028B67D /* Localizable.strings in Resources */, 43709ADE20DF1D5400F941B3 /* MinimedPumpManager.storyboard in Resources */, + 7D23675621252A5E0028B67D /* Localizable.strings in Resources */, + 7D23675021252A5E0028B67D /* InfoPlist.strings in Resources */, 43709AC920DF1C9A00F941B3 /* MinimedKitUI.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2374,6 +2574,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7D23674721252A5E0028B67D /* InfoPlist.strings in Resources */, + 7D23676721252A9D0028B67D /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2389,7 +2591,10 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7D23679721252EBC0028B67D /* Localizable.strings in Resources */, 43709AEC20E0056F00F941B3 /* RileyLinkKitUI.xcassets in Resources */, + 7D23676321252A9D0028B67D /* InfoPlist.strings in Resources */, + 7D23674421252A5E0028B67D /* InfoPlist.strings in Resources */, 43709AF020E0120F00F941B3 /* SetupImageTableViewCell.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2407,6 +2612,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7D23674D21252A5E0028B67D /* InfoPlist.strings in Resources */, + 7D23676921252A9D0028B67D /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2445,6 +2652,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7D23675321252A5E0028B67D /* InfoPlist.strings in Resources */, + 7D23676B21252A9D0028B67D /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2490,6 +2699,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7D2366F5212527DA0028B67D /* LocalizedString.swift in Sources */, 43BA719D2026C9B00058961E /* ResponseBuffer.swift in Sources */, 431CE78F1F985B6E00255374 /* CBPeripheral.swift in Sources */, 431CE79F1F9C670600255374 /* TimeInterval.swift in Sources */, @@ -2526,6 +2736,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7D2366F7212527DA0028B67D /* LocalizedString.swift in Sources */, 43709AD420DF1CF800F941B3 /* MinimedPumpIDSetupViewController.swift in Sources */, 43709AD520DF1CF800F941B3 /* MinimedPumpManagerSetupViewController.swift in Sources */, 43709AD320DF1CF800F941B3 /* MinimedPumpClockSetupViewController.swift in Sources */, @@ -2551,6 +2762,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7D2366F2212527DA0028B67D /* LocalizedString.swift in Sources */, 43323EAA1FA81C1B003FB0FA /* RileyLinkDevice.swift in Sources */, 43EBE4531EAD23CE0073A0B5 /* TimeInterval.swift in Sources */, 434AB0C71CBCB76400422F4A /* Data.swift in Sources */, @@ -2578,6 +2790,7 @@ files = ( 43C246A11D891BA80031F8D1 /* NSData+Conversion.m in Sources */, 43C246A01D8919E20031F8D1 /* Crypto.m in Sources */, + 7D2366F4212527DA0028B67D /* LocalizedString.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2585,6 +2798,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7D2366F6212527DA0028B67D /* LocalizedString.swift in Sources */, 43BF58B31FF6079600499C46 /* TimeInterval.swift in Sources */, 43D5E7A11FAF7CE0004ACDB7 /* UITableViewCell.swift in Sources */, 43709AEE20E008F300F941B3 /* SetupImageTableViewCell.swift in Sources */, @@ -2656,6 +2870,7 @@ C1EB955D1C887FE5002517DF /* HistoryPage.swift in Sources */, 54BC44921DB47CBA00340EED /* BatteryChangeGlucoseEvent.swift in Sources */, C1EAD6CA1C826B92006DBA60 /* MySentryAlertClearedMessageBody.swift in Sources */, + 7D2366F1212527DA0028B67D /* LocalizedString.swift in Sources */, C1842C181C8FA45100DB42AC /* BolusWizardSetupPumpEvent.swift in Sources */, C1274F791D823A550002912B /* ChangeMeterIDPumpEvent.swift in Sources */, C1842C201C8FA45100DB42AC /* ChangeAudioBolusPumpEvent.swift in Sources */, @@ -2867,6 +3082,7 @@ C16843771CF00C0100D53CCD /* SwitchTableViewCell.swift in Sources */, C14FFC551D3D72A50049CF85 /* UIViewController.swift in Sources */, 434FF1DE1CF268F3000DB779 /* RileyLinkDeviceTableViewCell.swift in Sources */, + 7D2366F0212527DA0028B67D /* LocalizedString.swift in Sources */, C14FFC651D3D7E250049CF85 /* RemoteDataManager.swift in Sources */, C17884611D519F1E00405663 /* BatteryIndicator.swift in Sources */, 437462391FA9287A00643383 /* RileyLinkDevice.swift in Sources */, @@ -2897,6 +3113,7 @@ files = ( C1B383291CD0668600CE7782 /* NightscoutPumpEvents.swift in Sources */, C18EB742207EE20100EA002B /* NightscoutProfile.swift in Sources */, + 7D2366F3212527DA0028B67D /* LocalizedString.swift in Sources */, 43B0ADCC1D126E3000AAD278 /* NSDateFormatter.swift in Sources */, C184875C20BC232F00ABE9E7 /* CorrectionRange.swift in Sources */, C1AF21E81D4866960088C41D /* PumpStatus.swift in Sources */, @@ -3058,15 +3275,167 @@ isa = PBXVariantGroup; children = ( 43709ADF20DF1D5400F941B3 /* Base */, + 7D2366FA212529510028B67D /* fr */, + 7D2367062125297B0028B67D /* de */, + 7D236712212529810028B67D /* zh-Hans */, + 7D23671E212529890028B67D /* it */, + 7D23672A212529940028B67D /* nl */, + 7D2367362125299F0028B67D /* nb */, + 7D23675721252A5E0028B67D /* es */, + 7D23675F21252A720028B67D /* ru */, ); name = MinimedPumpManager.storyboard; sourceTree = ""; }; + 7D23674221252A5E0028B67D /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 7D23674321252A5E0028B67D /* es */, + 7D23675921252A720028B67D /* ru */, + 7D23676221252A9D0028B67D /* de */, + 7D23677121252AA80028B67D /* fr */, + 7D23677621252AB70028B67D /* it */, + 7D23677D21252AC40028B67D /* nb */, + 7D23678321252AD30028B67D /* nl */, + 7D23678B21252AE10028B67D /* zh-Hans */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 7D23674521252A5E0028B67D /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 7D23674621252A5E0028B67D /* es */, + 7D23675A21252A720028B67D /* ru */, + 7D23676621252A9D0028B67D /* de */, + 7D23676E21252AA80028B67D /* fr */, + 7D23677A21252AB70028B67D /* it */, + 7D23677E21252AC40028B67D /* nb */, + 7D23678421252AD30028B67D /* nl */, + 7D23678C21252AE10028B67D /* zh-Hans */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 7D23674821252A5E0028B67D /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 7D23674921252A5E0028B67D /* es */, + 7D23675821252A720028B67D /* ru */, + 7D23676021252A9D0028B67D /* de */, + 7D23677021252AA80028B67D /* fr */, + 7D23677721252AB70028B67D /* it */, + 7D23677C21252AC40028B67D /* nb */, + 7D23678521252AD30028B67D /* nl */, + 7D23678A21252AE10028B67D /* zh-Hans */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 7D23674B21252A5E0028B67D /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 7D23674C21252A5E0028B67D /* es */, + 7D23675B21252A720028B67D /* ru */, + 7D23676821252A9D0028B67D /* de */, + 7D23676F21252AA80028B67D /* fr */, + 7D23677921252AB70028B67D /* it */, + 7D23677F21252AC40028B67D /* nb */, + 7D23678621252AD30028B67D /* nl */, + 7D23678E21252AE10028B67D /* zh-Hans */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 7D23674E21252A5E0028B67D /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 7D23674F21252A5E0028B67D /* es */, + 7D23675C21252A720028B67D /* ru */, + 7D23676421252A9D0028B67D /* de */, + 7D23677221252AA80028B67D /* fr */, + 7D23677821252AB70028B67D /* it */, + 7D23678121252AC40028B67D /* nb */, + 7D23678821252AD30028B67D /* nl */, + 7D23678D21252AE10028B67D /* zh-Hans */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 7D23675121252A5E0028B67D /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 7D23675221252A5E0028B67D /* es */, + 7D23675D21252A720028B67D /* ru */, + 7D23676A21252A9D0028B67D /* de */, + 7D23677321252AA80028B67D /* fr */, + 7D23677521252AB70028B67D /* it */, + 7D23678021252AC40028B67D /* nb */, + 7D23678721252AD30028B67D /* nl */, + 7D23678F21252AE10028B67D /* zh-Hans */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 7D23675421252A5E0028B67D /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 7D23675521252A5E0028B67D /* es */, + 7D23675E21252A720028B67D /* ru */, + 7D23676C21252A9D0028B67D /* de */, + 7D23677421252AA80028B67D /* fr */, + 7D23677B21252AB70028B67D /* it */, + 7D23678221252AC40028B67D /* nb */, + 7D23678921252AD40028B67D /* nl */, + 7D23679021252AE10028B67D /* zh-Hans */, + 7D23679121252BCC0028B67D /* Base */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + 7D23679221252EBC0028B67D /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 7D23679321252EBC0028B67D /* es */, + 7D23679821252F050028B67D /* Base */, + 7D23679A21252FF30028B67D /* de */, + 7D23679C2125300A0028B67D /* fr */, + 7D23679E212530160028B67D /* it */, + 7D2367A0212530230028B67D /* nb */, + 7D2367A2212530300028B67D /* ru */, + 7D2367A42125303D0028B67D /* zh-Hans */, + 7D2367A62125304D0028B67D /* nl */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + 7D23679521252EBC0028B67D /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 7D23679621252EBC0028B67D /* es */, + 7D23679921252F0D0028B67D /* Base */, + 7D23679B21252FF30028B67D /* de */, + 7D23679D2125300A0028B67D /* fr */, + 7D23679F212530160028B67D /* it */, + 7D2367A1212530230028B67D /* nb */, + 7D2367A3212530300028B67D /* ru */, + 7D2367A52125303D0028B67D /* zh-Hans */, + 7D2367A72125304D0028B67D /* nl */, + ); + name = Localizable.strings; + sourceTree = ""; + }; 7D70766F1FE092D4004AC8EA /* LoopKit.strings */ = { isa = PBXVariantGroup; children = ( 7D70766E1FE092D4004AC8EA /* es */, 7D68AACD1FE31DEA00522C49 /* ru */, + 7D2366FC212529510028B67D /* fr */, + 7D2367082125297B0028B67D /* de */, + 7D236714212529820028B67D /* zh-Hans */, + 7D236720212529890028B67D /* it */, + 7D23672C212529950028B67D /* nl */, + 7D236738212529A00028B67D /* nb */, ); name = LoopKit.strings; sourceTree = ""; @@ -3076,6 +3445,12 @@ children = ( 7D7076731FE092D5004AC8EA /* es */, 7D68AAD51FE31DEC00522C49 /* ru */, + 7D236702212529520028B67D /* fr */, + 7D23670E2125297C0028B67D /* de */, + 7D23671A212529820028B67D /* zh-Hans */, + 7D2367262125298A0028B67D /* it */, + 7D236732212529950028B67D /* nl */, + 7D23673E212529A00028B67D /* nb */, ); name = Localizable.strings; sourceTree = ""; @@ -3085,6 +3460,12 @@ children = ( 7D7076781FE092D6004AC8EA /* es */, 7D68AACF1FE31DEB00522C49 /* ru */, + 7D236704212529530028B67D /* fr */, + 7D2367102125297C0028B67D /* de */, + 7D23671C212529830028B67D /* zh-Hans */, + 7D2367282125298A0028B67D /* it */, + 7D236734212529960028B67D /* nl */, + 7D236740212529A10028B67D /* nb */, ); name = InfoPlist.strings; sourceTree = ""; @@ -3094,6 +3475,12 @@ children = ( 7D70767D1FE092D6004AC8EA /* es */, 7D68AAD01FE31DEB00522C49 /* ru */, + 7D236700212529520028B67D /* fr */, + 7D23670C2125297B0028B67D /* de */, + 7D236718212529820028B67D /* zh-Hans */, + 7D2367242125298A0028B67D /* it */, + 7D236730212529950028B67D /* nl */, + 7D23673C212529A00028B67D /* nb */, ); name = InfoPlist.strings; sourceTree = ""; @@ -3103,6 +3490,12 @@ children = ( 7D7076821FE092D7004AC8EA /* es */, 7D68AAD11FE31DEB00522C49 /* ru */, + 7D236701212529520028B67D /* fr */, + 7D23670D2125297B0028B67D /* de */, + 7D236719212529820028B67D /* zh-Hans */, + 7D2367252125298A0028B67D /* it */, + 7D236731212529950028B67D /* nl */, + 7D23673D212529A00028B67D /* nb */, ); name = InfoPlist.strings; sourceTree = ""; @@ -3112,6 +3505,12 @@ children = ( 7D7076871FE092D7004AC8EA /* es */, 7D68AAD21FE31DEC00522C49 /* ru */, + 7D236705212529530028B67D /* fr */, + 7D2367112125297C0028B67D /* de */, + 7D23671D212529830028B67D /* zh-Hans */, + 7D2367292125298A0028B67D /* it */, + 7D236735212529960028B67D /* nl */, + 7D236741212529A10028B67D /* nb */, ); name = InfoPlist.strings; sourceTree = ""; @@ -3121,6 +3520,13 @@ children = ( 7D70768C1FE09310004AC8EA /* es */, 7D68AAD31FE31DEC00522C49 /* ru */, + 7D2366F9212528990028B67D /* Base */, + 7D2366FF212529520028B67D /* fr */, + 7D23670B2125297B0028B67D /* de */, + 7D236717212529820028B67D /* zh-Hans */, + 7D236723212529890028B67D /* it */, + 7D23672F212529950028B67D /* nl */, + 7D23673B212529A00028B67D /* nb */, ); name = Localizable.strings; sourceTree = ""; @@ -3130,6 +3536,12 @@ children = ( 7D7076911FE09311004AC8EA /* es */, 7D68AAD41FE31DEC00522C49 /* ru */, + 7D236703212529520028B67D /* fr */, + 7D23670F2125297C0028B67D /* de */, + 7D23671B212529820028B67D /* zh-Hans */, + 7D2367272125298A0028B67D /* it */, + 7D236733212529950028B67D /* nl */, + 7D23673F212529A00028B67D /* nb */, ); name = InfoPlist.strings; sourceTree = ""; @@ -3139,6 +3551,13 @@ children = ( 7D7076961FE09311004AC8EA /* es */, 7D68AACE1FE31DEB00522C49 /* ru */, + 7D2366F8212528560028B67D /* Base */, + 7D2366FB212529510028B67D /* fr */, + 7D2367072125297B0028B67D /* de */, + 7D236713212529810028B67D /* zh-Hans */, + 7D23671F212529890028B67D /* it */, + 7D23672B212529950028B67D /* nl */, + 7D2367372125299F0028B67D /* nb */, ); name = Localizable.strings; sourceTree = ""; @@ -3149,6 +3568,12 @@ C12EA244198B436800309FA4 /* en */, 7D4F0A611F8F226F00A55FB2 /* es */, 7D68AACB1FE31CE500522C49 /* ru */, + 7D2366FD212529520028B67D /* fr */, + 7D2367092125297B0028B67D /* de */, + 7D236715212529820028B67D /* zh-Hans */, + 7D236721212529890028B67D /* it */, + 7D23672D212529950028B67D /* nl */, + 7D236739212529A00028B67D /* nb */, ); name = InfoPlist.strings; sourceTree = ""; @@ -3159,6 +3584,12 @@ C12EA25D198B436900309FA4 /* en */, 7D4F0A621F8F226F00A55FB2 /* es */, 7D68AACC1FE31CE500522C49 /* ru */, + 7D2366FE212529520028B67D /* fr */, + 7D23670A2125297B0028B67D /* de */, + 7D236716212529820028B67D /* zh-Hans */, + 7D236722212529890028B67D /* it */, + 7D23672E212529950028B67D /* nl */, + 7D23673A212529A00028B67D /* nb */, ); name = InfoPlist.strings; sourceTree = ""; @@ -3486,6 +3917,7 @@ buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; + CLANG_ENABLE_MODULES = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; @@ -3504,6 +3936,8 @@ PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.Crypto; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; VERSION_INFO_PREFIX = ""; }; name = Debug; @@ -3513,6 +3947,7 @@ buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ANALYZER_NONNULL = YES; + CLANG_ENABLE_MODULES = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; @@ -3532,6 +3967,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.Crypto; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; VERSION_INFO_PREFIX = ""; }; name = Release; @@ -3796,6 +4232,11 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 11.1; + LOCALIZED_STRING_MACRO_NAMES = ( + NSLocalizedString, + CFLocalizedString, + LocalizedString, + ); ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OBJC_BRIDGING_HEADER = ""; @@ -3851,6 +4292,11 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 11.1; + LOCALIZED_STRING_MACRO_NAMES = ( + NSLocalizedString, + CFLocalizedString, + LocalizedString, + ); SDKROOT = iphoneos; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; diff --git a/RileyLink/Base.lproj/Localizable.strings b/RileyLink/Base.lproj/Localizable.strings new file mode 100644 index 000000000..a594bf5cd --- /dev/null +++ b/RileyLink/Base.lproj/Localizable.strings @@ -0,0 +1,53 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The title of the about section */ +"About" = "About"; + +/* The title of the button to add the credentials for a service */ +"Add Account" = "Add Account"; + +/* The title of the nightscout API secret credential */ +"API Secret" = "API Secret"; + +/* The title of the configuration section in settings */ +"Configuration" = "Configuration"; + +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "Delete Account"; + +/* The placeholder text instructing users how to enter a pump ID */ +"Enter the 6-digit pump ID" = "Enter the 6-digit pump ID"; + +/* The title text for the pull cgm Data cell */ +"Fetch CGM" = "Fetch CGM"; + +/* The placeholder text for the nightscout site URL credential */ +"http://mysite.azurewebsites.net" = "http://mysite.azurewebsites.net"; + +/* The title of the Nightscout service */ +"Nightscout" = "Nightscout"; + +/* The title text for the pump ID config value */ +"Pump ID" = "Pump ID"; + +/* The title text for the pump Region config value */ +"Pump Region" = "Pump Region"; + +/* Instructions on selecting the pump region */ +"Pump Region is listed on the back of your pump as two of the last three characters of the model string, which reads something like this: MMT-551NAB, or MMT-515LWWS. If your model has an \"NA\" in it, then the region is North America. If your model has an \"WW\" in it, then the region is WorldWide." = "Pump Region is listed on the back of your pump as two of the last three characters of the model string, which reads something like this: MMT-551NAB, or MMT-515LWWS. If your model has an \"NA\" in it, then the region is North America. If your model has an \"WW\" in it, then the region is WorldWide."; + +/* The default placeholder string for a credential */ +"Required" = "Required"; + +/* The title of the nightscout site URL credential */ +"Site URL" = "Site URL"; + +/* The empty-state text for a configuration value */ +"Tap to set" = "Tap to set"; + +/* The title text for the nightscout upload enabled switch cell */ +"Upload To Nightscout" = "Upload To Nightscout"; + +/* Label indicating validation is occurring */ +"Verifying" = "Verifying"; diff --git a/RileyLink/Extensions/UIViewController.swift b/RileyLink/Extensions/UIViewController.swift index 980a054c3..c3c325e9b 100644 --- a/RileyLink/Extensions/UIViewController.swift +++ b/RileyLink/Extensions/UIViewController.swift @@ -25,7 +25,7 @@ extension UIViewController { ) let action = UIAlertAction( - title: NSLocalizedString("com.loudnate.LoopKit.errorAlertActionTitle", tableName: "LoopKit", value: "OK", comment: "The title of the action used to dismiss an error alert"), + title: LocalizedString("com.loudnate.LoopKit.errorAlertActionTitle", tableName: "LoopKit", value: "OK", comment: "The title of the action used to dismiss an error alert"), style: .default, handler: nil ) diff --git a/RileyLink/Models/NightscoutService.swift b/RileyLink/Models/NightscoutService.swift index 3b030e889..c338d8194 100644 --- a/RileyLink/Models/NightscoutService.swift +++ b/RileyLink/Models/NightscoutService.swift @@ -14,19 +14,19 @@ import NightscoutUploadKit struct NightscoutService: ServiceAuthentication { var credentials: [ServiceCredential] - let title: String = NSLocalizedString("Nightscout", comment: "The title of the Nightscout service") + let title: String = LocalizedString("Nightscout", comment: "The title of the Nightscout service") init(siteURL: URL?, APISecret: String?) { credentials = [ ServiceCredential( - title: NSLocalizedString("Site URL", comment: "The title of the nightscout site URL credential"), - placeholder: NSLocalizedString("http://mysite.azurewebsites.net", comment: "The placeholder text for the nightscout site URL credential"), + title: LocalizedString("Site URL", comment: "The title of the nightscout site URL credential"), + placeholder: LocalizedString("http://mysite.azurewebsites.net", comment: "The placeholder text for the nightscout site URL credential"), isSecret: false, keyboardType: .URL, value: siteURL?.absoluteString ), ServiceCredential( - title: NSLocalizedString("API Secret", comment: "The title of the nightscout API secret credential"), + title: LocalizedString("API Secret", comment: "The title of the nightscout API secret credential"), placeholder: nil, isSecret: false, keyboardType: .asciiCapable, diff --git a/RileyLink/View Controllers/AuthenticationViewController.swift b/RileyLink/View Controllers/AuthenticationViewController.swift index e4032fc04..f73604b93 100644 --- a/RileyLink/View Controllers/AuthenticationViewController.swift +++ b/RileyLink/View Controllers/AuthenticationViewController.swift @@ -109,10 +109,10 @@ class AuthenticationViewController: UITableViewControl switch state { case .authorized: - cell.button.setTitle(NSLocalizedString("Delete Account", comment: "The title of the button to remove the credentials for a service"), for: UIControlState()) + cell.button.setTitle(LocalizedString("Delete Account", comment: "The title of the button to remove the credentials for a service"), for: UIControlState()) cell.button.setTitleColor(UIColor.deleteColor, for: UIControlState()) case .empty, .unauthorized, .verifying: - cell.button.setTitle(NSLocalizedString("Add Account", comment: "The title of the button to add the credentials for a service"), for: UIControlState()) + cell.button.setTitle(LocalizedString("Add Account", comment: "The title of the button to add the credentials for a service"), for: UIControlState()) cell.button.setTitleColor(nil, for: UIControlState()) } @@ -136,7 +136,7 @@ class AuthenticationViewController: UITableViewControl cell.textField.isSecureTextEntry = credential.isSecret cell.textField.returnKeyType = (indexPath.row < authentication.credentials.count - 1) ? .next : .done cell.textField.text = credential.value - cell.textField.placeholder = credential.placeholder ?? NSLocalizedString("Required", comment: "The default placeholder string for a credential") + cell.textField.placeholder = credential.placeholder ?? LocalizedString("Required", comment: "The default placeholder string for a credential") cell.textField.delegate = self diff --git a/RileyLink/View Controllers/RadioSelectionTableViewController.swift b/RileyLink/View Controllers/RadioSelectionTableViewController.swift index 165c5c655..bd179917e 100644 --- a/RileyLink/View Controllers/RadioSelectionTableViewController.swift +++ b/RileyLink/View Controllers/RadioSelectionTableViewController.swift @@ -80,7 +80,7 @@ extension RadioSelectionTableViewController { vc.selectedIndex = value?.rawValue vc.options = (0..<2).compactMap({ PumpRegion(rawValue: $0) }).map { String(describing: $0) } - vc.contextHelp = NSLocalizedString("Pump Region is listed on the back of your pump as two of the last three characters of the model string, which reads something like this: MMT-551NAB, or MMT-515LWWS. If your model has an \"NA\" in it, then the region is NorthAmerica. If your model has an \"WW\" in it, then the region is WorldWide.", comment: "Instructions on selecting the pump region") + vc.contextHelp = LocalizedString("Pump Region is listed on the back of your pump as two of the last three characters of the model string, which reads something like this: MMT-551NAB, or MMT-515LWWS. If your model has an \"NA\" in it, then the region is NorthAmerica. If your model has an \"WW\" in it, then the region is WorldWide.", comment: "Instructions on selecting the pump region") return vc } } diff --git a/RileyLink/View Controllers/SettingsTableViewController.swift b/RileyLink/View Controllers/SettingsTableViewController.swift index 8e2f38ecf..0815b6283 100644 --- a/RileyLink/View Controllers/SettingsTableViewController.swift +++ b/RileyLink/View Controllers/SettingsTableViewController.swift @@ -14,7 +14,7 @@ import RileyLinkKitUI private let ConfigCellIdentifier = "ConfigTableViewCell" -private let TapToSetString = NSLocalizedString("Tap to set", comment: "The empty-state text for a configuration value") +private let TapToSetString = LocalizedString("Tap to set", comment: "The empty-state text for a configuration value") extension TextFieldTableViewController: IdentifiableClass { } @@ -91,7 +91,7 @@ class SettingsTableViewController: UITableViewController, TextFieldTableViewCont let switchCell = tableView.dequeueReusableCell(withIdentifier: SwitchTableViewCell.className, for: indexPath) as! SwitchTableViewCell switchCell.`switch`?.isOn = Config.sharedInstance().uploadEnabled - switchCell.titleLabel.text = NSLocalizedString("Upload To Nightscout", comment: "The title text for the nightscout upload enabled switch cell") + switchCell.titleLabel.text = LocalizedString("Upload To Nightscout", comment: "The title text for the nightscout upload enabled switch cell") switchCell.`switch`?.addTarget(self, action: #selector(uploadEnabledChanged(_:)), for: .valueChanged) return switchCell @@ -101,12 +101,12 @@ class SettingsTableViewController: UITableViewController, TextFieldTableViewCont switch ConfigurationRow(rawValue: indexPath.row)! { case .pumpID: let configCell = tableView.dequeueReusableCell(withIdentifier: ConfigCellIdentifier, for: indexPath) - configCell.textLabel?.text = NSLocalizedString("Pump ID", comment: "The title text for the pump ID config value") + configCell.textLabel?.text = LocalizedString("Pump ID", comment: "The title text for the pump ID config value") configCell.detailTextLabel?.text = dataManager.pumpSettings?.pumpID ?? TapToSetString cell = configCell case .pumpRegion: let configCell = tableView.dequeueReusableCell(withIdentifier: ConfigCellIdentifier, for: indexPath) - configCell.textLabel?.text = NSLocalizedString("Pump Region", comment: "The title text for the pump Region config value") + configCell.textLabel?.text = LocalizedString("Pump Region", comment: "The title text for the pump Region config value") if let pumpRegion = dataManager.pumpSettings?.pumpRegion { configCell.detailTextLabel?.text = String(describing: pumpRegion) @@ -126,7 +126,7 @@ class SettingsTableViewController: UITableViewController, TextFieldTableViewCont let switchCell = tableView.dequeueReusableCell(withIdentifier: SwitchTableViewCell.className, for: indexPath) as! SwitchTableViewCell switchCell.`switch`?.isOn = Config.sharedInstance().fetchCGMEnabled - switchCell.titleLabel.text = NSLocalizedString("Fetch CGM", comment: "The title text for the pull cgm Data cell") + switchCell.titleLabel.text = LocalizedString("Fetch CGM", comment: "The title text for the pull cgm Data cell") switchCell.`switch`?.addTarget(self, action: #selector(fetchCGMEnabledChanged(_:)), for: .valueChanged) cell = switchCell } @@ -137,11 +137,11 @@ class SettingsTableViewController: UITableViewController, TextFieldTableViewCont override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { switch Section(rawValue: section)! { case .about: - return NSLocalizedString("About", comment: "The title of the about section") + return LocalizedString("About", comment: "The title of the about section") case .upload: return nil case .configuration: - return NSLocalizedString("Configuration", comment: "The title of the configuration section in settings") + return LocalizedString("Configuration", comment: "The title of the configuration section in settings") } } @@ -156,7 +156,7 @@ class SettingsTableViewController: UITableViewController, TextFieldTableViewCont case .pumpID: let vc = TextFieldTableViewController() - vc.placeholder = NSLocalizedString("Enter the 6-digit pump ID", comment: "The placeholder text instructing users how to enter a pump ID") + vc.placeholder = LocalizedString("Enter the 6-digit pump ID", comment: "The placeholder text instructing users how to enter a pump ID") vc.value = dataManager.pumpSettings?.pumpID if let cell = tableView.cellForRow(at: indexPath) { diff --git a/RileyLink/Views/ValidatingIndicatorView.swift b/RileyLink/Views/ValidatingIndicatorView.swift index a54250966..91765a2d8 100644 --- a/RileyLink/Views/ValidatingIndicatorView.swift +++ b/RileyLink/Views/ValidatingIndicatorView.swift @@ -20,7 +20,7 @@ class ValidatingIndicatorView: UIView { override init(frame: CGRect) { super.init(frame: frame) label.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle.headline) - label.text = NSLocalizedString("Verifying", comment: "Label indicating validation is occurring") + label.text = LocalizedString("Verifying", comment: "Label indicating validation is occurring") label.sizeToFit() addSubview(indicatorView) diff --git a/RileyLink/de.lproj/InfoPlist.strings b/RileyLink/de.lproj/InfoPlist.strings new file mode 100644 index 000000000..e69de29bb diff --git a/RileyLink/de.lproj/Localizable.strings b/RileyLink/de.lproj/Localizable.strings new file mode 100644 index 000000000..07bf675cc --- /dev/null +++ b/RileyLink/de.lproj/Localizable.strings @@ -0,0 +1,54 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The title of the about section */ +"About" = "Über"; + +/* The title of the button to add the credentials for a service */ +"Add Account" = "Konto hinzufügen"; + +/* The title of the nightscout API secret credential */ +"API Secret" = "API Secret"; + +/* The title of the configuration section in settings */ +"Configuration" = "Konfiguration"; + +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "Konto löschen"; + +/* The placeholder text instructing users how to enter a pump ID */ +"Enter the 6-digit pump ID" = "Geben Sie die 6-stellige Pumpen-ID ein"; + +/* The title text for the pull cgm Data cell */ +"Fetch CGM" = "Hol CGM"; + +/* The placeholder text for the nightscout site URL credential */ +"http://mysite.azurewebsites.net" = "http://mysite.azurewebsites.net"; + +/* The title of the Nightscout service */ +"Nightscout" = "Nightscout"; + +/* The title text for the pump ID config value */ +"Pump ID" = "Pumpen-ID"; + +/* The title text for the pump Region config value */ +"Pump Region" = "Pumpenregion"; + +/* Instructions on selecting the pump region */ +"Pump Region is listed on the back of your pump as two of the last three characters of the model string, which reads something like this: MMT-551NAB, or MMT-515LWWS. If your model has an \"NA\" in it, then the region is North America. If your model has an \"WW\" in it, then the region is WorldWide." = "Die Pumpenregion wird auf der Rückseite der Pumpe als zwei der letzten drei Zeichen der Modellzeichenfolge aufgeführt, die etwa so lautet: MMT-551NAB oder MMT-515LWWS. Wenn Ihr Modell eine \"NA\" enthält, ist die Region North America. Wenn Ihr Modell ein \"WW\" enthält, ist die Region WorldWide."; + +/* The default placeholder string for a credential */ +"Required" = "Erforderlich"; + +/* The title of the nightscout site URL credential */ +"Site URL" = "Website URL"; + +/* The empty-state text for a configuration value */ +"Tap to set" = "Tippen, um festzulegen"; + +/* The title text for the nightscout upload enabled switch cell */ +"Upload To Nightscout" = "Upload zu NightScout"; + +/* Label indicating validation is occurring */ +"Verifying" = "Überprüfen"; + diff --git a/RileyLink/de.lproj/LoopKit.strings b/RileyLink/de.lproj/LoopKit.strings new file mode 100644 index 000000000..bc1fda9fb --- /dev/null +++ b/RileyLink/de.lproj/LoopKit.strings @@ -0,0 +1,3 @@ +/* The title of the action used to dismiss an error alert */ +"com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; + diff --git a/RileyLink/es.lproj/InfoPlist.strings b/RileyLink/es.lproj/InfoPlist.strings index 452bfea68..92e48b3b0 100644 --- a/RileyLink/es.lproj/InfoPlist.strings +++ b/RileyLink/es.lproj/InfoPlist.strings @@ -1,6 +1,6 @@ -/* (No Comment) */ +/* Bundle display name */ "CFBundleDisplayName" = "${PRODUCT_NAME}"; -/* (No Comment) */ +/* Bundle name */ "CFBundleName" = "${PRODUCT_NAME}"; diff --git a/RileyLink/es.lproj/Localizable.strings b/RileyLink/es.lproj/Localizable.strings index 25639514c..e1cdcc8e5 100644 --- a/RileyLink/es.lproj/Localizable.strings +++ b/RileyLink/es.lproj/Localizable.strings @@ -1,5 +1,5 @@ -/* The title of the nightscout API secret credential */ -"API Secret" = "Secreto API"; +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; /* The title of the about section */ "About" = "Respecto a"; @@ -7,6 +7,9 @@ /* The title of the button to add the credentials for a service */ "Add Account" = "Agregar Cuenta"; +/* The title of the nightscout API secret credential */ +"API Secret" = "Secreto API"; + /* The title of the configuration section in settings */ "Configuration" = "Configuración"; @@ -19,6 +22,9 @@ /* The title text for the pull cgm Data cell */ "Fetch CGM" = "Obtener de CGM"; +/* The placeholder text for the nightscout site URL credential */ +"http://mysite.azurewebsites.net" = "http://mysite.azurewebsites.net"; + /* The title of the Nightscout service */ "Nightscout" = "Nightscout"; @@ -29,7 +35,7 @@ "Pump Region" = "Región de Microinfusora"; /* Instructions on selecting the pump region */ -"Pump Region is listed on the back of your pump as two of the last three characters of the model string, which reads something like this: MMT-551NAB, or MMT-515LWWS. If your model has an \"NA\" in it, then the region is NorthAmerica. If your model has an \"WW\" in it, then the region is WorldWide." = "La región de la microinfusora puede ser encontrada impresa en la parte trasera como parte del código de modelo ( REF ), por ejemplo MMT-551AB o MMT-515LWWS. Si el código de modelo contiene \"NA\" o \"CA\", la región es Norte América. Si contiene \"WW\" la región es Mundial."; +"Pump Region is listed on the back of your pump as two of the last three characters of the model string, which reads something like this: MMT-551NAB, or MMT-515LWWS. If your model has an \"NA\" in it, then the region is North America. If your model has an \"WW\" in it, then the region is WorldWide." = "La región de la microinfusora puede ser encontrada impresa en la parte trasera como parte del código de modelo (REF), por ejemplo MMT-551AB o MMT-515LWWS. Si el código de modelo contiene \"NA\" o \"CA\", la región es Norte América. Si contiene \"WW\" la región es Mundial."; /* The default placeholder string for a credential */ "Required" = "Requerido"; @@ -44,8 +50,5 @@ "Upload To Nightscout" = "Subir a Nightscout"; /* Label indicating validation is occurring */ -"Verifying" = "verificando"; - -/* The placeholder text for the nightscout site URL credential */ -"http://mysite.azurewebsites.net" = "http://mysite.azurewebsites.net"; +"Verifying" = "Verificando"; diff --git a/RileyLink/fr.lproj/InfoPlist.strings b/RileyLink/fr.lproj/InfoPlist.strings new file mode 100644 index 000000000..e69de29bb diff --git a/RileyLink/fr.lproj/Localizable.strings b/RileyLink/fr.lproj/Localizable.strings new file mode 100644 index 000000000..44a519f68 --- /dev/null +++ b/RileyLink/fr.lproj/Localizable.strings @@ -0,0 +1,54 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The title of the about section */ +"About" = "À propos"; + +/* The title of the button to add the credentials for a service */ +"Add Account" = "Ajouter Compte"; + +/* The title of the nightscout API secret credential */ +"API Secret" = "API Secret"; + +/* The title of the configuration section in settings */ +"Configuration" = "Configuration"; + +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "Effacer Compte"; + +/* The placeholder text instructing users how to enter a pump ID */ +"Enter the 6-digit pump ID" = "Entrée l’ID de pompe de 6 chiffres"; + +/* The title text for the pull cgm Data cell */ +"Fetch CGM" = "Obtenir CGM"; + +/* The placeholder text for the nightscout site URL credential */ +"http://mysite.azurewebsites.net" = "http://mysite.azurewebsites.net"; + +/* The title of the Nightscout service */ +"Nightscout" = "Nightscout"; + +/* The title text for the pump ID config value */ +"Pump ID" = "ID de la Pompe"; + +/* The title text for the pump Region config value */ +"Pump Region" = "Région de Pompe"; + +/* Instructions on selecting the pump region */ +"Pump Region is listed on the back of your pump as two of the last three characters of the model string, which reads something like this: MMT-551NAB, or MMT-515LWWS. If your model has an \"NA\" in it, then the region is North America. If your model has an \"WW\" in it, then the region is WorldWide." = "La région de la pompe est indiquée au dos de votre pompe par deux des trois derniers caractères de la chaîne du modèle, qui se lit comme suit: MMT-551NAB ou MMT-515LWWS. Si votre modèle contient un \"NA\" ou \"CA\", la région est l’Amérique du Nord. Si votre modèle contient un \"WW\", alors la région est Monde Entier."; + +/* The default placeholder string for a credential */ +"Required" = "Requis"; + +/* The title of the nightscout site URL credential */ +"Site URL" = "URL du Site"; + +/* The empty-state text for a configuration value */ +"Tap to set" = "Appuyez pour définir"; + +/* The title text for the nightscout upload enabled switch cell */ +"Upload To Nightscout" = "Télécharger vers Nightscout"; + +/* Label indicating validation is occurring */ +"Verifying" = "Validation en cours"; + diff --git a/RileyLink/fr.lproj/LoopKit.strings b/RileyLink/fr.lproj/LoopKit.strings new file mode 100644 index 000000000..bc1fda9fb --- /dev/null +++ b/RileyLink/fr.lproj/LoopKit.strings @@ -0,0 +1,3 @@ +/* The title of the action used to dismiss an error alert */ +"com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; + diff --git a/RileyLink/it.lproj/InfoPlist.strings b/RileyLink/it.lproj/InfoPlist.strings new file mode 100644 index 000000000..e69de29bb diff --git a/RileyLink/it.lproj/Localizable.strings b/RileyLink/it.lproj/Localizable.strings new file mode 100644 index 000000000..b322f0404 --- /dev/null +++ b/RileyLink/it.lproj/Localizable.strings @@ -0,0 +1,54 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The title of the about section */ +"About" = "Informazioni"; + +/* The title of the button to add the credentials for a service */ +"Add Account" = "Aggiungi Account"; + +/* The title of the nightscout API secret credential */ +"API Secret" = "API Secret"; + +/* The title of the configuration section in settings */ +"Configuration" = "Configurazione"; + +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "Cancella Account"; + +/* The placeholder text instructing users how to enter a pump ID */ +"Enter the 6-digit pump ID" = "Inserire 6-numeri ID microinfusore"; + +/* The title text for the pull cgm Data cell */ +"Fetch CGM" = "Sincronizza Sensore"; + +/* The placeholder text for the nightscout site URL credential */ +"http://mysite.azurewebsites.net" = "http://mysite.azurewebsites.net"; + +/* The title of the Nightscout service */ +"Nightscout" = "Nightscout"; + +/* The title text for the pump ID config value */ +"Pump ID" = "ID Microinfusore"; + +/* The title text for the pump Region config value */ +"Pump Region" = "Región de Microinfusora"; + +/* Instructions on selecting the pump region */ +"Pump Region is listed on the back of your pump as two of the last three characters of the model string, which reads something like this: MMT-551NAB, or MMT-515LWWS. If your model has an \"NA\" in it, then the region is North America. If your model has an \"WW\" in it, then the region is WorldWide." = "La provenienza del microinfusore è segnalata sul retro del microinfusore come i due degli ultimi tre caratteri della stringa del modello, che si legge in questo modo: MMT-551NAB o MMT-515LWWS. Se il tuo modello ha un \"NA\" o \"CA\" in esso, la regione è Nord America. Se il tuo modello ha un \"WW\" al suo interno, la regione è Internazionale."; + +/* The default placeholder string for a credential */ +"Required" = "Necessario"; + +/* The title of the nightscout site URL credential */ +"Site URL" = "Sito URL"; + +/* The empty-state text for a configuration value */ +"Tap to set" = "Premi per impostare"; + +/* The title text for the nightscout upload enabled switch cell */ +"Upload To Nightscout" = "Carica su Nightscout"; + +/* Label indicating validation is occurring */ +"Verifying" = "Sto verificando"; + diff --git a/RileyLink/it.lproj/LoopKit.strings b/RileyLink/it.lproj/LoopKit.strings new file mode 100644 index 000000000..bc1fda9fb --- /dev/null +++ b/RileyLink/it.lproj/LoopKit.strings @@ -0,0 +1,3 @@ +/* The title of the action used to dismiss an error alert */ +"com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; + diff --git a/RileyLink/nb.lproj/InfoPlist.strings b/RileyLink/nb.lproj/InfoPlist.strings new file mode 100644 index 000000000..e69de29bb diff --git a/RileyLink/nb.lproj/Localizable.strings b/RileyLink/nb.lproj/Localizable.strings new file mode 100644 index 000000000..5e90e9c80 --- /dev/null +++ b/RileyLink/nb.lproj/Localizable.strings @@ -0,0 +1,54 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The title of the about section */ +"About" = "Om"; + +/* The title of the button to add the credentials for a service */ +"Add Account" = "Legg til konto"; + +/* The title of the nightscout API secret credential */ +"API Secret" = "API Secret"; + +/* The title of the configuration section in settings */ +"Configuration" = "Konfigurasjon"; + +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "Slett Konto"; + +/* The placeholder text instructing users how to enter a pump ID */ +"Enter the 6-digit pump ID" = "Skriv 6-sifret pumpe-ID"; + +/* The title text for the pull cgm Data cell */ +"Fetch CGM" = "Hent CGM"; + +/* The placeholder text for the nightscout site URL credential */ +"http://mysite.azurewebsites.net" = "http://mysite.azurewebsites.net"; + +/* The title of the Nightscout service */ +"Nightscout" = "Nightscout"; + +/* The title text for the pump ID config value */ +"Pump ID" = "Pumpe-ID"; + +/* The title text for the pump Region config value */ +"Pump Region" = "Pumperegion"; + +/* Instructions on selecting the pump region */ +"Pump Region is listed on the back of your pump as two of the last three characters of the model string, which reads something like this: MMT-551NAB, or MMT-515LWWS. If your model has an \"NA\" in it, then the region is North America. If your model has an \"WW\" in it, then the region is WorldWide." = "Pumperegion er merket på baksiden av din pumpe som to av de tre siste tegnene i din modell, og ser ut noe som dette: MMT-551NAB, eller MMT-515LWWS. Hvis pumpa di har \"NA\" eller \"CA\" i navnet er regionen Nord-Amerika. Hvis den derimot har \"WW\" i navnet er regionen WorldWide."; + +/* The default placeholder string for a credential */ +"Required" = "Påkrevd"; + +/* The title of the nightscout site URL credential */ +"Site URL" = "Nettstedslenke (URL)"; + +/* The empty-state text for a configuration value */ +"Tap to set" = "Trykk for å bekrefte innstilling"; + +/* The title text for the nightscout upload enabled switch cell */ +"Upload To Nightscout" = "Last opp til Nightscout"; + +/* Label indicating validation is occurring */ +"Verifying" = "Bekrefter"; + diff --git a/RileyLink/nb.lproj/LoopKit.strings b/RileyLink/nb.lproj/LoopKit.strings new file mode 100644 index 000000000..bc1fda9fb --- /dev/null +++ b/RileyLink/nb.lproj/LoopKit.strings @@ -0,0 +1,3 @@ +/* The title of the action used to dismiss an error alert */ +"com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; + diff --git a/RileyLink/nl.lproj/InfoPlist.strings b/RileyLink/nl.lproj/InfoPlist.strings new file mode 100644 index 000000000..92e48b3b0 --- /dev/null +++ b/RileyLink/nl.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "${PRODUCT_NAME}"; + +/* Bundle name */ +"CFBundleName" = "${PRODUCT_NAME}"; + diff --git a/RileyLink/nl.lproj/Localizable.strings b/RileyLink/nl.lproj/Localizable.strings new file mode 100644 index 000000000..ad1f13071 --- /dev/null +++ b/RileyLink/nl.lproj/Localizable.strings @@ -0,0 +1,54 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The title of the about section */ +"About" = "Over"; + +/* The title of the button to add the credentials for a service */ +"Add Account" = "Voeg account toe"; + +/* The title of the nightscout API secret credential */ +"API Secret" = "API Secret"; + +/* The title of the configuration section in settings */ +"Configuration" = "Configuratie"; + +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "Verwijder account"; + +/* The placeholder text instructing users how to enter a pump ID */ +"Enter the 6-digit pump ID" = "Voer het 6-cijferige ID van de pomp in"; + +/* The title text for the pull cgm Data cell */ +"Fetch CGM" = "Haal CGM op"; + +/* The placeholder text for the nightscout site URL credential */ +"http://mysite.azurewebsites.net" = "http://mysite.azurewebsites.net"; + +/* The title of the Nightscout service */ +"Nightscout" = "Nightscout"; + +/* The title text for the pump ID config value */ +"Pump ID" = "Pomp ID"; + +/* The title text for the pump Region config value */ +"Pump Region" = "Pomp regio"; + +/* Instructions on selecting the pump region */ +"Pump Region is listed on the back of your pump as two of the last three characters of the model string, which reads something like this: MMT-551NAB, or MMT-515LWWS. If your model has an \"NA\" in it, then the region is North America. If your model has an \"WW\" in it, then the region is WorldWide." = "Pump Regio staat op de achterkant van uw pomp als twee van de laatste drie tekens van de modeltekenreeks, die er als volgt uitziet: MMT-551NAB of MMT-515LWWS. Als uw model een \"NA\" bevat, dan is de regio Noord Amerika. Als uw model een \"WW\" bevat, is de regio Wereldwijd."; + +/* The default placeholder string for a credential */ +"Required" = "Vereist"; + +/* The title of the nightscout site URL credential */ +"Site URL" = "Webpagina URL"; + +/* The empty-state text for a configuration value */ +"Tap to set" = "Instellen…"; + +/* The title text for the nightscout upload enabled switch cell */ +"Upload To Nightscout" = "Uploaden naar Nightscout"; + +/* Label indicating validation is occurring */ +"Verifying" = "Verifiëren"; + diff --git a/RileyLink/nl.lproj/LoopKit.strings b/RileyLink/nl.lproj/LoopKit.strings new file mode 100644 index 000000000..bc1fda9fb --- /dev/null +++ b/RileyLink/nl.lproj/LoopKit.strings @@ -0,0 +1,3 @@ +/* The title of the action used to dismiss an error alert */ +"com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; + diff --git a/RileyLink/ru.lproj/InfoPlist.strings b/RileyLink/ru.lproj/InfoPlist.strings index 874e8a453..92e48b3b0 100644 --- a/RileyLink/ru.lproj/InfoPlist.strings +++ b/RileyLink/ru.lproj/InfoPlist.strings @@ -1 +1,6 @@ -/* No Localized Strings */ +/* Bundle display name */ +"CFBundleDisplayName" = "${PRODUCT_NAME}"; + +/* Bundle name */ +"CFBundleName" = "${PRODUCT_NAME}"; + diff --git a/RileyLink/ru.lproj/Localizable.strings b/RileyLink/ru.lproj/Localizable.strings index 26b71b186..ad8630efc 100644 --- a/RileyLink/ru.lproj/Localizable.strings +++ b/RileyLink/ru.lproj/Localizable.strings @@ -1,5 +1,5 @@ -/* The title of the nightscout API secret credential */ -"API Secret" = "API secret"; +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; /* The title of the about section */ "About" = "Про"; @@ -7,6 +7,9 @@ /* The title of the button to add the credentials for a service */ "Add Account" = "Добавить учетную запись"; +/* The title of the nightscout API secret credential */ +"API Secret" = "API secret"; + /* The title of the configuration section in settings */ "Configuration" = "Конфигурация"; @@ -19,6 +22,9 @@ /* The title text for the pull cgm Data cell */ "Fetch CGM" = "Получить данные мониторинга"; +/* The placeholder text for the nightscout site URL credential */ +"http://mysite.azurewebsites.net" = "http://мойсайт. azurewebsites.net"; + /* The title of the Nightscout service */ "Nightscout" = "Nightscout"; @@ -29,7 +35,7 @@ "Pump Region" = "Регион помпы"; /* Instructions on selecting the pump region */ -"Pump Region is listed on the back of your pump as two of the last three characters of the model string, which reads something like this: MMT-551NAB, or MMT-515LWWS. If your model has an \"NA\" in it, then the region is NorthAmerica. If your model has an \"WW\" in it, then the region is WorldWide." = "Регион помпы находится на задней стенке помпы в виде двух из последних трех знаков вида MMT-551NAB или MMT-515LWWS. Если ваша модель имеет \"NA\" то это Северная Америка. Если \"WW\", то это остальной мир."; +"Pump Region is listed on the back of your pump as two of the last three characters of the model string, which reads something like this: MMT-551NAB, or MMT-515LWWS. If your model has an \"NA\" in it, then the region is North America. If your model has an \"WW\" in it, then the region is WorldWide." = "Регион помпы находится на задней стенке помпы в виде двух из последних трех знаков вида MMT-551NAB или MMT-515LWWS. Если ваша модель имеет \"NA\" то это Северная Америка. Если \"WW\", то это остальной мир."; /* The default placeholder string for a credential */ "Required" = "Обязательное значение"; @@ -46,6 +52,3 @@ /* Label indicating validation is occurring */ "Verifying" = "Верифицируется"; -/* The placeholder text for the nightscout site URL credential */ -"http://mysite.azurewebsites.net" = "https://мойсайт. azurewebsites.net"; - diff --git a/RileyLink/zh-Hans.lproj/InfoPlist.strings b/RileyLink/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 000000000..92e48b3b0 --- /dev/null +++ b/RileyLink/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1,6 @@ +/* Bundle display name */ +"CFBundleDisplayName" = "${PRODUCT_NAME}"; + +/* Bundle name */ +"CFBundleName" = "${PRODUCT_NAME}"; + diff --git a/RileyLink/zh-Hans.lproj/Localizable.strings b/RileyLink/zh-Hans.lproj/Localizable.strings new file mode 100644 index 000000000..4b1d010d6 --- /dev/null +++ b/RileyLink/zh-Hans.lproj/Localizable.strings @@ -0,0 +1,54 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The title of the about section */ +"About" = "关于"; + +/* The title of the button to add the credentials for a service */ +"Add Account" = "添加账户"; + +/* The title of the nightscout API secret credential */ +"API Secret" = "API密码"; + +/* The title of the configuration section in settings */ +"Configuration" = "配置"; + +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "删除账户"; + +/* The placeholder text instructing users how to enter a pump ID */ +"Enter the 6-digit pump ID" = "请输入6位数字胰岛素泵序列号"; + +/* The title text for the pull cgm Data cell */ +"Fetch CGM" = "获取动态血糖数据"; + +/* The placeholder text for the nightscout site URL credential */ +"http://mysite.azurewebsites.net" = "http://mysite.azurewebsites.net"; + +/* The title of the Nightscout service */ +"Nightscout" = "Nightscout"; + +/* The title text for the pump ID config value */ +"Pump ID" = "胰岛素泵序列号"; + +/* The title text for the pump Region config value */ +"Pump Region" = "胰岛素泵所属销售市场i"; + +/* Instructions on selecting the pump region */ +"Pump Region is listed on the back of your pump as two of the last three characters of the model string, which reads something like this: MMT-551NAB, or MMT-515LWWS. If your model has an \"NA\" in it, then the region is North America. If your model has an \"WW\" in it, then the region is WorldWide." = "泵的区域可作为型号(REF)的一部分印在背面,例如:MMT-551NAB或MMT-515LWWS。如果型号包含“NA”或“CA”,则该区域为北美。如果如果包含“WW”,则该区域是全球范围的。"; + +/* The default placeholder string for a credential */ +"Required" = "需要"; + +/* The title of the nightscout site URL credential */ +"Site URL" = "网址"; + +/* The empty-state text for a configuration value */ +"Tap to set" = "点击设置"; + +/* The title text for the nightscout upload enabled switch cell */ +"Upload To Nightscout" = "上传到Nightscout"; + +/* Label indicating validation is occurring */ +"Verifying" = "确认"; + diff --git a/RileyLink/zh-Hans.lproj/LoopKit.strings b/RileyLink/zh-Hans.lproj/LoopKit.strings new file mode 100644 index 000000000..bc1fda9fb --- /dev/null +++ b/RileyLink/zh-Hans.lproj/LoopKit.strings @@ -0,0 +1,3 @@ +/* The title of the action used to dismiss an error alert */ +"com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; + diff --git a/RileyLinkBLEKit/Base.lproj/Localizable.strings b/RileyLinkBLEKit/Base.lproj/Localizable.strings new file mode 100644 index 000000000..b8344eccc --- /dev/null +++ b/RileyLinkBLEKit/Base.lproj/Localizable.strings @@ -0,0 +1,30 @@ +/* Write size limit exceeded error description (1: size limit) */ +"Data exceeded maximum size of %@ bytes" = "Data exceeded maximum size of %@ bytes"; + +/* Invalid input error description (1: input) */ +"Input %@ is invalid" = "Input %@ is invalid"; + +/* Recovery suggestion for unknown peripheral characteristic */ +"Make sure the device is nearby, and the issue should resolve automatically" = "Make sure the device is nearby, and the issue should resolve automatically"; + +/* Timeout error description */ +"Peripheral did not respond in time" = "Peripheral did not respond in time"; + +/* Not ready error description */ +"Peripheral isnʼt connected" = "Peripheral isnʼt connected"; + +/* Response timeout error description */ +"Pump did not respond in time" = "Pump did not respond in time"; + +/* Invalid response error description (1: response) */ +"Response %@ is invalid" = "Response %@ is invalid"; + +/* Unsupported command error description */ +"RileyLink firmware does not support the %@ command" = "RileyLink firmware does not support the %@ command"; + +/* Failure reason: unknown peripheral characteristic */ +"The RileyLink was temporarily disconnected" = "The RileyLink was temporarily disconnected"; + +/* Error description */ +"Unknown characteristic" = "Unknown characteristic"; + diff --git a/RileyLinkBLEKit/PeripheralManagerError.swift b/RileyLinkBLEKit/PeripheralManagerError.swift index f6f1f0670..871c3f0ed 100644 --- a/RileyLinkBLEKit/PeripheralManagerError.swift +++ b/RileyLinkBLEKit/PeripheralManagerError.swift @@ -22,11 +22,11 @@ extension PeripheralManagerError: LocalizedError { case .cbPeripheralError(let error): return error.localizedDescription case .notReady: - return NSLocalizedString("Peripheral isnʼt connected", comment: "Not ready error description") + return LocalizedString("Peripheral isnʼt connected", comment: "Not ready error description") case .timeout: - return NSLocalizedString("Peripheral did not respond in time", comment: "Timeout error description") + return LocalizedString("Peripheral did not respond in time", comment: "Timeout error description") case .unknownCharacteristic: - return NSLocalizedString("Unknown characteristic", comment: "Error description") + return LocalizedString("Unknown characteristic", comment: "Error description") } } @@ -35,7 +35,7 @@ extension PeripheralManagerError: LocalizedError { case .cbPeripheralError(let error as NSError): return error.localizedFailureReason case .unknownCharacteristic: - return NSLocalizedString("The RileyLink was temporarily disconnected", comment: "Failure reason: unknown peripheral characteristic") + return LocalizedString("The RileyLink was temporarily disconnected", comment: "Failure reason: unknown peripheral characteristic") default: return nil } @@ -46,7 +46,7 @@ extension PeripheralManagerError: LocalizedError { case .cbPeripheralError(let error as NSError): return error.localizedRecoverySuggestion case .unknownCharacteristic: - return NSLocalizedString("Make sure the device is nearby, and the issue should resolve automatically", comment: "Recovery suggestion for unknown peripheral characteristic") + return LocalizedString("Make sure the device is nearby, and the issue should resolve automatically", comment: "Recovery suggestion for unknown peripheral characteristic") default: return nil } diff --git a/RileyLinkBLEKit/RileyLinkDeviceError.swift b/RileyLinkBLEKit/RileyLinkDeviceError.swift index 8cee2d75c..fcd2c49d0 100644 --- a/RileyLinkBLEKit/RileyLinkDeviceError.swift +++ b/RileyLinkBLEKit/RileyLinkDeviceError.swift @@ -22,15 +22,15 @@ extension RileyLinkDeviceError: LocalizedError { case .peripheralManagerError(let error): return error.errorDescription case .invalidInput(let input): - return String(format: NSLocalizedString("Input %@ is invalid", comment: "Invalid input error description (1: input)"), String(describing: input)) + return String(format: LocalizedString("Input %@ is invalid", comment: "Invalid input error description (1: input)"), String(describing: input)) case .invalidResponse(let response): - return String(format: NSLocalizedString("Response %@ is invalid", comment: "Invalid response error description (1: response)"), String(describing: response)) + return String(format: LocalizedString("Response %@ is invalid", comment: "Invalid response error description (1: response)"), String(describing: response)) case .writeSizeLimitExceeded(let maxLength): - return String(format: NSLocalizedString("Data exceededs maximum size of %@ bytes", comment: "Write size limit exceeded error description (1: size limit)"), NumberFormatter.localizedString(from: NSNumber(value: maxLength), number: .none)) + return String(format: LocalizedString("Data exceededs maximum size of %@ bytes", comment: "Write size limit exceeded error description (1: size limit)"), NumberFormatter.localizedString(from: NSNumber(value: maxLength), number: .none)) case .responseTimeout: - return NSLocalizedString("Pump did not respond in time", comment: "Response timeout error description") + return LocalizedString("Pump did not respond in time", comment: "Response timeout error description") case .unsupportedCommand(let command): - return String(format: NSLocalizedString("RileyLink firmware does not support the %@ command", comment: "Unsupported command error description"), String(describing: command)) + return String(format: LocalizedString("RileyLink firmware does not support the %@ command", comment: "Unsupported command error description"), String(describing: command)) } } diff --git a/RileyLinkBLEKit/de.lproj/InfoPlist.strings b/RileyLinkBLEKit/de.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkBLEKit/de.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkBLEKit/de.lproj/Localizable.strings b/RileyLinkBLEKit/de.lproj/Localizable.strings new file mode 100644 index 000000000..7b8a3ae6a --- /dev/null +++ b/RileyLinkBLEKit/de.lproj/Localizable.strings @@ -0,0 +1,30 @@ +/* Write size limit exceeded error description (1: size limit) */ +"Data exceeded maximum size of %@ bytes" = "Datenvolumen übersteigt die Maximalgröße von %@ Bytes"; + +/* Invalid input error description (1: input) */ +"Input %@ is invalid" = "Eingabe %@ ist ungültig"; + +/* Recovery suggestion for unknown peripheral characteristic */ +"Make sure the device is nearby, and the issue should resolve automatically" = "Sicherstellen, dass sich das Gerät in der Nähe befindet, um das Problem automatisch zu beheben"; + +/* Timeout error description */ +"Peripheral did not respond in time" = "Peripheres Gerät antwortet nicht rechtzeitig"; + +/* Not ready error description */ +"Peripheral isnʼt connected" = "Peripheres Gerät ist nicht verbunden"; + +/* Response timeout error description */ +"Pump did not respond in time" = "Pumpe antwortet nicht rechtzeitig"; + +/* Invalid response error description (1: response) */ +"Response %@ is invalid" = "Antwort %@ ist ungültig"; + +/* Unsupported command error description */ +"RileyLink firmware does not support the %@ command" = "RileyLink Firmware unterstützt den Befehl %@ nicht"; + +/* Failure reason: unknown peripheral characteristic */ +"The RileyLink was temporarily disconnected" = "Verbindung zu RileyLink wurde vorübergehend unterbrochen"; + +/* Error description */ +"Unknown characteristic" = "Unbekannte Charakteristik"; + diff --git a/RileyLinkBLEKit/es.lproj/InfoPlist.strings b/RileyLinkBLEKit/es.lproj/InfoPlist.strings index f8e9a2b43..bbcf8f904 100644 --- a/RileyLinkBLEKit/es.lproj/InfoPlist.strings +++ b/RileyLinkBLEKit/es.lproj/InfoPlist.strings @@ -1,3 +1,3 @@ -/* (No Comment) */ +/* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; diff --git a/RileyLinkBLEKit/es.lproj/Localizable.strings b/RileyLinkBLEKit/es.lproj/Localizable.strings new file mode 100644 index 000000000..3da4f3745 --- /dev/null +++ b/RileyLinkBLEKit/es.lproj/Localizable.strings @@ -0,0 +1,27 @@ +/* Invalid input error description (1: input) */ +"Input %@ is invalid" = "El dato %@ es inválido"; + +/* Recovery suggestion for unknown peripheral characteristic */ +"Make sure the device is nearby, and the issue should resolve automatically" = "Asegúrate de que los dispositivos estén cercanos. El problema deberá solucionarse automáticamente"; + +/* Timeout error description */ +"Peripheral did not respond in time" = "El dispositivo periférico no respondió a tiempo"; + +/* Not ready error description */ +"Peripheral isnʼt connected" = "El dispositivo periférico no está conectado"; + +/* Response timeout error description */ +"Pump did not respond in time" = "La microinfusora no respondió a tiempo"; + +/* Invalid response error description (1: response) */ +"Response %@ is invalid" = "Le respuesta %@ es inválida"; + +/* Unsupported command error description */ +"RileyLink firmware does not support the %@ command" = "RileyLink firmware no soporta el comando %@"; + +/* Failure reason: unknown peripheral characteristic */ +"The RileyLink was temporarily disconnected" = "RileyLink fue temporalmente desconectado"; + +/* Error description */ +"Unknown characteristic" = "Característica desconocida"; + diff --git a/RileyLinkBLEKit/fr.lproj/InfoPlist.strings b/RileyLinkBLEKit/fr.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkBLEKit/fr.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkBLEKit/fr.lproj/Localizable.strings b/RileyLinkBLEKit/fr.lproj/Localizable.strings new file mode 100644 index 000000000..c1f62a3c0 --- /dev/null +++ b/RileyLinkBLEKit/fr.lproj/Localizable.strings @@ -0,0 +1,27 @@ +/* Invalid input error description (1: input) */ +"Input %@ is invalid" = "L’entrée %@ n’est pas valide"; + +/* Recovery suggestion for unknown peripheral characteristic */ +"Make sure the device is nearby, and the issue should resolve automatically" = "Assurez-vous que le périphérique est à proximité et que le problème doit être résolu automatiquement"; + +/* Timeout error description */ +"Peripheral did not respond in time" = "Le périphérique n’a pas répondu à temps"; + +/* Not ready error description */ +"Peripheral isnʼt connected" = "Le périphérique n’est pas connecté"; + +/* Response timeout error description */ +"Pump did not respond in time" = "La pompe n’a pas répondu à temps"; + +/* Invalid response error description (1: response) */ +"Response %@ is invalid" = "Réponse %@ n’est pas valide"; + +/* Unsupported command error description */ +"RileyLink firmware does not support the %@ command" = "Le firmware de RileyLink ne prend pas en charge la commande %@"; + +/* Failure reason: unknown peripheral characteristic */ +"The RileyLink was temporarily disconnected" = "Le RileyLink a été temporairement déconnecté"; + +/* Error description */ +"Unknown characteristic" = "Caractéristique inconnue"; + diff --git a/RileyLinkBLEKit/it.lproj/InfoPlist.strings b/RileyLinkBLEKit/it.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkBLEKit/it.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkBLEKit/it.lproj/Localizable.strings b/RileyLinkBLEKit/it.lproj/Localizable.strings new file mode 100644 index 000000000..9d7d60881 --- /dev/null +++ b/RileyLinkBLEKit/it.lproj/Localizable.strings @@ -0,0 +1,30 @@ +/* Write size limit exceeded error description (1: size limit) */ +"Data exceeded maximum size of %@ bytes" = "I dati superano la dimensione massima di %@ bytes"; + +/* Invalid input error description (1: input) */ +"Input %@ is invalid" = "Il dato inserito %@ non e' valido"; + +/* Recovery suggestion for unknown peripheral characteristic */ +"Make sure the device is nearby, and the issue should resolve automatically" = "Fai attenzione che il device sia vicino e il problema dovrebbe risolversi automaticamente"; + +/* Timeout error description */ +"Peripheral did not respond in time" = "La periferica non ha risposto nel tempo limite"; + +/* Not ready error description */ +"Peripheral isnʼt connected" = "La periferica non e' connessa"; + +/* Response timeout error description */ +"Pump did not respond in time" = "Il microinfusore non ha risposto nel tempo limite"; + +/* Invalid response error description (1: response) */ +"Response %@ is invalid" = "La risposta %@ non e' valida"; + +/* Unsupported command error description */ +"RileyLink firmware does not support the %@ command" = "Il firmware del RileyLink non supporta il comando %@"; + +/* Failure reason: unknown peripheral characteristic */ +"The RileyLink was temporarily disconnected" = "Il RileyLink e' stato temporaneamente disconnesso"; + +/* Error description */ +"Unknown characteristic" = "Caratteristiche sconosciute"; + diff --git a/RileyLinkBLEKit/nb.lproj/InfoPlist.strings b/RileyLinkBLEKit/nb.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkBLEKit/nb.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkBLEKit/nb.lproj/Localizable.strings b/RileyLinkBLEKit/nb.lproj/Localizable.strings new file mode 100644 index 000000000..9f34065a1 --- /dev/null +++ b/RileyLinkBLEKit/nb.lproj/Localizable.strings @@ -0,0 +1,30 @@ +/* Write size limit exceeded error description (1: size limit) */ +"Data exceeded maximum size of %@ bytes" = "Data overskrider maks størrelse på %@ bytes"; + +/* Invalid input error description (1: input) */ +"Input %@ is invalid" = "Inndata %@ er ikke gyldig"; + +/* Recovery suggestion for unknown peripheral characteristic */ +"Make sure the device is nearby, and the issue should resolve automatically" = "Forsikre deg at enheten er i nærheten, så skal problemet løse seg selv automatisk."; + +/* Timeout error description */ +"Peripheral did not respond in time" = "Tilbehøret svarte ikke i tide"; + +/* Not ready error description */ +"Peripheral isnʼt connected" = "Tilbehøret er ikke tilkoblet"; + +/* Response timeout error description */ +"Pump did not respond in time" = "Pumpen svarte ikke i tide"; + +/* Invalid response error description (1: response) */ +"Response %@ is invalid" = "Responsen %@ er ikke gyldig"; + +/* Unsupported command error description */ +"RileyLink firmware does not support the %@ command" = "RileyLink firmware støtter ikke %@ kommandoen"; + +/* Failure reason: unknown peripheral characteristic */ +"The RileyLink was temporarily disconnected" = "RileyLink ble midlertidig frakoblet"; + +/* Error description */ +"Unknown characteristic" = "Ukjent karakteristikk"; + diff --git a/RileyLinkBLEKit/nl.lproj/InfoPlist.strings b/RileyLinkBLEKit/nl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkBLEKit/nl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkBLEKit/nl.lproj/Localizable.strings b/RileyLinkBLEKit/nl.lproj/Localizable.strings new file mode 100644 index 000000000..ea234d6ef --- /dev/null +++ b/RileyLinkBLEKit/nl.lproj/Localizable.strings @@ -0,0 +1,30 @@ +/* Write size limit exceeded error description (1: size limit) */ +"Data exceeded maximum size of %@ bytes" = "Data overschrijdt maximale grootte van %@ bytes"; + +/* Invalid input error description (1: input) */ +"Input %@ is invalid" = "Invoer %@ is ongeldig"; + +/* Recovery suggestion for unknown peripheral characteristic */ +"Make sure the device is nearby, and the issue should resolve automatically" = "Zorg ervoor dat het apparaat in de buurt is en het probleem zal automatisch worden opgelost."; + +/* Timeout error description */ +"Peripheral did not respond in time" = "Apparaat reageerde niet op tijd"; + +/* Not ready error description */ +"Peripheral isnʼt connected" = "Apparaat is niet verbonden"; + +/* Response timeout error description */ +"Pump did not respond in time" = "Pomp reageerde niet op tijd"; + +/* Invalid response error description (1: response) */ +"Response %@ is invalid" = "Antwoord %@ is ongeldig"; + +/* Unsupported command error description */ +"RileyLink firmware does not support the %@ command" = "De RileyLink firmware ondersteund niet het %@ commando"; + +/* Failure reason: unknown peripheral characteristic */ +"The RileyLink was temporarily disconnected" = "The RileyLink was tijdelijk niet verbonden"; + +/* Error description */ +"Unknown characteristic" = "Onbekende eigenschap"; + diff --git a/RileyLinkBLEKit/ru.lproj/InfoPlist.strings b/RileyLinkBLEKit/ru.lproj/InfoPlist.strings index 874e8a453..bbcf8f904 100644 --- a/RileyLinkBLEKit/ru.lproj/InfoPlist.strings +++ b/RileyLinkBLEKit/ru.lproj/InfoPlist.strings @@ -1 +1,3 @@ -/* No Localized Strings */ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkBLEKit/ru.lproj/Localizable.strings b/RileyLinkBLEKit/ru.lproj/Localizable.strings new file mode 100644 index 000000000..50b9996cb --- /dev/null +++ b/RileyLinkBLEKit/ru.lproj/Localizable.strings @@ -0,0 +1,30 @@ +/* Write size limit exceeded error description (1: size limit) */ +"Data exceeded maximum size of %@ bytes" = "Данные превышают максимальный объем %@ байт"; + +/* Invalid input error description (1: input) */ +"Input %@ is invalid" = "Введенная величина %@ неверна"; + +/* Recovery suggestion for unknown peripheral characteristic */ +"Make sure the device is nearby, and the issue should resolve automatically" = "Убедитесь в том, что устройство находится рядом и проблема должна устраниться автоматически"; + +/* Timeout error description */ +"Peripheral did not respond in time" = "Периферийное устройство не отозвалось вовремя"; + +/* Not ready error description */ +"Peripheral isnʼt connected" = "Соединение с периферийным устройством не установлено"; + +/* Response timeout error description */ +"Pump did not respond in time" = "Отклик от помпы не получен вовремя"; + +/* Invalid response error description (1: response) */ +"Response %@ is invalid" = "Отклик %@ неверен"; + +/* Unsupported command error description */ +"RileyLink firmware does not support the %@ command" = "Прошивка RileyLink не поддерживает команду %@"; + +/* Failure reason: unknown peripheral characteristic */ +"The RileyLink was temporarily disconnected" = "Связь с RileyLink была временно потеряна"; + +/* Error description */ +"Unknown characteristic" = "Неизвестная характеристика"; + diff --git a/RileyLinkBLEKit/zh-Hans.lproj/InfoPlist.strings b/RileyLinkBLEKit/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkBLEKit/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkBLEKit/zh-Hans.lproj/Localizable.strings b/RileyLinkBLEKit/zh-Hans.lproj/Localizable.strings new file mode 100644 index 000000000..8f932a421 --- /dev/null +++ b/RileyLinkBLEKit/zh-Hans.lproj/Localizable.strings @@ -0,0 +1,30 @@ +/* Write size limit exceeded error description (1: size limit) */ +"Data exceeded maximum size of %@ bytes" = "数据超过最大%@字节"; + +/* Invalid input error description (1: input) */ +"Input %@ is invalid" = "输入%@无效"; + +/* Recovery suggestion for unknown peripheral characteristic */ +"Make sure the device is nearby, and the issue should resolve automatically" = "确保设备在附近,该问题可自动解决"; + +/* Timeout error description */ +"Peripheral did not respond in time" = "外设没有及时响应"; + +/* Not ready error description */ +"Peripheral isnʼt connected" = "外围设备未连接"; + +/* Response timeout error description */ +"Pump did not respond in time" = "泵没有及时响应"; + +/* Invalid response error description (1: response) */ +"Response %@ is invalid" = "响应%@无效"; + +/* Unsupported command error description */ +"RileyLink firmware does not support the %@ command" = "RileyLink固件不支持%@命令"; + +/* Failure reason: unknown peripheral characteristic */ +"The RileyLink was temporarily disconnected" = "RileyLink暂时断开连接"; + +/* Error description */ +"Unknown characteristic" = "未知特性"; + diff --git a/RileyLinkBLEKitTests/de.lproj/InfoPlist.strings b/RileyLinkBLEKitTests/de.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkBLEKitTests/de.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkBLEKitTests/es.lproj/InfoPlist.strings b/RileyLinkBLEKitTests/es.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkBLEKitTests/es.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkBLEKitTests/fr.lproj/InfoPlist.strings b/RileyLinkBLEKitTests/fr.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkBLEKitTests/fr.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkBLEKitTests/it.lproj/InfoPlist.strings b/RileyLinkBLEKitTests/it.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkBLEKitTests/it.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkBLEKitTests/nb.lproj/InfoPlist.strings b/RileyLinkBLEKitTests/nb.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkBLEKitTests/nb.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkBLEKitTests/nl.lproj/InfoPlist.strings b/RileyLinkBLEKitTests/nl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkBLEKitTests/nl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkBLEKitTests/ru.lproj/InfoPlist.strings b/RileyLinkBLEKitTests/ru.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkBLEKitTests/ru.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkBLEKitTests/zh-Hans.lproj/InfoPlist.strings b/RileyLinkBLEKitTests/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkBLEKitTests/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKit/de.lproj/InfoPlist.strings b/RileyLinkKit/de.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKit/de.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKit/de.lproj/Localizable.strings b/RileyLinkKit/de.lproj/Localizable.strings new file mode 100644 index 000000000..fd9cfbc60 --- /dev/null +++ b/RileyLinkKit/de.lproj/Localizable.strings @@ -0,0 +1,189 @@ +/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ +"%1$@ MHz %2$@/%3$@ %4$@" = "%1$@ MHz %2$@/%3$@ %4$@"; + +/* Describes a certain bolus failure (1: size of the bolus in units) */ +"%1$@ U bolus failed" = "%1$@ U Bolo Falló"; + +/* Describes an uncertain bolus failure (1: size of the bolus in units) */ +"%1$@ U bolus may not have succeeded" = "%1$@ U bolo posiblemente fallado"; + +/* The format string describing units of insulin remaining: (1: number of units) */ +"%1$@ Units of insulin remaining\n" = "%1$@ Unidades de insulina restantes"; + +/* The format string describing number of basal schedule entries: (1: number of entries) */ +"%1$@ basal schedule entries\n" = "%1$@ entradas de prefil basal"; + +/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ +"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; + +/* Communications error for a bolus currently running */ +"A bolus is already in progress" = "Un bolo ya está en progreso"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Despierto hasta"; + +/* The format string describing pump battery voltage: (1: battery voltage) */ +"Battery: %1$@ volts\n" = "Pila: %1$@ voltios"; + +/* The label indicating the best radio frequency */ +"Best Frequency" = "Mejor Frecuencia"; + +/* The format string describing pump bolusing state: (1: bolusing) */ +"Bolusing: %1$@\n" = "Bolo en progreso: %1$@"; + +/* The title of the command to change pump time */ +"Change Time" = "Cambio de Hora"; + +/* Progress message for changing pump time. */ +"Changing time…" = "Cambio de Hora..."; + +/* Recovery instruction for an uncertain bolus failure */ +"Check your pump before retrying." = "Revisar su microinfusadora antes de intentarlo de nuevo"; + +/* The title of the section describing commands */ +"Commands" = "Comandos"; + +/* No comment provided by engineer. */ +"Comms with another pump detected." = "Comunicación con otra microinfusadora detectado."; + +/* The connected state */ +"Connected" = "Conectado"; + +/* The in-progress connecting state */ +"Connecting" = "Conectando"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Estado de Conexión"; + +/* The title of the section describing the device */ +"Device" = "Dispositivo"; + +/* The disconnected state */ +"Disconnected" = "Desconectado"; + +/* The in-progress disconnecting state */ +"Disconnecting" = "Desconectando"; + +/* The error displayed during MySentry pairing when the RX filter could not be set */ +"Error setting filter bandwidth: %@" = "Error al establecer el ancho de banda del filtro: %@"; + +/* The title of the command to fetch recent glucose */ +"Fetch Recent Glucose" = "Obtener Glucosa Reciente"; + +/* The title of the command to fetch recent history */ +"Fetch Recent History" = "Obtener Historia Reciente"; + +/* Progress message for fetching pump glucose. */ +"Fetching glucose…" = "Obteniendo glucosa…"; + +/* Progress message for fetching pump history. */ +"Fetching history…" = "Obteniendo historia…"; + +/* Progress message for fetching pump model. */ +"Fetching pump model…" = "Obteniendo modelo de microinfusadora…"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Firmware"; + +/* The title of the command to get pump model */ +"Get Pump Model" = "Obtener Modelo de Microinfusadora"; + +/* Recovery instruction for a certain bolus failure */ +"It is safe to retry" = "Es seguro intentarlo de nuevo."; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "último despierto"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Escuchando apagado"; + +/* The title of the command to pair with mysentry */ +"MySentry Pair" = "Junta de MySentry"; + +/* The title of the cell showing device name */ +"Name" = "Nombre"; + +/* Message display when no response from tuning pump */ +"No response" = "No respuesta"; + +/* The title of the cell showing the last idle */ +"On Idle" = "En Inactivo"; + +/* The title of the section describing the pump */ +"Pump" = "Microinfusadora"; + +/* The title of the cell showing pump ID */ +"Pump ID" = "ID de Microinfusadora"; + +/* The title of the cell showing the pump model number */ +"Pump Model" = "Modelo de Microinfusadora"; + +/* No comment provided by engineer. */ +"Pump did not respond." = "Microinfusadora no respondió."; + +/* The format string description of a Pump Error. (1: The specific error code) */ +"Pump error: %1$@" = "Error de Microinfusadora: %1$@"; + +/* No comment provided by engineer. */ +"Pump is suspended." = "Micorinfusadora está suspendida"; + +/* No comment provided by engineer. */ +"Pump responded unexpectedly." = "Micorinfusadora respondió inesperadamente."; + +/* The title of the command to read basal schedule */ +"Read Basal Schedule" = "Obtener prefil basal"; + +/* The title of the command to read pump status */ +"Read Pump Status" = "Obtener estada de microinfusadora"; + +/* Progress message for reading basal schedule */ +"Reading basal schedule…" = "Obteniendo perfil basal…"; + +/* Progress message for reading pump status */ +"Reading pump status…" = "Obteniendo estada de microinfusadora…"; + +/* No comment provided by engineer. */ +"RileyLink timed out." = "RileyLink agotó el tiempo."; + +/* The title of the command to send a button press */ +"Send Button Press" = "Enviar presion de botón"; + +/* Progress message for sending button press to pump. */ +"Sending button press…" = "Enviando presion de botón…"; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Intensidad de señal"; + +/* A message indicating a command succeeded */ +"Succeeded" = "éxito"; + +/* The format string describing pump suspended state: (1: suspended) */ +"Suspended: %1$@\n" = "Suspendida: %1$@"; + +/* The label indicating the results of each frequency trial */ +"Trials" = "Pruebas"; + +/* The title of the command to re-tune the radio */ +"Tune Radio Frequency" = "Sintonizar frecuencia de radio"; + +/* Progress message for tuning radio */ +"Tuning radio…" = "Sintonizando frecuencia de radio…"; + +/* The detail text for an unknown pump model */ +"Unknown" = "Desconocido"; + +/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ +"Unknown pump error code: %1$@" = "Codigo desconocido de microinfusadora: %1$@"; + +/* No comment provided by engineer. */ +"Unknown pump model." = "Desconocido modelo de microinfusadora."; + +/* No comment provided by engineer. */ +"Unknown response from pump." = "Respuesta desconocida de microinfusora"; + +/* The title of the command to write a glucose history timestamp */ +"Write Glucose History Timestamp" = "Recordar la hora de glucosa historia"; + +/* Progress message for writing glucose history timestamp. */ +"Writing glucose history timestamp…" = "Recordando la hora de glucosa historia…"; + diff --git a/RileyLinkKit/es.lproj/InfoPlist.strings b/RileyLinkKit/es.lproj/InfoPlist.strings index f8e9a2b43..bbcf8f904 100644 --- a/RileyLinkKit/es.lproj/InfoPlist.strings +++ b/RileyLinkKit/es.lproj/InfoPlist.strings @@ -1,3 +1,3 @@ -/* (No Comment) */ +/* Bundle name */ "CFBundleName" = "$(PRODUCT_NAME)"; diff --git a/RileyLinkKit/fr.lproj/InfoPlist.strings b/RileyLinkKit/fr.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKit/fr.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKit/fr.lproj/Localizable.strings b/RileyLinkKit/fr.lproj/Localizable.strings new file mode 100644 index 000000000..fd9cfbc60 --- /dev/null +++ b/RileyLinkKit/fr.lproj/Localizable.strings @@ -0,0 +1,189 @@ +/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ +"%1$@ MHz %2$@/%3$@ %4$@" = "%1$@ MHz %2$@/%3$@ %4$@"; + +/* Describes a certain bolus failure (1: size of the bolus in units) */ +"%1$@ U bolus failed" = "%1$@ U Bolo Falló"; + +/* Describes an uncertain bolus failure (1: size of the bolus in units) */ +"%1$@ U bolus may not have succeeded" = "%1$@ U bolo posiblemente fallado"; + +/* The format string describing units of insulin remaining: (1: number of units) */ +"%1$@ Units of insulin remaining\n" = "%1$@ Unidades de insulina restantes"; + +/* The format string describing number of basal schedule entries: (1: number of entries) */ +"%1$@ basal schedule entries\n" = "%1$@ entradas de prefil basal"; + +/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ +"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; + +/* Communications error for a bolus currently running */ +"A bolus is already in progress" = "Un bolo ya está en progreso"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Despierto hasta"; + +/* The format string describing pump battery voltage: (1: battery voltage) */ +"Battery: %1$@ volts\n" = "Pila: %1$@ voltios"; + +/* The label indicating the best radio frequency */ +"Best Frequency" = "Mejor Frecuencia"; + +/* The format string describing pump bolusing state: (1: bolusing) */ +"Bolusing: %1$@\n" = "Bolo en progreso: %1$@"; + +/* The title of the command to change pump time */ +"Change Time" = "Cambio de Hora"; + +/* Progress message for changing pump time. */ +"Changing time…" = "Cambio de Hora..."; + +/* Recovery instruction for an uncertain bolus failure */ +"Check your pump before retrying." = "Revisar su microinfusadora antes de intentarlo de nuevo"; + +/* The title of the section describing commands */ +"Commands" = "Comandos"; + +/* No comment provided by engineer. */ +"Comms with another pump detected." = "Comunicación con otra microinfusadora detectado."; + +/* The connected state */ +"Connected" = "Conectado"; + +/* The in-progress connecting state */ +"Connecting" = "Conectando"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Estado de Conexión"; + +/* The title of the section describing the device */ +"Device" = "Dispositivo"; + +/* The disconnected state */ +"Disconnected" = "Desconectado"; + +/* The in-progress disconnecting state */ +"Disconnecting" = "Desconectando"; + +/* The error displayed during MySentry pairing when the RX filter could not be set */ +"Error setting filter bandwidth: %@" = "Error al establecer el ancho de banda del filtro: %@"; + +/* The title of the command to fetch recent glucose */ +"Fetch Recent Glucose" = "Obtener Glucosa Reciente"; + +/* The title of the command to fetch recent history */ +"Fetch Recent History" = "Obtener Historia Reciente"; + +/* Progress message for fetching pump glucose. */ +"Fetching glucose…" = "Obteniendo glucosa…"; + +/* Progress message for fetching pump history. */ +"Fetching history…" = "Obteniendo historia…"; + +/* Progress message for fetching pump model. */ +"Fetching pump model…" = "Obteniendo modelo de microinfusadora…"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Firmware"; + +/* The title of the command to get pump model */ +"Get Pump Model" = "Obtener Modelo de Microinfusadora"; + +/* Recovery instruction for a certain bolus failure */ +"It is safe to retry" = "Es seguro intentarlo de nuevo."; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "último despierto"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Escuchando apagado"; + +/* The title of the command to pair with mysentry */ +"MySentry Pair" = "Junta de MySentry"; + +/* The title of the cell showing device name */ +"Name" = "Nombre"; + +/* Message display when no response from tuning pump */ +"No response" = "No respuesta"; + +/* The title of the cell showing the last idle */ +"On Idle" = "En Inactivo"; + +/* The title of the section describing the pump */ +"Pump" = "Microinfusadora"; + +/* The title of the cell showing pump ID */ +"Pump ID" = "ID de Microinfusadora"; + +/* The title of the cell showing the pump model number */ +"Pump Model" = "Modelo de Microinfusadora"; + +/* No comment provided by engineer. */ +"Pump did not respond." = "Microinfusadora no respondió."; + +/* The format string description of a Pump Error. (1: The specific error code) */ +"Pump error: %1$@" = "Error de Microinfusadora: %1$@"; + +/* No comment provided by engineer. */ +"Pump is suspended." = "Micorinfusadora está suspendida"; + +/* No comment provided by engineer. */ +"Pump responded unexpectedly." = "Micorinfusadora respondió inesperadamente."; + +/* The title of the command to read basal schedule */ +"Read Basal Schedule" = "Obtener prefil basal"; + +/* The title of the command to read pump status */ +"Read Pump Status" = "Obtener estada de microinfusadora"; + +/* Progress message for reading basal schedule */ +"Reading basal schedule…" = "Obteniendo perfil basal…"; + +/* Progress message for reading pump status */ +"Reading pump status…" = "Obteniendo estada de microinfusadora…"; + +/* No comment provided by engineer. */ +"RileyLink timed out." = "RileyLink agotó el tiempo."; + +/* The title of the command to send a button press */ +"Send Button Press" = "Enviar presion de botón"; + +/* Progress message for sending button press to pump. */ +"Sending button press…" = "Enviando presion de botón…"; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Intensidad de señal"; + +/* A message indicating a command succeeded */ +"Succeeded" = "éxito"; + +/* The format string describing pump suspended state: (1: suspended) */ +"Suspended: %1$@\n" = "Suspendida: %1$@"; + +/* The label indicating the results of each frequency trial */ +"Trials" = "Pruebas"; + +/* The title of the command to re-tune the radio */ +"Tune Radio Frequency" = "Sintonizar frecuencia de radio"; + +/* Progress message for tuning radio */ +"Tuning radio…" = "Sintonizando frecuencia de radio…"; + +/* The detail text for an unknown pump model */ +"Unknown" = "Desconocido"; + +/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ +"Unknown pump error code: %1$@" = "Codigo desconocido de microinfusadora: %1$@"; + +/* No comment provided by engineer. */ +"Unknown pump model." = "Desconocido modelo de microinfusadora."; + +/* No comment provided by engineer. */ +"Unknown response from pump." = "Respuesta desconocida de microinfusora"; + +/* The title of the command to write a glucose history timestamp */ +"Write Glucose History Timestamp" = "Recordar la hora de glucosa historia"; + +/* Progress message for writing glucose history timestamp. */ +"Writing glucose history timestamp…" = "Recordando la hora de glucosa historia…"; + diff --git a/RileyLinkKit/it.lproj/InfoPlist.strings b/RileyLinkKit/it.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKit/it.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKit/it.lproj/Localizable.strings b/RileyLinkKit/it.lproj/Localizable.strings new file mode 100644 index 000000000..fd9cfbc60 --- /dev/null +++ b/RileyLinkKit/it.lproj/Localizable.strings @@ -0,0 +1,189 @@ +/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ +"%1$@ MHz %2$@/%3$@ %4$@" = "%1$@ MHz %2$@/%3$@ %4$@"; + +/* Describes a certain bolus failure (1: size of the bolus in units) */ +"%1$@ U bolus failed" = "%1$@ U Bolo Falló"; + +/* Describes an uncertain bolus failure (1: size of the bolus in units) */ +"%1$@ U bolus may not have succeeded" = "%1$@ U bolo posiblemente fallado"; + +/* The format string describing units of insulin remaining: (1: number of units) */ +"%1$@ Units of insulin remaining\n" = "%1$@ Unidades de insulina restantes"; + +/* The format string describing number of basal schedule entries: (1: number of entries) */ +"%1$@ basal schedule entries\n" = "%1$@ entradas de prefil basal"; + +/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ +"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; + +/* Communications error for a bolus currently running */ +"A bolus is already in progress" = "Un bolo ya está en progreso"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Despierto hasta"; + +/* The format string describing pump battery voltage: (1: battery voltage) */ +"Battery: %1$@ volts\n" = "Pila: %1$@ voltios"; + +/* The label indicating the best radio frequency */ +"Best Frequency" = "Mejor Frecuencia"; + +/* The format string describing pump bolusing state: (1: bolusing) */ +"Bolusing: %1$@\n" = "Bolo en progreso: %1$@"; + +/* The title of the command to change pump time */ +"Change Time" = "Cambio de Hora"; + +/* Progress message for changing pump time. */ +"Changing time…" = "Cambio de Hora..."; + +/* Recovery instruction for an uncertain bolus failure */ +"Check your pump before retrying." = "Revisar su microinfusadora antes de intentarlo de nuevo"; + +/* The title of the section describing commands */ +"Commands" = "Comandos"; + +/* No comment provided by engineer. */ +"Comms with another pump detected." = "Comunicación con otra microinfusadora detectado."; + +/* The connected state */ +"Connected" = "Conectado"; + +/* The in-progress connecting state */ +"Connecting" = "Conectando"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Estado de Conexión"; + +/* The title of the section describing the device */ +"Device" = "Dispositivo"; + +/* The disconnected state */ +"Disconnected" = "Desconectado"; + +/* The in-progress disconnecting state */ +"Disconnecting" = "Desconectando"; + +/* The error displayed during MySentry pairing when the RX filter could not be set */ +"Error setting filter bandwidth: %@" = "Error al establecer el ancho de banda del filtro: %@"; + +/* The title of the command to fetch recent glucose */ +"Fetch Recent Glucose" = "Obtener Glucosa Reciente"; + +/* The title of the command to fetch recent history */ +"Fetch Recent History" = "Obtener Historia Reciente"; + +/* Progress message for fetching pump glucose. */ +"Fetching glucose…" = "Obteniendo glucosa…"; + +/* Progress message for fetching pump history. */ +"Fetching history…" = "Obteniendo historia…"; + +/* Progress message for fetching pump model. */ +"Fetching pump model…" = "Obteniendo modelo de microinfusadora…"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Firmware"; + +/* The title of the command to get pump model */ +"Get Pump Model" = "Obtener Modelo de Microinfusadora"; + +/* Recovery instruction for a certain bolus failure */ +"It is safe to retry" = "Es seguro intentarlo de nuevo."; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "último despierto"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Escuchando apagado"; + +/* The title of the command to pair with mysentry */ +"MySentry Pair" = "Junta de MySentry"; + +/* The title of the cell showing device name */ +"Name" = "Nombre"; + +/* Message display when no response from tuning pump */ +"No response" = "No respuesta"; + +/* The title of the cell showing the last idle */ +"On Idle" = "En Inactivo"; + +/* The title of the section describing the pump */ +"Pump" = "Microinfusadora"; + +/* The title of the cell showing pump ID */ +"Pump ID" = "ID de Microinfusadora"; + +/* The title of the cell showing the pump model number */ +"Pump Model" = "Modelo de Microinfusadora"; + +/* No comment provided by engineer. */ +"Pump did not respond." = "Microinfusadora no respondió."; + +/* The format string description of a Pump Error. (1: The specific error code) */ +"Pump error: %1$@" = "Error de Microinfusadora: %1$@"; + +/* No comment provided by engineer. */ +"Pump is suspended." = "Micorinfusadora está suspendida"; + +/* No comment provided by engineer. */ +"Pump responded unexpectedly." = "Micorinfusadora respondió inesperadamente."; + +/* The title of the command to read basal schedule */ +"Read Basal Schedule" = "Obtener prefil basal"; + +/* The title of the command to read pump status */ +"Read Pump Status" = "Obtener estada de microinfusadora"; + +/* Progress message for reading basal schedule */ +"Reading basal schedule…" = "Obteniendo perfil basal…"; + +/* Progress message for reading pump status */ +"Reading pump status…" = "Obteniendo estada de microinfusadora…"; + +/* No comment provided by engineer. */ +"RileyLink timed out." = "RileyLink agotó el tiempo."; + +/* The title of the command to send a button press */ +"Send Button Press" = "Enviar presion de botón"; + +/* Progress message for sending button press to pump. */ +"Sending button press…" = "Enviando presion de botón…"; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Intensidad de señal"; + +/* A message indicating a command succeeded */ +"Succeeded" = "éxito"; + +/* The format string describing pump suspended state: (1: suspended) */ +"Suspended: %1$@\n" = "Suspendida: %1$@"; + +/* The label indicating the results of each frequency trial */ +"Trials" = "Pruebas"; + +/* The title of the command to re-tune the radio */ +"Tune Radio Frequency" = "Sintonizar frecuencia de radio"; + +/* Progress message for tuning radio */ +"Tuning radio…" = "Sintonizando frecuencia de radio…"; + +/* The detail text for an unknown pump model */ +"Unknown" = "Desconocido"; + +/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ +"Unknown pump error code: %1$@" = "Codigo desconocido de microinfusadora: %1$@"; + +/* No comment provided by engineer. */ +"Unknown pump model." = "Desconocido modelo de microinfusadora."; + +/* No comment provided by engineer. */ +"Unknown response from pump." = "Respuesta desconocida de microinfusora"; + +/* The title of the command to write a glucose history timestamp */ +"Write Glucose History Timestamp" = "Recordar la hora de glucosa historia"; + +/* Progress message for writing glucose history timestamp. */ +"Writing glucose history timestamp…" = "Recordando la hora de glucosa historia…"; + diff --git a/RileyLinkKit/nb.lproj/InfoPlist.strings b/RileyLinkKit/nb.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKit/nb.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKit/nb.lproj/Localizable.strings b/RileyLinkKit/nb.lproj/Localizable.strings new file mode 100644 index 000000000..fd9cfbc60 --- /dev/null +++ b/RileyLinkKit/nb.lproj/Localizable.strings @@ -0,0 +1,189 @@ +/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ +"%1$@ MHz %2$@/%3$@ %4$@" = "%1$@ MHz %2$@/%3$@ %4$@"; + +/* Describes a certain bolus failure (1: size of the bolus in units) */ +"%1$@ U bolus failed" = "%1$@ U Bolo Falló"; + +/* Describes an uncertain bolus failure (1: size of the bolus in units) */ +"%1$@ U bolus may not have succeeded" = "%1$@ U bolo posiblemente fallado"; + +/* The format string describing units of insulin remaining: (1: number of units) */ +"%1$@ Units of insulin remaining\n" = "%1$@ Unidades de insulina restantes"; + +/* The format string describing number of basal schedule entries: (1: number of entries) */ +"%1$@ basal schedule entries\n" = "%1$@ entradas de prefil basal"; + +/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ +"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; + +/* Communications error for a bolus currently running */ +"A bolus is already in progress" = "Un bolo ya está en progreso"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Despierto hasta"; + +/* The format string describing pump battery voltage: (1: battery voltage) */ +"Battery: %1$@ volts\n" = "Pila: %1$@ voltios"; + +/* The label indicating the best radio frequency */ +"Best Frequency" = "Mejor Frecuencia"; + +/* The format string describing pump bolusing state: (1: bolusing) */ +"Bolusing: %1$@\n" = "Bolo en progreso: %1$@"; + +/* The title of the command to change pump time */ +"Change Time" = "Cambio de Hora"; + +/* Progress message for changing pump time. */ +"Changing time…" = "Cambio de Hora..."; + +/* Recovery instruction for an uncertain bolus failure */ +"Check your pump before retrying." = "Revisar su microinfusadora antes de intentarlo de nuevo"; + +/* The title of the section describing commands */ +"Commands" = "Comandos"; + +/* No comment provided by engineer. */ +"Comms with another pump detected." = "Comunicación con otra microinfusadora detectado."; + +/* The connected state */ +"Connected" = "Conectado"; + +/* The in-progress connecting state */ +"Connecting" = "Conectando"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Estado de Conexión"; + +/* The title of the section describing the device */ +"Device" = "Dispositivo"; + +/* The disconnected state */ +"Disconnected" = "Desconectado"; + +/* The in-progress disconnecting state */ +"Disconnecting" = "Desconectando"; + +/* The error displayed during MySentry pairing when the RX filter could not be set */ +"Error setting filter bandwidth: %@" = "Error al establecer el ancho de banda del filtro: %@"; + +/* The title of the command to fetch recent glucose */ +"Fetch Recent Glucose" = "Obtener Glucosa Reciente"; + +/* The title of the command to fetch recent history */ +"Fetch Recent History" = "Obtener Historia Reciente"; + +/* Progress message for fetching pump glucose. */ +"Fetching glucose…" = "Obteniendo glucosa…"; + +/* Progress message for fetching pump history. */ +"Fetching history…" = "Obteniendo historia…"; + +/* Progress message for fetching pump model. */ +"Fetching pump model…" = "Obteniendo modelo de microinfusadora…"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Firmware"; + +/* The title of the command to get pump model */ +"Get Pump Model" = "Obtener Modelo de Microinfusadora"; + +/* Recovery instruction for a certain bolus failure */ +"It is safe to retry" = "Es seguro intentarlo de nuevo."; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "último despierto"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Escuchando apagado"; + +/* The title of the command to pair with mysentry */ +"MySentry Pair" = "Junta de MySentry"; + +/* The title of the cell showing device name */ +"Name" = "Nombre"; + +/* Message display when no response from tuning pump */ +"No response" = "No respuesta"; + +/* The title of the cell showing the last idle */ +"On Idle" = "En Inactivo"; + +/* The title of the section describing the pump */ +"Pump" = "Microinfusadora"; + +/* The title of the cell showing pump ID */ +"Pump ID" = "ID de Microinfusadora"; + +/* The title of the cell showing the pump model number */ +"Pump Model" = "Modelo de Microinfusadora"; + +/* No comment provided by engineer. */ +"Pump did not respond." = "Microinfusadora no respondió."; + +/* The format string description of a Pump Error. (1: The specific error code) */ +"Pump error: %1$@" = "Error de Microinfusadora: %1$@"; + +/* No comment provided by engineer. */ +"Pump is suspended." = "Micorinfusadora está suspendida"; + +/* No comment provided by engineer. */ +"Pump responded unexpectedly." = "Micorinfusadora respondió inesperadamente."; + +/* The title of the command to read basal schedule */ +"Read Basal Schedule" = "Obtener prefil basal"; + +/* The title of the command to read pump status */ +"Read Pump Status" = "Obtener estada de microinfusadora"; + +/* Progress message for reading basal schedule */ +"Reading basal schedule…" = "Obteniendo perfil basal…"; + +/* Progress message for reading pump status */ +"Reading pump status…" = "Obteniendo estada de microinfusadora…"; + +/* No comment provided by engineer. */ +"RileyLink timed out." = "RileyLink agotó el tiempo."; + +/* The title of the command to send a button press */ +"Send Button Press" = "Enviar presion de botón"; + +/* Progress message for sending button press to pump. */ +"Sending button press…" = "Enviando presion de botón…"; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Intensidad de señal"; + +/* A message indicating a command succeeded */ +"Succeeded" = "éxito"; + +/* The format string describing pump suspended state: (1: suspended) */ +"Suspended: %1$@\n" = "Suspendida: %1$@"; + +/* The label indicating the results of each frequency trial */ +"Trials" = "Pruebas"; + +/* The title of the command to re-tune the radio */ +"Tune Radio Frequency" = "Sintonizar frecuencia de radio"; + +/* Progress message for tuning radio */ +"Tuning radio…" = "Sintonizando frecuencia de radio…"; + +/* The detail text for an unknown pump model */ +"Unknown" = "Desconocido"; + +/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ +"Unknown pump error code: %1$@" = "Codigo desconocido de microinfusadora: %1$@"; + +/* No comment provided by engineer. */ +"Unknown pump model." = "Desconocido modelo de microinfusadora."; + +/* No comment provided by engineer. */ +"Unknown response from pump." = "Respuesta desconocida de microinfusora"; + +/* The title of the command to write a glucose history timestamp */ +"Write Glucose History Timestamp" = "Recordar la hora de glucosa historia"; + +/* Progress message for writing glucose history timestamp. */ +"Writing glucose history timestamp…" = "Recordando la hora de glucosa historia…"; + diff --git a/RileyLinkKit/nl.lproj/InfoPlist.strings b/RileyLinkKit/nl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKit/nl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKit/nl.lproj/Localizable.strings b/RileyLinkKit/nl.lproj/Localizable.strings new file mode 100644 index 000000000..fd9cfbc60 --- /dev/null +++ b/RileyLinkKit/nl.lproj/Localizable.strings @@ -0,0 +1,189 @@ +/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ +"%1$@ MHz %2$@/%3$@ %4$@" = "%1$@ MHz %2$@/%3$@ %4$@"; + +/* Describes a certain bolus failure (1: size of the bolus in units) */ +"%1$@ U bolus failed" = "%1$@ U Bolo Falló"; + +/* Describes an uncertain bolus failure (1: size of the bolus in units) */ +"%1$@ U bolus may not have succeeded" = "%1$@ U bolo posiblemente fallado"; + +/* The format string describing units of insulin remaining: (1: number of units) */ +"%1$@ Units of insulin remaining\n" = "%1$@ Unidades de insulina restantes"; + +/* The format string describing number of basal schedule entries: (1: number of entries) */ +"%1$@ basal schedule entries\n" = "%1$@ entradas de prefil basal"; + +/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ +"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; + +/* Communications error for a bolus currently running */ +"A bolus is already in progress" = "Un bolo ya está en progreso"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Despierto hasta"; + +/* The format string describing pump battery voltage: (1: battery voltage) */ +"Battery: %1$@ volts\n" = "Pila: %1$@ voltios"; + +/* The label indicating the best radio frequency */ +"Best Frequency" = "Mejor Frecuencia"; + +/* The format string describing pump bolusing state: (1: bolusing) */ +"Bolusing: %1$@\n" = "Bolo en progreso: %1$@"; + +/* The title of the command to change pump time */ +"Change Time" = "Cambio de Hora"; + +/* Progress message for changing pump time. */ +"Changing time…" = "Cambio de Hora..."; + +/* Recovery instruction for an uncertain bolus failure */ +"Check your pump before retrying." = "Revisar su microinfusadora antes de intentarlo de nuevo"; + +/* The title of the section describing commands */ +"Commands" = "Comandos"; + +/* No comment provided by engineer. */ +"Comms with another pump detected." = "Comunicación con otra microinfusadora detectado."; + +/* The connected state */ +"Connected" = "Conectado"; + +/* The in-progress connecting state */ +"Connecting" = "Conectando"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Estado de Conexión"; + +/* The title of the section describing the device */ +"Device" = "Dispositivo"; + +/* The disconnected state */ +"Disconnected" = "Desconectado"; + +/* The in-progress disconnecting state */ +"Disconnecting" = "Desconectando"; + +/* The error displayed during MySentry pairing when the RX filter could not be set */ +"Error setting filter bandwidth: %@" = "Error al establecer el ancho de banda del filtro: %@"; + +/* The title of the command to fetch recent glucose */ +"Fetch Recent Glucose" = "Obtener Glucosa Reciente"; + +/* The title of the command to fetch recent history */ +"Fetch Recent History" = "Obtener Historia Reciente"; + +/* Progress message for fetching pump glucose. */ +"Fetching glucose…" = "Obteniendo glucosa…"; + +/* Progress message for fetching pump history. */ +"Fetching history…" = "Obteniendo historia…"; + +/* Progress message for fetching pump model. */ +"Fetching pump model…" = "Obteniendo modelo de microinfusadora…"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Firmware"; + +/* The title of the command to get pump model */ +"Get Pump Model" = "Obtener Modelo de Microinfusadora"; + +/* Recovery instruction for a certain bolus failure */ +"It is safe to retry" = "Es seguro intentarlo de nuevo."; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "último despierto"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Escuchando apagado"; + +/* The title of the command to pair with mysentry */ +"MySentry Pair" = "Junta de MySentry"; + +/* The title of the cell showing device name */ +"Name" = "Nombre"; + +/* Message display when no response from tuning pump */ +"No response" = "No respuesta"; + +/* The title of the cell showing the last idle */ +"On Idle" = "En Inactivo"; + +/* The title of the section describing the pump */ +"Pump" = "Microinfusadora"; + +/* The title of the cell showing pump ID */ +"Pump ID" = "ID de Microinfusadora"; + +/* The title of the cell showing the pump model number */ +"Pump Model" = "Modelo de Microinfusadora"; + +/* No comment provided by engineer. */ +"Pump did not respond." = "Microinfusadora no respondió."; + +/* The format string description of a Pump Error. (1: The specific error code) */ +"Pump error: %1$@" = "Error de Microinfusadora: %1$@"; + +/* No comment provided by engineer. */ +"Pump is suspended." = "Micorinfusadora está suspendida"; + +/* No comment provided by engineer. */ +"Pump responded unexpectedly." = "Micorinfusadora respondió inesperadamente."; + +/* The title of the command to read basal schedule */ +"Read Basal Schedule" = "Obtener prefil basal"; + +/* The title of the command to read pump status */ +"Read Pump Status" = "Obtener estada de microinfusadora"; + +/* Progress message for reading basal schedule */ +"Reading basal schedule…" = "Obteniendo perfil basal…"; + +/* Progress message for reading pump status */ +"Reading pump status…" = "Obteniendo estada de microinfusadora…"; + +/* No comment provided by engineer. */ +"RileyLink timed out." = "RileyLink agotó el tiempo."; + +/* The title of the command to send a button press */ +"Send Button Press" = "Enviar presion de botón"; + +/* Progress message for sending button press to pump. */ +"Sending button press…" = "Enviando presion de botón…"; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Intensidad de señal"; + +/* A message indicating a command succeeded */ +"Succeeded" = "éxito"; + +/* The format string describing pump suspended state: (1: suspended) */ +"Suspended: %1$@\n" = "Suspendida: %1$@"; + +/* The label indicating the results of each frequency trial */ +"Trials" = "Pruebas"; + +/* The title of the command to re-tune the radio */ +"Tune Radio Frequency" = "Sintonizar frecuencia de radio"; + +/* Progress message for tuning radio */ +"Tuning radio…" = "Sintonizando frecuencia de radio…"; + +/* The detail text for an unknown pump model */ +"Unknown" = "Desconocido"; + +/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ +"Unknown pump error code: %1$@" = "Codigo desconocido de microinfusadora: %1$@"; + +/* No comment provided by engineer. */ +"Unknown pump model." = "Desconocido modelo de microinfusadora."; + +/* No comment provided by engineer. */ +"Unknown response from pump." = "Respuesta desconocida de microinfusora"; + +/* The title of the command to write a glucose history timestamp */ +"Write Glucose History Timestamp" = "Recordar la hora de glucosa historia"; + +/* Progress message for writing glucose history timestamp. */ +"Writing glucose history timestamp…" = "Recordando la hora de glucosa historia…"; + diff --git a/RileyLinkKit/ru.lproj/InfoPlist.strings b/RileyLinkKit/ru.lproj/InfoPlist.strings index 874e8a453..bbcf8f904 100644 --- a/RileyLinkKit/ru.lproj/InfoPlist.strings +++ b/RileyLinkKit/ru.lproj/InfoPlist.strings @@ -1 +1,3 @@ -/* No Localized Strings */ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKit/zh-Hans.lproj/InfoPlist.strings b/RileyLinkKit/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKit/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKit/zh-Hans.lproj/Localizable.strings b/RileyLinkKit/zh-Hans.lproj/Localizable.strings new file mode 100644 index 000000000..fd9cfbc60 --- /dev/null +++ b/RileyLinkKit/zh-Hans.lproj/Localizable.strings @@ -0,0 +1,189 @@ +/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ +"%1$@ MHz %2$@/%3$@ %4$@" = "%1$@ MHz %2$@/%3$@ %4$@"; + +/* Describes a certain bolus failure (1: size of the bolus in units) */ +"%1$@ U bolus failed" = "%1$@ U Bolo Falló"; + +/* Describes an uncertain bolus failure (1: size of the bolus in units) */ +"%1$@ U bolus may not have succeeded" = "%1$@ U bolo posiblemente fallado"; + +/* The format string describing units of insulin remaining: (1: number of units) */ +"%1$@ Units of insulin remaining\n" = "%1$@ Unidades de insulina restantes"; + +/* The format string describing number of basal schedule entries: (1: number of entries) */ +"%1$@ basal schedule entries\n" = "%1$@ entradas de prefil basal"; + +/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ +"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; + +/* Communications error for a bolus currently running */ +"A bolus is already in progress" = "Un bolo ya está en progreso"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Despierto hasta"; + +/* The format string describing pump battery voltage: (1: battery voltage) */ +"Battery: %1$@ volts\n" = "Pila: %1$@ voltios"; + +/* The label indicating the best radio frequency */ +"Best Frequency" = "Mejor Frecuencia"; + +/* The format string describing pump bolusing state: (1: bolusing) */ +"Bolusing: %1$@\n" = "Bolo en progreso: %1$@"; + +/* The title of the command to change pump time */ +"Change Time" = "Cambio de Hora"; + +/* Progress message for changing pump time. */ +"Changing time…" = "Cambio de Hora..."; + +/* Recovery instruction for an uncertain bolus failure */ +"Check your pump before retrying." = "Revisar su microinfusadora antes de intentarlo de nuevo"; + +/* The title of the section describing commands */ +"Commands" = "Comandos"; + +/* No comment provided by engineer. */ +"Comms with another pump detected." = "Comunicación con otra microinfusadora detectado."; + +/* The connected state */ +"Connected" = "Conectado"; + +/* The in-progress connecting state */ +"Connecting" = "Conectando"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Estado de Conexión"; + +/* The title of the section describing the device */ +"Device" = "Dispositivo"; + +/* The disconnected state */ +"Disconnected" = "Desconectado"; + +/* The in-progress disconnecting state */ +"Disconnecting" = "Desconectando"; + +/* The error displayed during MySentry pairing when the RX filter could not be set */ +"Error setting filter bandwidth: %@" = "Error al establecer el ancho de banda del filtro: %@"; + +/* The title of the command to fetch recent glucose */ +"Fetch Recent Glucose" = "Obtener Glucosa Reciente"; + +/* The title of the command to fetch recent history */ +"Fetch Recent History" = "Obtener Historia Reciente"; + +/* Progress message for fetching pump glucose. */ +"Fetching glucose…" = "Obteniendo glucosa…"; + +/* Progress message for fetching pump history. */ +"Fetching history…" = "Obteniendo historia…"; + +/* Progress message for fetching pump model. */ +"Fetching pump model…" = "Obteniendo modelo de microinfusadora…"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Firmware"; + +/* The title of the command to get pump model */ +"Get Pump Model" = "Obtener Modelo de Microinfusadora"; + +/* Recovery instruction for a certain bolus failure */ +"It is safe to retry" = "Es seguro intentarlo de nuevo."; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "último despierto"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Escuchando apagado"; + +/* The title of the command to pair with mysentry */ +"MySentry Pair" = "Junta de MySentry"; + +/* The title of the cell showing device name */ +"Name" = "Nombre"; + +/* Message display when no response from tuning pump */ +"No response" = "No respuesta"; + +/* The title of the cell showing the last idle */ +"On Idle" = "En Inactivo"; + +/* The title of the section describing the pump */ +"Pump" = "Microinfusadora"; + +/* The title of the cell showing pump ID */ +"Pump ID" = "ID de Microinfusadora"; + +/* The title of the cell showing the pump model number */ +"Pump Model" = "Modelo de Microinfusadora"; + +/* No comment provided by engineer. */ +"Pump did not respond." = "Microinfusadora no respondió."; + +/* The format string description of a Pump Error. (1: The specific error code) */ +"Pump error: %1$@" = "Error de Microinfusadora: %1$@"; + +/* No comment provided by engineer. */ +"Pump is suspended." = "Micorinfusadora está suspendida"; + +/* No comment provided by engineer. */ +"Pump responded unexpectedly." = "Micorinfusadora respondió inesperadamente."; + +/* The title of the command to read basal schedule */ +"Read Basal Schedule" = "Obtener prefil basal"; + +/* The title of the command to read pump status */ +"Read Pump Status" = "Obtener estada de microinfusadora"; + +/* Progress message for reading basal schedule */ +"Reading basal schedule…" = "Obteniendo perfil basal…"; + +/* Progress message for reading pump status */ +"Reading pump status…" = "Obteniendo estada de microinfusadora…"; + +/* No comment provided by engineer. */ +"RileyLink timed out." = "RileyLink agotó el tiempo."; + +/* The title of the command to send a button press */ +"Send Button Press" = "Enviar presion de botón"; + +/* Progress message for sending button press to pump. */ +"Sending button press…" = "Enviando presion de botón…"; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Intensidad de señal"; + +/* A message indicating a command succeeded */ +"Succeeded" = "éxito"; + +/* The format string describing pump suspended state: (1: suspended) */ +"Suspended: %1$@\n" = "Suspendida: %1$@"; + +/* The label indicating the results of each frequency trial */ +"Trials" = "Pruebas"; + +/* The title of the command to re-tune the radio */ +"Tune Radio Frequency" = "Sintonizar frecuencia de radio"; + +/* Progress message for tuning radio */ +"Tuning radio…" = "Sintonizando frecuencia de radio…"; + +/* The detail text for an unknown pump model */ +"Unknown" = "Desconocido"; + +/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ +"Unknown pump error code: %1$@" = "Codigo desconocido de microinfusadora: %1$@"; + +/* No comment provided by engineer. */ +"Unknown pump model." = "Desconocido modelo de microinfusadora."; + +/* No comment provided by engineer. */ +"Unknown response from pump." = "Respuesta desconocida de microinfusora"; + +/* The title of the command to write a glucose history timestamp */ +"Write Glucose History Timestamp" = "Recordar la hora de glucosa historia"; + +/* Progress message for writing glucose history timestamp. */ +"Writing glucose history timestamp…" = "Recordando la hora de glucosa historia…"; + diff --git a/RileyLinkKitTests/de.lproj/InfoPlist.strings b/RileyLinkKitTests/de.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKitTests/de.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKitTests/es.lproj/InfoPlist.strings b/RileyLinkKitTests/es.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKitTests/es.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKitTests/fr.lproj/InfoPlist.strings b/RileyLinkKitTests/fr.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKitTests/fr.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKitTests/it.lproj/InfoPlist.strings b/RileyLinkKitTests/it.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKitTests/it.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKitTests/nb.lproj/InfoPlist.strings b/RileyLinkKitTests/nb.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKitTests/nb.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKitTests/nl.lproj/InfoPlist.strings b/RileyLinkKitTests/nl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKitTests/nl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKitTests/ru.lproj/InfoPlist.strings b/RileyLinkKitTests/ru.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKitTests/ru.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKitTests/zh-Hans.lproj/InfoPlist.strings b/RileyLinkKitTests/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKitTests/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKitUI/Base.lproj/Localizable.strings b/RileyLinkKitUI/Base.lproj/Localizable.strings new file mode 100644 index 000000000..1150ab038 --- /dev/null +++ b/RileyLinkKitUI/Base.lproj/Localizable.strings @@ -0,0 +1,52 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Awake Until"; + +/* The title of the section describing commands */ +"Commands" = "Commands"; + +/* The connected state */ +"Connected" = "Connected"; + +/* The in-progress connecting state */ +"Connecting" = "Connecting"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Connection State"; + +/* The title of the section describing the device */ +"Device" = "Device"; + +/* The title of the devices table section in RileyLink settings */ +"Devices" = "Devices"; + +/* The disconnected state */ +"Disconnected" = "Disconnected"; + +/* The in-progress disconnecting state */ +"Disconnecting" = "Disconnecting"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Firmware"; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "Last Awake"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Listening Off"; + +/* The title of the cell showing device name */ +"Name" = "Name"; + +/* The title of the cell showing the last idle */ +"On Idle" = "On Idle"; + +/* RileyLink setup description */ +"RileyLink allows for communication with the pump over Bluetooth Low Energy." = "RileyLink allows for communication with the pump over Bluetooth Low Energy."; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Signal Strength"; + + diff --git a/RileyLinkKitUI/CBPeripheralState.swift b/RileyLinkKitUI/CBPeripheralState.swift index 2279d414b..92086ea76 100644 --- a/RileyLinkKitUI/CBPeripheralState.swift +++ b/RileyLinkKitUI/CBPeripheralState.swift @@ -16,13 +16,13 @@ extension CBPeripheralState { public var description: String { switch self { case .connected: - return NSLocalizedString("Connected", comment: "The connected state") + return LocalizedString("Connected", comment: "The connected state") case .connecting: - return NSLocalizedString("Connecting", comment: "The in-progress connecting state") + return LocalizedString("Connecting", comment: "The in-progress connecting state") case .disconnected: - return NSLocalizedString("Disconnected", comment: "The disconnected state") + return LocalizedString("Disconnected", comment: "The disconnected state") case .disconnecting: - return NSLocalizedString("Disconnecting", comment: "The in-progress disconnecting state") + return LocalizedString("Disconnecting", comment: "The in-progress disconnecting state") } } } diff --git a/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift b/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift index 2c1ec5213..a0489ce39 100644 --- a/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift +++ b/RileyLinkKitUI/RileyLinkDeviceTableViewController.swift @@ -219,21 +219,21 @@ public class RileyLinkDeviceTableViewController: UITableViewController { case .device: switch DeviceRow(rawValue: indexPath.row)! { case .customName: - cell.textLabel?.text = NSLocalizedString("Name", comment: "The title of the cell showing device name") + cell.textLabel?.text = LocalizedString("Name", comment: "The title of the cell showing device name") cell.detailTextLabel?.text = device.name cell.accessoryType = .disclosureIndicator case .version: - cell.textLabel?.text = NSLocalizedString("Firmware", comment: "The title of the cell showing firmware version") + cell.textLabel?.text = LocalizedString("Firmware", comment: "The title of the cell showing firmware version") cell.detailTextLabel?.text = firmwareVersion case .connection: - cell.textLabel?.text = NSLocalizedString("Connection State", comment: "The title of the cell showing BLE connection state") + cell.textLabel?.text = LocalizedString("Connection State", comment: "The title of the cell showing BLE connection state") cell.detailTextLabel?.text = device.peripheralState.description case .rssi: - cell.textLabel?.text = NSLocalizedString("Signal Strength", comment: "The title of the cell showing BLE signal strength (RSSI)") + cell.textLabel?.text = LocalizedString("Signal Strength", comment: "The title of the cell showing BLE signal strength (RSSI)") cell.setDetailRSSI(bleRSSI, formatter: integerFormatter) case .idleStatus: - cell.textLabel?.text = NSLocalizedString("On Idle", comment: "The title of the cell showing the last idle") + cell.textLabel?.text = LocalizedString("On Idle", comment: "The title of the cell showing the last idle") cell.setDetailDate(lastIdle, formatter: dateFormatter) } case .commands: @@ -247,9 +247,9 @@ public class RileyLinkDeviceTableViewController: UITableViewController { public override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { switch Section(rawValue: section)! { case .device: - return NSLocalizedString("Device", comment: "The title of the section describing the device") + return LocalizedString("Device", comment: "The title of the section describing the device") case .commands: - return NSLocalizedString("Commands", comment: "The title of the section describing commands") + return LocalizedString("Commands", comment: "The title of the section describing commands") } } @@ -332,13 +332,13 @@ private extension UITableViewCell { func setAwakeUntil(_ awakeUntil: Date?, formatter: DateFormatter) { switch awakeUntil { case let until? where until.timeIntervalSinceNow < 0: - textLabel?.text = NSLocalizedString("Last Awake", comment: "The title of the cell describing an awake radio") + textLabel?.text = LocalizedString("Last Awake", comment: "The title of the cell describing an awake radio") setDetailDate(until, formatter: formatter) case let until?: - textLabel?.text = NSLocalizedString("Awake Until", comment: "The title of the cell describing an awake radio") + textLabel?.text = LocalizedString("Awake Until", comment: "The title of the cell describing an awake radio") setDetailDate(until, formatter: formatter) default: - textLabel?.text = NSLocalizedString("Listening Off", comment: "The title of the cell describing no radio awake data") + textLabel?.text = LocalizedString("Listening Off", comment: "The title of the cell describing no radio awake data") detailTextLabel?.text = nil } } diff --git a/RileyLinkKitUI/RileyLinkDevicesTableViewDataSource.swift b/RileyLinkKitUI/RileyLinkDevicesTableViewDataSource.swift index ebbb2b50a..7c35bbd80 100644 --- a/RileyLinkKitUI/RileyLinkDevicesTableViewDataSource.swift +++ b/RileyLinkKitUI/RileyLinkDevicesTableViewDataSource.swift @@ -182,7 +182,7 @@ extension RileyLinkDevicesTableViewDataSource: UITableViewDataSource { } public func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { - return NSLocalizedString("Devices", comment: "The title of the devices table section in RileyLink settings") + return LocalizedString("Devices", comment: "The title of the devices table section in RileyLink settings") } } diff --git a/RileyLinkKitUI/RileyLinkSetupTableViewController.swift b/RileyLinkKitUI/RileyLinkSetupTableViewController.swift index 318078c56..8c0076622 100644 --- a/RileyLinkKitUI/RileyLinkSetupTableViewController.swift +++ b/RileyLinkKitUI/RileyLinkSetupTableViewController.swift @@ -91,7 +91,7 @@ public class RileyLinkSetupTableViewController: SetupTableViewController { if cell == nil { cell = UITableViewCell(style: .default, reuseIdentifier: "DescriptionCell") cell?.selectionStyle = .none - cell?.textLabel?.text = NSLocalizedString("RileyLink allows for communication with the pump over Bluetooth Low Energy.", comment: "RileyLink setup description") + cell?.textLabel?.text = LocalizedString("RileyLink allows for communication with the pump over Bluetooth Low Energy.", comment: "RileyLink setup description") cell?.textLabel?.numberOfLines = 0 } return cell! diff --git a/RileyLinkKitUI/de.lproj/InfoPlist.strings b/RileyLinkKitUI/de.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKitUI/de.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKitUI/de.lproj/Localizable.strings b/RileyLinkKitUI/de.lproj/Localizable.strings new file mode 100644 index 000000000..8594bf650 --- /dev/null +++ b/RileyLinkKitUI/de.lproj/Localizable.strings @@ -0,0 +1,51 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Aktiv bis"; + +/* The title of the section describing commands */ +"Commands" = "Befehle"; + +/* The connected state */ +"Connected" = "Verbunden"; + +/* The in-progress connecting state */ +"Connecting" = "Verbinden"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Verbindungsstatus"; + +/* The title of the section describing the device */ +"Device" = "Gerät"; + +/* The title of the devices table section in RileyLink settings */ +"Devices" = "Geräte"; + +/* The disconnected state */ +"Disconnected" = "Getrennt"; + +/* The in-progress disconnecting state */ +"Disconnecting" = "trennen"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Firmware"; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "Zuletzt aktiv"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Signal aus"; + +/* The title of the cell showing device name */ +"Name" = "Nombre"; + +/* The title of the cell showing the last idle */ +"On Idle" = "im Leerlauf"; + +/* RileyLink setup description */ +"RileyLink allows for communication with the pump over Bluetooth Low Energy." = "RileyLink ermöglicht Kommunikation zur Pumpe über Bluetooth Low Energy."; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Signalstärke"; + diff --git a/RileyLinkKitUI/es.lproj/InfoPlist.strings b/RileyLinkKitUI/es.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKitUI/es.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKitUI/es.lproj/Localizable.strings b/RileyLinkKitUI/es.lproj/Localizable.strings new file mode 100644 index 000000000..59a7a923b --- /dev/null +++ b/RileyLinkKitUI/es.lproj/Localizable.strings @@ -0,0 +1,51 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Despierto hasta"; + +/* The title of the section describing commands */ +"Commands" = "Comandos"; + +/* The connected state */ +"Connected" = "Conectado"; + +/* The in-progress connecting state */ +"Connecting" = "Conectando"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Estado de Conexión"; + +/* The title of the section describing the device */ +"Device" = "Dispositivo"; + +/* The title of the devices table section in RileyLink settings */ +"Devices" = "Dispositivos"; + +/* The disconnected state */ +"Disconnected" = "Desconectado"; + +/* The in-progress disconnecting state */ +"Disconnecting" = "Desconectando"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Firmware"; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "Último Despierto"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Escuchando Apagado"; + +/* The title of the cell showing device name */ +"Name" = "Nombre"; + +/* The title of the cell showing the last idle */ +"On Idle" = "En Inactivo"; + +/* RileyLink setup description */ +"RileyLink allows for communication with the pump over Bluetooth Low Energy." = "RileyLink permite la comunicación con la microinfusora a través del uso de Bluetooth de baja energía."; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Intensidad de señal"; + diff --git a/RileyLinkKitUI/fr.lproj/InfoPlist.strings b/RileyLinkKitUI/fr.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKitUI/fr.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKitUI/fr.lproj/Localizable.strings b/RileyLinkKitUI/fr.lproj/Localizable.strings new file mode 100644 index 000000000..bd9f456b4 --- /dev/null +++ b/RileyLinkKitUI/fr.lproj/Localizable.strings @@ -0,0 +1,51 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Réveillez-vous jusqu’à"; + +/* The title of the section describing commands */ +"Commands" = "Commandes"; + +/* The connected state */ +"Connected" = "Connecté"; + +/* The in-progress connecting state */ +"Connecting" = "De liaison"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Etat de connexion"; + +/* The title of the section describing the device */ +"Device" = "Dispositif"; + +/* The title of the devices table section in RileyLink settings */ +"Devices" = "Dispositifs"; + +/* The disconnected state */ +"Disconnected" = "Débranché"; + +/* The in-progress disconnecting state */ +"Disconnecting" = "Se déconnecter"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Firmware"; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "Dernier éveillé"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Listening Off"; + +/* The title of the cell showing device name */ +"Name" = "Nom"; + +/* The title of the cell showing the last idle */ +"On Idle" = "Au Repos"; + +/* RileyLink setup description */ +"RileyLink allows for communication with the pump over Bluetooth Low Energy." = "RileyLink permet la communication avec la pompe via Bluetooth Low Energy."; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Force du signal"; + diff --git a/RileyLinkKitUI/it.lproj/InfoPlist.strings b/RileyLinkKitUI/it.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKitUI/it.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKitUI/it.lproj/Localizable.strings b/RileyLinkKitUI/it.lproj/Localizable.strings new file mode 100644 index 000000000..147c33f67 --- /dev/null +++ b/RileyLinkKitUI/it.lproj/Localizable.strings @@ -0,0 +1,51 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Attivo fino"; + +/* The title of the section describing commands */ +"Commands" = "Comandi"; + +/* The connected state */ +"Connected" = "Collegato"; + +/* The in-progress connecting state */ +"Connecting" = "In collegamento"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Stato Connessione"; + +/* The title of the section describing the device */ +"Device" = "Dispositivo"; + +/* The title of the devices table section in RileyLink settings */ +"Devices" = "Dispositivi"; + +/* The disconnected state */ +"Disconnected" = "Disconnesso"; + +/* The in-progress disconnecting state */ +"Disconnecting" = "Disconnessione"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Firmware"; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "Ultimo risveglio"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Ascolto Spento"; + +/* The title of the cell showing device name */ +"Name" = "Nome"; + +/* The title of the cell showing the last idle */ +"On Idle" = "Inattivo"; + +/* RileyLink setup description */ +"RileyLink allows for communication with the pump over Bluetooth Low Energy." = "RileyLink consente la comunicazione con il microinfusore tramite Bluetooth Low Energy."; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Potenza Segnale"; + diff --git a/RileyLinkKitUI/nb.lproj/InfoPlist.strings b/RileyLinkKitUI/nb.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKitUI/nb.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKitUI/nb.lproj/Localizable.strings b/RileyLinkKitUI/nb.lproj/Localizable.strings new file mode 100644 index 000000000..1dcee1a80 --- /dev/null +++ b/RileyLinkKitUI/nb.lproj/Localizable.strings @@ -0,0 +1,51 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Våken til"; + +/* The title of the section describing commands */ +"Commands" = "Kommandoer"; + +/* The connected state */ +"Connected" = "Tilkoblet"; + +/* The in-progress connecting state */ +"Connecting" = "Kobler Til"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Tilkoblingsstatus"; + +/* The title of the section describing the device */ +"Device" = "Enhet"; + +/* The title of the devices table section in RileyLink settings */ +"Devices" = "Enheter"; + +/* The disconnected state */ +"Disconnected" = "Frakoblet"; + +/* The in-progress disconnecting state */ +"Disconnecting" = "Kobler Fra"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Firmware"; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "Sist Våken"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Lytting skrudd av skrudd av"; + +/* The title of the cell showing device name */ +"Name" = "Navn"; + +/* The title of the cell showing the last idle */ +"On Idle" = "Pauset"; + +/* RileyLink setup description */ +"RileyLink allows for communication with the pump over Bluetooth Low Energy." = "RileyLink tillater kommunikasjon med pumpen over Bluetooth Low Energy."; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Signalstyrke"; + diff --git a/RileyLinkKitUI/nl.lproj/InfoPlist.strings b/RileyLinkKitUI/nl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKitUI/nl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKitUI/nl.lproj/Localizable.strings b/RileyLinkKitUI/nl.lproj/Localizable.strings new file mode 100644 index 000000000..45aa7b9ce --- /dev/null +++ b/RileyLinkKitUI/nl.lproj/Localizable.strings @@ -0,0 +1,51 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Actief tot"; + +/* The title of the section describing commands */ +"Commands" = "Commando's"; + +/* The connected state */ +"Connected" = "Verbonden"; + +/* The in-progress connecting state */ +"Connecting" = "Verbinden"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Verbindingsstatus"; + +/* The title of the section describing the device */ +"Device" = "Apparaat"; + +/* The title of the devices table section in RileyLink settings */ +"Devices" = "Apparaten"; + +/* The disconnected state */ +"Disconnected" = "Ontkoppeld"; + +/* The in-progress disconnecting state */ +"Disconnecting" = "Ontkoppelen"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Firmware"; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "Laatst actief"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Luisteren uit"; + +/* The title of the cell showing device name */ +"Name" = "Naam"; + +/* The title of the cell showing the last idle */ +"On Idle" = "Inactief"; + +/* RileyLink setup description */ +"RileyLink allows for communication with the pump over Bluetooth Low Energy." = "RileyLink staat verbinding met de pomp toe via Bluetooth Low Energy (BLE of Bluetooth Smart)."; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Signaalsterkte"; + diff --git a/RileyLinkKitUI/ru.lproj/InfoPlist.strings b/RileyLinkKitUI/ru.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKitUI/ru.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKitUI/ru.lproj/Localizable.strings b/RileyLinkKitUI/ru.lproj/Localizable.strings new file mode 100644 index 000000000..e0ce23218 --- /dev/null +++ b/RileyLinkKitUI/ru.lproj/Localizable.strings @@ -0,0 +1,51 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Рабочее состояние до"; + +/* The title of the section describing commands */ +"Commands" = "Команды"; + +/* The connected state */ +"Connected" = "Соединение установлено"; + +/* The in-progress connecting state */ +"Connecting" = "Соединяется"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Состояние соединения"; + +/* The title of the section describing the device */ +"Device" = "устройство"; + +/* The title of the devices table section in RileyLink settings */ +"Devices" = "устройства"; + +/* The disconnected state */ +"Disconnected" = "Разъединено"; + +/* The in-progress disconnecting state */ +"Disconnecting" = "Разъединяется"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Прошивка"; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "Недавнее состояние активности"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Получаю данные от"; + +/* The title of the cell showing device name */ +"Name" = "Название"; + +/* The title of the cell showing the last idle */ +"On Idle" = "Бездействие"; + +/* RileyLink setup description */ +"RileyLink allows for communication with the pump over Bluetooth Low Energy." = "RileyLink позволяет вести коммуникацию с помпой через Bluetooth Low Energy."; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Уровень сигнала"; + diff --git a/RileyLinkKitUI/zh-Hans.lproj/InfoPlist.strings b/RileyLinkKitUI/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKitUI/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKitUI/zh-Hans.lproj/Localizable.strings b/RileyLinkKitUI/zh-Hans.lproj/Localizable.strings new file mode 100644 index 000000000..815d49a0c --- /dev/null +++ b/RileyLinkKitUI/zh-Hans.lproj/Localizable.strings @@ -0,0 +1,51 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "唤醒 "; + +/* The title of the section describing commands */ +"Commands" = "命令"; + +/* The connected state */ +"Connected" = "已连接"; + +/* The in-progress connecting state */ +"Connecting" = "正在连接"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "连接状态"; + +/* The title of the section describing the device */ +"Device" = "设备"; + +/* The title of the devices table section in RileyLink settings */ +"Devices" = "设备"; + +/* The disconnected state */ +"Disconnected" = "已断开连接"; + +/* The in-progress disconnecting state */ +"Disconnecting" = "断开"; + +/* The title of the cell showing firmware version */ +"Firmware" = "固件"; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "最近唤醒"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "监听关闭"; + +/* The title of the cell showing device name */ +"Name" = "设备名称"; + +/* The title of the cell showing the last idle */ +"On Idle" = "空闲"; + +/* RileyLink setup description */ +"RileyLink allows for communication with the pump over Bluetooth Low Energy." = "允许RileyLink通过低功耗蓝牙与泵连接通信"; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "信号强度"; + diff --git a/RileyLinkTests/de.lproj/InfoPlist.strings b/RileyLinkTests/de.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/RileyLinkTests/de.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/RileyLinkTests/fr.lproj/InfoPlist.strings b/RileyLinkTests/fr.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/RileyLinkTests/fr.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/RileyLinkTests/it.lproj/InfoPlist.strings b/RileyLinkTests/it.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/RileyLinkTests/it.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/RileyLinkTests/nb.lproj/InfoPlist.strings b/RileyLinkTests/nb.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/RileyLinkTests/nb.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/RileyLinkTests/nl.lproj/InfoPlist.strings b/RileyLinkTests/nl.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/RileyLinkTests/nl.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/RileyLinkTests/zh-Hans.lproj/InfoPlist.strings b/RileyLinkTests/zh-Hans.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/RileyLinkTests/zh-Hans.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + From adef571daf1412cd58d42d00426febabb3a199eb Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sat, 18 Aug 2018 11:03:16 -0500 Subject: [PATCH 15/22] Bump version, and point to LoopKit release (#433) --- Cartfile | 2 +- Cartfile.resolved | 2 +- Crypto/Info.plist | 2 +- MinimedKit/Info.plist | 2 +- MinimedKitTests/Info.plist | 2 +- MinimedKitUI/Info.plist | 2 +- NightscoutUploadKit/Info.plist | 2 +- NightscoutUploadKitTests/Info.plist | 2 +- RileyLink.xcodeproj/project.pbxproj | 48 ++++++++++++------------ RileyLink/RileyLink-Info.plist | 2 +- RileyLinkBLEKit/Info.plist | 2 +- RileyLinkBLEKitTests/Info.plist | 2 +- RileyLinkKit/Info.plist | 2 +- RileyLinkKitTests/Info.plist | 2 +- RileyLinkKitUI/Info.plist | 2 +- RileyLinkTests/RileyLinkTests-Info.plist | 2 +- 16 files changed, 39 insertions(+), 39 deletions(-) diff --git a/Cartfile b/Cartfile index 05195c51b..49519e1cf 100644 --- a/Cartfile +++ b/Cartfile @@ -1 +1 @@ -github "LoopKit/LoopKit" "dev" +github "LoopKit/LoopKit" == 2.1 diff --git a/Cartfile.resolved b/Cartfile.resolved index fb79a039d..e71e34770 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1 +1 @@ -github "LoopKit/LoopKit" "16fc21d01a7bf0758c6c81dbb25a5168588c9e30" +github "LoopKit/LoopKit" "v2.1" diff --git a/Crypto/Info.plist b/Crypto/Info.plist index e13d2efa7..21e7e6da6 100644 --- a/Crypto/Info.plist +++ b/Crypto/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.0.2 + 2.0.3 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/MinimedKit/Info.plist b/MinimedKit/Info.plist index a16c895d4..0de69c100 100644 --- a/MinimedKit/Info.plist +++ b/MinimedKit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.0.2 + 2.0.3 CFBundleSignature ???? CFBundleVersion diff --git a/MinimedKitTests/Info.plist b/MinimedKitTests/Info.plist index 9798c2ab8..5a6398fbf 100644 --- a/MinimedKitTests/Info.plist +++ b/MinimedKitTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.0.2 + 2.0.3 CFBundleSignature ???? CFBundleVersion diff --git a/MinimedKitUI/Info.plist b/MinimedKitUI/Info.plist index 1007fd9dd..f936f8d95 100644 --- a/MinimedKitUI/Info.plist +++ b/MinimedKitUI/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.0 + 2.0.3 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/NightscoutUploadKit/Info.plist b/NightscoutUploadKit/Info.plist index a16c895d4..0de69c100 100644 --- a/NightscoutUploadKit/Info.plist +++ b/NightscoutUploadKit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.0.2 + 2.0.3 CFBundleSignature ???? CFBundleVersion diff --git a/NightscoutUploadKitTests/Info.plist b/NightscoutUploadKitTests/Info.plist index 6f3a2eb14..f437a4c22 100644 --- a/NightscoutUploadKitTests/Info.plist +++ b/NightscoutUploadKitTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.0.2 + 2.0.3 CFBundleSignature ???? CFBundleVersion diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index c99a2233d..fd261583e 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -3614,7 +3614,7 @@ DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 38; + DYLIB_CURRENT_VERSION = 39; DYLIB_INSTALL_NAME_BASE = "@rpath"; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = RileyLinkBLEKit/Info.plist; @@ -3650,7 +3650,7 @@ DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 38; + DYLIB_CURRENT_VERSION = 39; DYLIB_INSTALL_NAME_BASE = "@rpath"; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = RileyLinkBLEKit/Info.plist; @@ -3734,7 +3734,7 @@ DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; + DYLIB_CURRENT_VERSION = 39; DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -3773,7 +3773,7 @@ DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; + DYLIB_CURRENT_VERSION = 39; DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -3801,11 +3801,11 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - CURRENT_PROJECT_VERSION = 38; + CURRENT_PROJECT_VERSION = 39; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 38; + DYLIB_CURRENT_VERSION = 39; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -3838,11 +3838,11 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 38; + CURRENT_PROJECT_VERSION = 39; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 38; + DYLIB_CURRENT_VERSION = 39; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -3922,12 +3922,12 @@ CLANG_WARN_SUSPICIOUS_MOVES = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - CURRENT_PROJECT_VERSION = 38; + CURRENT_PROJECT_VERSION = 39; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 38; + DYLIB_CURRENT_VERSION = 39; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = Crypto/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -3953,12 +3953,12 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 38; + CURRENT_PROJECT_VERSION = 39; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 38; + DYLIB_CURRENT_VERSION = 39; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = Crypto/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -3988,7 +3988,7 @@ DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 38; + DYLIB_CURRENT_VERSION = 39; DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -4026,7 +4026,7 @@ DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 38; + DYLIB_CURRENT_VERSION = 39; DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -4069,12 +4069,12 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - CURRENT_PROJECT_VERSION = 38; + CURRENT_PROJECT_VERSION = 39; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 38; + DYLIB_CURRENT_VERSION = 39; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -4106,11 +4106,11 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 38; + CURRENT_PROJECT_VERSION = 39; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 38; + DYLIB_CURRENT_VERSION = 39; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -4213,7 +4213,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 38; + CURRENT_PROJECT_VERSION = 39; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -4280,7 +4280,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; - CURRENT_PROJECT_VERSION = 38; + CURRENT_PROJECT_VERSION = 39; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -4404,11 +4404,11 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - CURRENT_PROJECT_VERSION = 38; + CURRENT_PROJECT_VERSION = 39; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 38; + DYLIB_CURRENT_VERSION = 39; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -4434,11 +4434,11 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 38; + CURRENT_PROJECT_VERSION = 39; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 38; + DYLIB_CURRENT_VERSION = 39; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; diff --git a/RileyLink/RileyLink-Info.plist b/RileyLink/RileyLink-Info.plist index b3db443e0..3991a00ee 100644 --- a/RileyLink/RileyLink-Info.plist +++ b/RileyLink/RileyLink-Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2.0.2 + 2.0.3 CFBundleSignature ???? CFBundleVersion diff --git a/RileyLinkBLEKit/Info.plist b/RileyLinkBLEKit/Info.plist index 0e8b81880..f936f8d95 100644 --- a/RileyLinkBLEKit/Info.plist +++ b/RileyLinkBLEKit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.0.2 + 2.0.3 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/RileyLinkBLEKitTests/Info.plist b/RileyLinkBLEKitTests/Info.plist index 83957c236..12db38e68 100644 --- a/RileyLinkBLEKitTests/Info.plist +++ b/RileyLinkBLEKitTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.0.2 + 2.0.3 CFBundleVersion 1 diff --git a/RileyLinkKit/Info.plist b/RileyLinkKit/Info.plist index a16c895d4..0de69c100 100644 --- a/RileyLinkKit/Info.plist +++ b/RileyLinkKit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.0.2 + 2.0.3 CFBundleSignature ???? CFBundleVersion diff --git a/RileyLinkKitTests/Info.plist b/RileyLinkKitTests/Info.plist index 9798c2ab8..5a6398fbf 100644 --- a/RileyLinkKitTests/Info.plist +++ b/RileyLinkKitTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.0.2 + 2.0.3 CFBundleSignature ???? CFBundleVersion diff --git a/RileyLinkKitUI/Info.plist b/RileyLinkKitUI/Info.plist index 0e8b81880..f936f8d95 100644 --- a/RileyLinkKitUI/Info.plist +++ b/RileyLinkKitUI/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.0.2 + 2.0.3 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/RileyLinkTests/RileyLinkTests-Info.plist b/RileyLinkTests/RileyLinkTests-Info.plist index 8e3ad2ab9..f1cae6f2b 100644 --- a/RileyLinkTests/RileyLinkTests-Info.plist +++ b/RileyLinkTests/RileyLinkTests-Info.plist @@ -13,7 +13,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 2.0.2 + 2.0.3 CFBundleSignature ???? CFBundleVersion From fd94505f0240fa4220d7d981493d23182ee8e389 Mon Sep 17 00:00:00 2001 From: katie disimone Date: Sat, 18 Aug 2018 14:23:28 -0700 Subject: [PATCH 16/22] Norwegian touchup and remove unused localized.strings (#437) * translation norwegian * remove unused localized.strings --- MinimedKitUI/nb.lproj/Localizable.strings | 2 +- MinimedKitUI/nl.lproj/Localizable.strings | 2 +- RileyLink.xcodeproj/project.pbxproj | 52 ----- RileyLinkKit/de.lproj/InfoPlist.strings | 3 - RileyLinkKit/de.lproj/Localizable.strings | 189 ------------------ RileyLinkKit/es.lproj/InfoPlist.strings | 3 - RileyLinkKit/es.lproj/Localizable.strings | 189 ------------------ RileyLinkKit/fr.lproj/InfoPlist.strings | 3 - RileyLinkKit/fr.lproj/Localizable.strings | 189 ------------------ RileyLinkKit/it.lproj/InfoPlist.strings | 3 - RileyLinkKit/it.lproj/Localizable.strings | 189 ------------------ RileyLinkKit/nb.lproj/InfoPlist.strings | 3 - RileyLinkKit/nb.lproj/Localizable.strings | 189 ------------------ RileyLinkKit/nl.lproj/InfoPlist.strings | 3 - RileyLinkKit/nl.lproj/Localizable.strings | 189 ------------------ RileyLinkKit/ru.lproj/InfoPlist.strings | 3 - RileyLinkKit/ru.lproj/Localizable.strings | 189 ------------------ RileyLinkKit/zh-Hans.lproj/InfoPlist.strings | 3 - .../zh-Hans.lproj/Localizable.strings | 189 ------------------ RileyLinkKitUI/nb.lproj/Localizable.strings | 6 +- 20 files changed, 5 insertions(+), 1593 deletions(-) delete mode 100644 RileyLinkKit/de.lproj/InfoPlist.strings delete mode 100644 RileyLinkKit/de.lproj/Localizable.strings delete mode 100644 RileyLinkKit/es.lproj/InfoPlist.strings delete mode 100644 RileyLinkKit/es.lproj/Localizable.strings delete mode 100644 RileyLinkKit/fr.lproj/InfoPlist.strings delete mode 100644 RileyLinkKit/fr.lproj/Localizable.strings delete mode 100644 RileyLinkKit/it.lproj/InfoPlist.strings delete mode 100644 RileyLinkKit/it.lproj/Localizable.strings delete mode 100644 RileyLinkKit/nb.lproj/InfoPlist.strings delete mode 100644 RileyLinkKit/nb.lproj/Localizable.strings delete mode 100644 RileyLinkKit/nl.lproj/InfoPlist.strings delete mode 100644 RileyLinkKit/nl.lproj/Localizable.strings delete mode 100644 RileyLinkKit/ru.lproj/InfoPlist.strings delete mode 100644 RileyLinkKit/ru.lproj/Localizable.strings delete mode 100644 RileyLinkKit/zh-Hans.lproj/InfoPlist.strings delete mode 100644 RileyLinkKit/zh-Hans.lproj/Localizable.strings diff --git a/MinimedKitUI/nb.lproj/Localizable.strings b/MinimedKitUI/nb.lproj/Localizable.strings index c985c608c..4fd791035 100644 --- a/MinimedKitUI/nb.lproj/Localizable.strings +++ b/MinimedKitUI/nb.lproj/Localizable.strings @@ -23,7 +23,7 @@ "Awake Until" = "Aktiv til"; /* The title text for the basal rate schedule */ -"Basal Rates" = "Basaldose"; +"Basal Rates" = "Basaldoser"; /* The format string describing pump battery voltage: (1: battery voltage) */ "Battery: %1$@ volts\n" = "Batteri: %1$@ volt\n"; diff --git a/MinimedKitUI/nl.lproj/Localizable.strings b/MinimedKitUI/nl.lproj/Localizable.strings index a13a2b342..e92dc7055 100644 --- a/MinimedKitUI/nl.lproj/Localizable.strings +++ b/MinimedKitUI/nl.lproj/Localizable.strings @@ -111,7 +111,7 @@ "Last Awake" = "Laatst actief"; /* The title of the cell describing no radio awake data */ -"Listening Off" = "Luisteren Uit"; +"Listening Off" = "Luisteren uit"; /* The title of the command to pair with mysentry */ "MySentry Pair" = "MySentry verbinden"; diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index fd261583e..a5616413c 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -285,10 +285,8 @@ 7D23679421252EBC0028B67D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23679221252EBC0028B67D /* Localizable.strings */; }; 7D23679721252EBC0028B67D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23679521252EBC0028B67D /* Localizable.strings */; }; 7D70766D1FE092D4004AC8EA /* LoopKit.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D70766F1FE092D4004AC8EA /* LoopKit.strings */; }; - 7D7076721FE092D5004AC8EA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D7076741FE092D5004AC8EA /* Localizable.strings */; }; 7D7076771FE092D6004AC8EA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D7076791FE092D6004AC8EA /* InfoPlist.strings */; }; 7D70767C1FE092D6004AC8EA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D70767E1FE092D6004AC8EA /* InfoPlist.strings */; }; - 7D7076811FE092D7004AC8EA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D7076831FE092D7004AC8EA /* InfoPlist.strings */; }; 7D70768B1FE09310004AC8EA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D70768D1FE09310004AC8EA /* Localizable.strings */; }; 7D7076901FE09311004AC8EA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D7076921FE09311004AC8EA /* InfoPlist.strings */; }; 7D7076951FE09311004AC8EA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D7076971FE09311004AC8EA /* Localizable.strings */; }; @@ -867,8 +865,6 @@ 7D2366FE212529520028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; 7D2366FF212529520028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; 7D236700212529520028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D236701212529520028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D236702212529520028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; 7D236703212529520028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; 7D236704212529530028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; 7D236705212529530028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -879,8 +875,6 @@ 7D23670A2125297B0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23670B2125297B0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; 7D23670C2125297B0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D23670D2125297B0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D23670E2125297C0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; 7D23670F2125297C0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; 7D2367102125297C0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; 7D2367112125297C0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -891,8 +885,6 @@ 7D236716212529820028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; 7D236717212529820028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; 7D236718212529820028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; - 7D236719212529820028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; - 7D23671A212529820028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; 7D23671B212529820028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; 7D23671C212529830028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; 7D23671D212529830028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; @@ -903,8 +895,6 @@ 7D236722212529890028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; 7D236723212529890028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; 7D2367242125298A0028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D2367252125298A0028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D2367262125298A0028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; 7D2367272125298A0028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; 7D2367282125298A0028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; 7D2367292125298A0028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -915,8 +905,6 @@ 7D23672E212529950028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23672F212529950028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; 7D236730212529950028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D236731212529950028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D236732212529950028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; 7D236733212529950028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; 7D236734212529960028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; 7D236735212529960028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -927,8 +915,6 @@ 7D23673A212529A00028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23673B212529A00028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Localizable.strings; sourceTree = ""; }; 7D23673C212529A00028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D23673D212529A00028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D23673E212529A00028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Localizable.strings; sourceTree = ""; }; 7D23673F212529A00028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; 7D236740212529A10028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; 7D236741212529A10028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -1017,16 +1003,12 @@ 7D68AACE1FE31DEB00522C49 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; 7D68AACF1FE31DEB00522C49 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; 7D68AAD01FE31DEB00522C49 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D68AAD11FE31DEB00522C49 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; 7D68AAD21FE31DEC00522C49 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; 7D68AAD31FE31DEC00522C49 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; 7D68AAD41FE31DEC00522C49 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D68AAD51FE31DEC00522C49 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; 7D70766E1FE092D4004AC8EA /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/LoopKit.strings; sourceTree = ""; }; - 7D7076731FE092D5004AC8EA /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; 7D7076781FE092D6004AC8EA /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; 7D70767D1FE092D6004AC8EA /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D7076821FE092D7004AC8EA /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; 7D7076871FE092D7004AC8EA /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; 7D70768C1FE09310004AC8EA /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; 7D7076911FE09311004AC8EA /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -1494,8 +1476,6 @@ 43722FAF1CB9F7630038B7F2 /* RileyLinkKit */ = { isa = PBXGroup; children = ( - 7D7076831FE092D7004AC8EA /* InfoPlist.strings */, - 7D7076741FE092D5004AC8EA /* Localizable.strings */, 43722FB01CB9F7640038B7F2 /* RileyLinkKit.h */, 43722FB21CB9F7640038B7F2 /* Info.plist */, 437F54061FBD52120070FF2C /* DeviceState.swift */, @@ -2565,8 +2545,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 7D7076811FE092D7004AC8EA /* InfoPlist.strings in Resources */, - 7D7076721FE092D5004AC8EA /* Localizable.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3440,21 +3418,6 @@ name = LoopKit.strings; sourceTree = ""; }; - 7D7076741FE092D5004AC8EA /* Localizable.strings */ = { - isa = PBXVariantGroup; - children = ( - 7D7076731FE092D5004AC8EA /* es */, - 7D68AAD51FE31DEC00522C49 /* ru */, - 7D236702212529520028B67D /* fr */, - 7D23670E2125297C0028B67D /* de */, - 7D23671A212529820028B67D /* zh-Hans */, - 7D2367262125298A0028B67D /* it */, - 7D236732212529950028B67D /* nl */, - 7D23673E212529A00028B67D /* nb */, - ); - name = Localizable.strings; - sourceTree = ""; - }; 7D7076791FE092D6004AC8EA /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( @@ -3485,21 +3448,6 @@ name = InfoPlist.strings; sourceTree = ""; }; - 7D7076831FE092D7004AC8EA /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - 7D7076821FE092D7004AC8EA /* es */, - 7D68AAD11FE31DEB00522C49 /* ru */, - 7D236701212529520028B67D /* fr */, - 7D23670D2125297B0028B67D /* de */, - 7D236719212529820028B67D /* zh-Hans */, - 7D2367252125298A0028B67D /* it */, - 7D236731212529950028B67D /* nl */, - 7D23673D212529A00028B67D /* nb */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; 7D7076881FE092D7004AC8EA /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( diff --git a/RileyLinkKit/de.lproj/InfoPlist.strings b/RileyLinkKit/de.lproj/InfoPlist.strings deleted file mode 100644 index bbcf8f904..000000000 --- a/RileyLinkKit/de.lproj/InfoPlist.strings +++ /dev/null @@ -1,3 +0,0 @@ -/* Bundle name */ -"CFBundleName" = "$(PRODUCT_NAME)"; - diff --git a/RileyLinkKit/de.lproj/Localizable.strings b/RileyLinkKit/de.lproj/Localizable.strings deleted file mode 100644 index fd9cfbc60..000000000 --- a/RileyLinkKit/de.lproj/Localizable.strings +++ /dev/null @@ -1,189 +0,0 @@ -/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ -"%1$@ MHz %2$@/%3$@ %4$@" = "%1$@ MHz %2$@/%3$@ %4$@"; - -/* Describes a certain bolus failure (1: size of the bolus in units) */ -"%1$@ U bolus failed" = "%1$@ U Bolo Falló"; - -/* Describes an uncertain bolus failure (1: size of the bolus in units) */ -"%1$@ U bolus may not have succeeded" = "%1$@ U bolo posiblemente fallado"; - -/* The format string describing units of insulin remaining: (1: number of units) */ -"%1$@ Units of insulin remaining\n" = "%1$@ Unidades de insulina restantes"; - -/* The format string describing number of basal schedule entries: (1: number of entries) */ -"%1$@ basal schedule entries\n" = "%1$@ entradas de prefil basal"; - -/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ -"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; - -/* Communications error for a bolus currently running */ -"A bolus is already in progress" = "Un bolo ya está en progreso"; - -/* The title of the cell describing an awake radio */ -"Awake Until" = "Despierto hasta"; - -/* The format string describing pump battery voltage: (1: battery voltage) */ -"Battery: %1$@ volts\n" = "Pila: %1$@ voltios"; - -/* The label indicating the best radio frequency */ -"Best Frequency" = "Mejor Frecuencia"; - -/* The format string describing pump bolusing state: (1: bolusing) */ -"Bolusing: %1$@\n" = "Bolo en progreso: %1$@"; - -/* The title of the command to change pump time */ -"Change Time" = "Cambio de Hora"; - -/* Progress message for changing pump time. */ -"Changing time…" = "Cambio de Hora..."; - -/* Recovery instruction for an uncertain bolus failure */ -"Check your pump before retrying." = "Revisar su microinfusadora antes de intentarlo de nuevo"; - -/* The title of the section describing commands */ -"Commands" = "Comandos"; - -/* No comment provided by engineer. */ -"Comms with another pump detected." = "Comunicación con otra microinfusadora detectado."; - -/* The connected state */ -"Connected" = "Conectado"; - -/* The in-progress connecting state */ -"Connecting" = "Conectando"; - -/* The title of the cell showing BLE connection state */ -"Connection State" = "Estado de Conexión"; - -/* The title of the section describing the device */ -"Device" = "Dispositivo"; - -/* The disconnected state */ -"Disconnected" = "Desconectado"; - -/* The in-progress disconnecting state */ -"Disconnecting" = "Desconectando"; - -/* The error displayed during MySentry pairing when the RX filter could not be set */ -"Error setting filter bandwidth: %@" = "Error al establecer el ancho de banda del filtro: %@"; - -/* The title of the command to fetch recent glucose */ -"Fetch Recent Glucose" = "Obtener Glucosa Reciente"; - -/* The title of the command to fetch recent history */ -"Fetch Recent History" = "Obtener Historia Reciente"; - -/* Progress message for fetching pump glucose. */ -"Fetching glucose…" = "Obteniendo glucosa…"; - -/* Progress message for fetching pump history. */ -"Fetching history…" = "Obteniendo historia…"; - -/* Progress message for fetching pump model. */ -"Fetching pump model…" = "Obteniendo modelo de microinfusadora…"; - -/* The title of the cell showing firmware version */ -"Firmware" = "Firmware"; - -/* The title of the command to get pump model */ -"Get Pump Model" = "Obtener Modelo de Microinfusadora"; - -/* Recovery instruction for a certain bolus failure */ -"It is safe to retry" = "Es seguro intentarlo de nuevo."; - -/* The title of the cell describing an awake radio */ -"Last Awake" = "último despierto"; - -/* The title of the cell describing no radio awake data */ -"Listening Off" = "Escuchando apagado"; - -/* The title of the command to pair with mysentry */ -"MySentry Pair" = "Junta de MySentry"; - -/* The title of the cell showing device name */ -"Name" = "Nombre"; - -/* Message display when no response from tuning pump */ -"No response" = "No respuesta"; - -/* The title of the cell showing the last idle */ -"On Idle" = "En Inactivo"; - -/* The title of the section describing the pump */ -"Pump" = "Microinfusadora"; - -/* The title of the cell showing pump ID */ -"Pump ID" = "ID de Microinfusadora"; - -/* The title of the cell showing the pump model number */ -"Pump Model" = "Modelo de Microinfusadora"; - -/* No comment provided by engineer. */ -"Pump did not respond." = "Microinfusadora no respondió."; - -/* The format string description of a Pump Error. (1: The specific error code) */ -"Pump error: %1$@" = "Error de Microinfusadora: %1$@"; - -/* No comment provided by engineer. */ -"Pump is suspended." = "Micorinfusadora está suspendida"; - -/* No comment provided by engineer. */ -"Pump responded unexpectedly." = "Micorinfusadora respondió inesperadamente."; - -/* The title of the command to read basal schedule */ -"Read Basal Schedule" = "Obtener prefil basal"; - -/* The title of the command to read pump status */ -"Read Pump Status" = "Obtener estada de microinfusadora"; - -/* Progress message for reading basal schedule */ -"Reading basal schedule…" = "Obteniendo perfil basal…"; - -/* Progress message for reading pump status */ -"Reading pump status…" = "Obteniendo estada de microinfusadora…"; - -/* No comment provided by engineer. */ -"RileyLink timed out." = "RileyLink agotó el tiempo."; - -/* The title of the command to send a button press */ -"Send Button Press" = "Enviar presion de botón"; - -/* Progress message for sending button press to pump. */ -"Sending button press…" = "Enviando presion de botón…"; - -/* The title of the cell showing BLE signal strength (RSSI) */ -"Signal Strength" = "Intensidad de señal"; - -/* A message indicating a command succeeded */ -"Succeeded" = "éxito"; - -/* The format string describing pump suspended state: (1: suspended) */ -"Suspended: %1$@\n" = "Suspendida: %1$@"; - -/* The label indicating the results of each frequency trial */ -"Trials" = "Pruebas"; - -/* The title of the command to re-tune the radio */ -"Tune Radio Frequency" = "Sintonizar frecuencia de radio"; - -/* Progress message for tuning radio */ -"Tuning radio…" = "Sintonizando frecuencia de radio…"; - -/* The detail text for an unknown pump model */ -"Unknown" = "Desconocido"; - -/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ -"Unknown pump error code: %1$@" = "Codigo desconocido de microinfusadora: %1$@"; - -/* No comment provided by engineer. */ -"Unknown pump model." = "Desconocido modelo de microinfusadora."; - -/* No comment provided by engineer. */ -"Unknown response from pump." = "Respuesta desconocida de microinfusora"; - -/* The title of the command to write a glucose history timestamp */ -"Write Glucose History Timestamp" = "Recordar la hora de glucosa historia"; - -/* Progress message for writing glucose history timestamp. */ -"Writing glucose history timestamp…" = "Recordando la hora de glucosa historia…"; - diff --git a/RileyLinkKit/es.lproj/InfoPlist.strings b/RileyLinkKit/es.lproj/InfoPlist.strings deleted file mode 100644 index bbcf8f904..000000000 --- a/RileyLinkKit/es.lproj/InfoPlist.strings +++ /dev/null @@ -1,3 +0,0 @@ -/* Bundle name */ -"CFBundleName" = "$(PRODUCT_NAME)"; - diff --git a/RileyLinkKit/es.lproj/Localizable.strings b/RileyLinkKit/es.lproj/Localizable.strings deleted file mode 100644 index fd9cfbc60..000000000 --- a/RileyLinkKit/es.lproj/Localizable.strings +++ /dev/null @@ -1,189 +0,0 @@ -/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ -"%1$@ MHz %2$@/%3$@ %4$@" = "%1$@ MHz %2$@/%3$@ %4$@"; - -/* Describes a certain bolus failure (1: size of the bolus in units) */ -"%1$@ U bolus failed" = "%1$@ U Bolo Falló"; - -/* Describes an uncertain bolus failure (1: size of the bolus in units) */ -"%1$@ U bolus may not have succeeded" = "%1$@ U bolo posiblemente fallado"; - -/* The format string describing units of insulin remaining: (1: number of units) */ -"%1$@ Units of insulin remaining\n" = "%1$@ Unidades de insulina restantes"; - -/* The format string describing number of basal schedule entries: (1: number of entries) */ -"%1$@ basal schedule entries\n" = "%1$@ entradas de prefil basal"; - -/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ -"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; - -/* Communications error for a bolus currently running */ -"A bolus is already in progress" = "Un bolo ya está en progreso"; - -/* The title of the cell describing an awake radio */ -"Awake Until" = "Despierto hasta"; - -/* The format string describing pump battery voltage: (1: battery voltage) */ -"Battery: %1$@ volts\n" = "Pila: %1$@ voltios"; - -/* The label indicating the best radio frequency */ -"Best Frequency" = "Mejor Frecuencia"; - -/* The format string describing pump bolusing state: (1: bolusing) */ -"Bolusing: %1$@\n" = "Bolo en progreso: %1$@"; - -/* The title of the command to change pump time */ -"Change Time" = "Cambio de Hora"; - -/* Progress message for changing pump time. */ -"Changing time…" = "Cambio de Hora..."; - -/* Recovery instruction for an uncertain bolus failure */ -"Check your pump before retrying." = "Revisar su microinfusadora antes de intentarlo de nuevo"; - -/* The title of the section describing commands */ -"Commands" = "Comandos"; - -/* No comment provided by engineer. */ -"Comms with another pump detected." = "Comunicación con otra microinfusadora detectado."; - -/* The connected state */ -"Connected" = "Conectado"; - -/* The in-progress connecting state */ -"Connecting" = "Conectando"; - -/* The title of the cell showing BLE connection state */ -"Connection State" = "Estado de Conexión"; - -/* The title of the section describing the device */ -"Device" = "Dispositivo"; - -/* The disconnected state */ -"Disconnected" = "Desconectado"; - -/* The in-progress disconnecting state */ -"Disconnecting" = "Desconectando"; - -/* The error displayed during MySentry pairing when the RX filter could not be set */ -"Error setting filter bandwidth: %@" = "Error al establecer el ancho de banda del filtro: %@"; - -/* The title of the command to fetch recent glucose */ -"Fetch Recent Glucose" = "Obtener Glucosa Reciente"; - -/* The title of the command to fetch recent history */ -"Fetch Recent History" = "Obtener Historia Reciente"; - -/* Progress message for fetching pump glucose. */ -"Fetching glucose…" = "Obteniendo glucosa…"; - -/* Progress message for fetching pump history. */ -"Fetching history…" = "Obteniendo historia…"; - -/* Progress message for fetching pump model. */ -"Fetching pump model…" = "Obteniendo modelo de microinfusadora…"; - -/* The title of the cell showing firmware version */ -"Firmware" = "Firmware"; - -/* The title of the command to get pump model */ -"Get Pump Model" = "Obtener Modelo de Microinfusadora"; - -/* Recovery instruction for a certain bolus failure */ -"It is safe to retry" = "Es seguro intentarlo de nuevo."; - -/* The title of the cell describing an awake radio */ -"Last Awake" = "último despierto"; - -/* The title of the cell describing no radio awake data */ -"Listening Off" = "Escuchando apagado"; - -/* The title of the command to pair with mysentry */ -"MySentry Pair" = "Junta de MySentry"; - -/* The title of the cell showing device name */ -"Name" = "Nombre"; - -/* Message display when no response from tuning pump */ -"No response" = "No respuesta"; - -/* The title of the cell showing the last idle */ -"On Idle" = "En Inactivo"; - -/* The title of the section describing the pump */ -"Pump" = "Microinfusadora"; - -/* The title of the cell showing pump ID */ -"Pump ID" = "ID de Microinfusadora"; - -/* The title of the cell showing the pump model number */ -"Pump Model" = "Modelo de Microinfusadora"; - -/* No comment provided by engineer. */ -"Pump did not respond." = "Microinfusadora no respondió."; - -/* The format string description of a Pump Error. (1: The specific error code) */ -"Pump error: %1$@" = "Error de Microinfusadora: %1$@"; - -/* No comment provided by engineer. */ -"Pump is suspended." = "Micorinfusadora está suspendida"; - -/* No comment provided by engineer. */ -"Pump responded unexpectedly." = "Micorinfusadora respondió inesperadamente."; - -/* The title of the command to read basal schedule */ -"Read Basal Schedule" = "Obtener prefil basal"; - -/* The title of the command to read pump status */ -"Read Pump Status" = "Obtener estada de microinfusadora"; - -/* Progress message for reading basal schedule */ -"Reading basal schedule…" = "Obteniendo perfil basal…"; - -/* Progress message for reading pump status */ -"Reading pump status…" = "Obteniendo estada de microinfusadora…"; - -/* No comment provided by engineer. */ -"RileyLink timed out." = "RileyLink agotó el tiempo."; - -/* The title of the command to send a button press */ -"Send Button Press" = "Enviar presion de botón"; - -/* Progress message for sending button press to pump. */ -"Sending button press…" = "Enviando presion de botón…"; - -/* The title of the cell showing BLE signal strength (RSSI) */ -"Signal Strength" = "Intensidad de señal"; - -/* A message indicating a command succeeded */ -"Succeeded" = "éxito"; - -/* The format string describing pump suspended state: (1: suspended) */ -"Suspended: %1$@\n" = "Suspendida: %1$@"; - -/* The label indicating the results of each frequency trial */ -"Trials" = "Pruebas"; - -/* The title of the command to re-tune the radio */ -"Tune Radio Frequency" = "Sintonizar frecuencia de radio"; - -/* Progress message for tuning radio */ -"Tuning radio…" = "Sintonizando frecuencia de radio…"; - -/* The detail text for an unknown pump model */ -"Unknown" = "Desconocido"; - -/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ -"Unknown pump error code: %1$@" = "Codigo desconocido de microinfusadora: %1$@"; - -/* No comment provided by engineer. */ -"Unknown pump model." = "Desconocido modelo de microinfusadora."; - -/* No comment provided by engineer. */ -"Unknown response from pump." = "Respuesta desconocida de microinfusora"; - -/* The title of the command to write a glucose history timestamp */ -"Write Glucose History Timestamp" = "Recordar la hora de glucosa historia"; - -/* Progress message for writing glucose history timestamp. */ -"Writing glucose history timestamp…" = "Recordando la hora de glucosa historia…"; - diff --git a/RileyLinkKit/fr.lproj/InfoPlist.strings b/RileyLinkKit/fr.lproj/InfoPlist.strings deleted file mode 100644 index bbcf8f904..000000000 --- a/RileyLinkKit/fr.lproj/InfoPlist.strings +++ /dev/null @@ -1,3 +0,0 @@ -/* Bundle name */ -"CFBundleName" = "$(PRODUCT_NAME)"; - diff --git a/RileyLinkKit/fr.lproj/Localizable.strings b/RileyLinkKit/fr.lproj/Localizable.strings deleted file mode 100644 index fd9cfbc60..000000000 --- a/RileyLinkKit/fr.lproj/Localizable.strings +++ /dev/null @@ -1,189 +0,0 @@ -/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ -"%1$@ MHz %2$@/%3$@ %4$@" = "%1$@ MHz %2$@/%3$@ %4$@"; - -/* Describes a certain bolus failure (1: size of the bolus in units) */ -"%1$@ U bolus failed" = "%1$@ U Bolo Falló"; - -/* Describes an uncertain bolus failure (1: size of the bolus in units) */ -"%1$@ U bolus may not have succeeded" = "%1$@ U bolo posiblemente fallado"; - -/* The format string describing units of insulin remaining: (1: number of units) */ -"%1$@ Units of insulin remaining\n" = "%1$@ Unidades de insulina restantes"; - -/* The format string describing number of basal schedule entries: (1: number of entries) */ -"%1$@ basal schedule entries\n" = "%1$@ entradas de prefil basal"; - -/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ -"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; - -/* Communications error for a bolus currently running */ -"A bolus is already in progress" = "Un bolo ya está en progreso"; - -/* The title of the cell describing an awake radio */ -"Awake Until" = "Despierto hasta"; - -/* The format string describing pump battery voltage: (1: battery voltage) */ -"Battery: %1$@ volts\n" = "Pila: %1$@ voltios"; - -/* The label indicating the best radio frequency */ -"Best Frequency" = "Mejor Frecuencia"; - -/* The format string describing pump bolusing state: (1: bolusing) */ -"Bolusing: %1$@\n" = "Bolo en progreso: %1$@"; - -/* The title of the command to change pump time */ -"Change Time" = "Cambio de Hora"; - -/* Progress message for changing pump time. */ -"Changing time…" = "Cambio de Hora..."; - -/* Recovery instruction for an uncertain bolus failure */ -"Check your pump before retrying." = "Revisar su microinfusadora antes de intentarlo de nuevo"; - -/* The title of the section describing commands */ -"Commands" = "Comandos"; - -/* No comment provided by engineer. */ -"Comms with another pump detected." = "Comunicación con otra microinfusadora detectado."; - -/* The connected state */ -"Connected" = "Conectado"; - -/* The in-progress connecting state */ -"Connecting" = "Conectando"; - -/* The title of the cell showing BLE connection state */ -"Connection State" = "Estado de Conexión"; - -/* The title of the section describing the device */ -"Device" = "Dispositivo"; - -/* The disconnected state */ -"Disconnected" = "Desconectado"; - -/* The in-progress disconnecting state */ -"Disconnecting" = "Desconectando"; - -/* The error displayed during MySentry pairing when the RX filter could not be set */ -"Error setting filter bandwidth: %@" = "Error al establecer el ancho de banda del filtro: %@"; - -/* The title of the command to fetch recent glucose */ -"Fetch Recent Glucose" = "Obtener Glucosa Reciente"; - -/* The title of the command to fetch recent history */ -"Fetch Recent History" = "Obtener Historia Reciente"; - -/* Progress message for fetching pump glucose. */ -"Fetching glucose…" = "Obteniendo glucosa…"; - -/* Progress message for fetching pump history. */ -"Fetching history…" = "Obteniendo historia…"; - -/* Progress message for fetching pump model. */ -"Fetching pump model…" = "Obteniendo modelo de microinfusadora…"; - -/* The title of the cell showing firmware version */ -"Firmware" = "Firmware"; - -/* The title of the command to get pump model */ -"Get Pump Model" = "Obtener Modelo de Microinfusadora"; - -/* Recovery instruction for a certain bolus failure */ -"It is safe to retry" = "Es seguro intentarlo de nuevo."; - -/* The title of the cell describing an awake radio */ -"Last Awake" = "último despierto"; - -/* The title of the cell describing no radio awake data */ -"Listening Off" = "Escuchando apagado"; - -/* The title of the command to pair with mysentry */ -"MySentry Pair" = "Junta de MySentry"; - -/* The title of the cell showing device name */ -"Name" = "Nombre"; - -/* Message display when no response from tuning pump */ -"No response" = "No respuesta"; - -/* The title of the cell showing the last idle */ -"On Idle" = "En Inactivo"; - -/* The title of the section describing the pump */ -"Pump" = "Microinfusadora"; - -/* The title of the cell showing pump ID */ -"Pump ID" = "ID de Microinfusadora"; - -/* The title of the cell showing the pump model number */ -"Pump Model" = "Modelo de Microinfusadora"; - -/* No comment provided by engineer. */ -"Pump did not respond." = "Microinfusadora no respondió."; - -/* The format string description of a Pump Error. (1: The specific error code) */ -"Pump error: %1$@" = "Error de Microinfusadora: %1$@"; - -/* No comment provided by engineer. */ -"Pump is suspended." = "Micorinfusadora está suspendida"; - -/* No comment provided by engineer. */ -"Pump responded unexpectedly." = "Micorinfusadora respondió inesperadamente."; - -/* The title of the command to read basal schedule */ -"Read Basal Schedule" = "Obtener prefil basal"; - -/* The title of the command to read pump status */ -"Read Pump Status" = "Obtener estada de microinfusadora"; - -/* Progress message for reading basal schedule */ -"Reading basal schedule…" = "Obteniendo perfil basal…"; - -/* Progress message for reading pump status */ -"Reading pump status…" = "Obteniendo estada de microinfusadora…"; - -/* No comment provided by engineer. */ -"RileyLink timed out." = "RileyLink agotó el tiempo."; - -/* The title of the command to send a button press */ -"Send Button Press" = "Enviar presion de botón"; - -/* Progress message for sending button press to pump. */ -"Sending button press…" = "Enviando presion de botón…"; - -/* The title of the cell showing BLE signal strength (RSSI) */ -"Signal Strength" = "Intensidad de señal"; - -/* A message indicating a command succeeded */ -"Succeeded" = "éxito"; - -/* The format string describing pump suspended state: (1: suspended) */ -"Suspended: %1$@\n" = "Suspendida: %1$@"; - -/* The label indicating the results of each frequency trial */ -"Trials" = "Pruebas"; - -/* The title of the command to re-tune the radio */ -"Tune Radio Frequency" = "Sintonizar frecuencia de radio"; - -/* Progress message for tuning radio */ -"Tuning radio…" = "Sintonizando frecuencia de radio…"; - -/* The detail text for an unknown pump model */ -"Unknown" = "Desconocido"; - -/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ -"Unknown pump error code: %1$@" = "Codigo desconocido de microinfusadora: %1$@"; - -/* No comment provided by engineer. */ -"Unknown pump model." = "Desconocido modelo de microinfusadora."; - -/* No comment provided by engineer. */ -"Unknown response from pump." = "Respuesta desconocida de microinfusora"; - -/* The title of the command to write a glucose history timestamp */ -"Write Glucose History Timestamp" = "Recordar la hora de glucosa historia"; - -/* Progress message for writing glucose history timestamp. */ -"Writing glucose history timestamp…" = "Recordando la hora de glucosa historia…"; - diff --git a/RileyLinkKit/it.lproj/InfoPlist.strings b/RileyLinkKit/it.lproj/InfoPlist.strings deleted file mode 100644 index bbcf8f904..000000000 --- a/RileyLinkKit/it.lproj/InfoPlist.strings +++ /dev/null @@ -1,3 +0,0 @@ -/* Bundle name */ -"CFBundleName" = "$(PRODUCT_NAME)"; - diff --git a/RileyLinkKit/it.lproj/Localizable.strings b/RileyLinkKit/it.lproj/Localizable.strings deleted file mode 100644 index fd9cfbc60..000000000 --- a/RileyLinkKit/it.lproj/Localizable.strings +++ /dev/null @@ -1,189 +0,0 @@ -/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ -"%1$@ MHz %2$@/%3$@ %4$@" = "%1$@ MHz %2$@/%3$@ %4$@"; - -/* Describes a certain bolus failure (1: size of the bolus in units) */ -"%1$@ U bolus failed" = "%1$@ U Bolo Falló"; - -/* Describes an uncertain bolus failure (1: size of the bolus in units) */ -"%1$@ U bolus may not have succeeded" = "%1$@ U bolo posiblemente fallado"; - -/* The format string describing units of insulin remaining: (1: number of units) */ -"%1$@ Units of insulin remaining\n" = "%1$@ Unidades de insulina restantes"; - -/* The format string describing number of basal schedule entries: (1: number of entries) */ -"%1$@ basal schedule entries\n" = "%1$@ entradas de prefil basal"; - -/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ -"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; - -/* Communications error for a bolus currently running */ -"A bolus is already in progress" = "Un bolo ya está en progreso"; - -/* The title of the cell describing an awake radio */ -"Awake Until" = "Despierto hasta"; - -/* The format string describing pump battery voltage: (1: battery voltage) */ -"Battery: %1$@ volts\n" = "Pila: %1$@ voltios"; - -/* The label indicating the best radio frequency */ -"Best Frequency" = "Mejor Frecuencia"; - -/* The format string describing pump bolusing state: (1: bolusing) */ -"Bolusing: %1$@\n" = "Bolo en progreso: %1$@"; - -/* The title of the command to change pump time */ -"Change Time" = "Cambio de Hora"; - -/* Progress message for changing pump time. */ -"Changing time…" = "Cambio de Hora..."; - -/* Recovery instruction for an uncertain bolus failure */ -"Check your pump before retrying." = "Revisar su microinfusadora antes de intentarlo de nuevo"; - -/* The title of the section describing commands */ -"Commands" = "Comandos"; - -/* No comment provided by engineer. */ -"Comms with another pump detected." = "Comunicación con otra microinfusadora detectado."; - -/* The connected state */ -"Connected" = "Conectado"; - -/* The in-progress connecting state */ -"Connecting" = "Conectando"; - -/* The title of the cell showing BLE connection state */ -"Connection State" = "Estado de Conexión"; - -/* The title of the section describing the device */ -"Device" = "Dispositivo"; - -/* The disconnected state */ -"Disconnected" = "Desconectado"; - -/* The in-progress disconnecting state */ -"Disconnecting" = "Desconectando"; - -/* The error displayed during MySentry pairing when the RX filter could not be set */ -"Error setting filter bandwidth: %@" = "Error al establecer el ancho de banda del filtro: %@"; - -/* The title of the command to fetch recent glucose */ -"Fetch Recent Glucose" = "Obtener Glucosa Reciente"; - -/* The title of the command to fetch recent history */ -"Fetch Recent History" = "Obtener Historia Reciente"; - -/* Progress message for fetching pump glucose. */ -"Fetching glucose…" = "Obteniendo glucosa…"; - -/* Progress message for fetching pump history. */ -"Fetching history…" = "Obteniendo historia…"; - -/* Progress message for fetching pump model. */ -"Fetching pump model…" = "Obteniendo modelo de microinfusadora…"; - -/* The title of the cell showing firmware version */ -"Firmware" = "Firmware"; - -/* The title of the command to get pump model */ -"Get Pump Model" = "Obtener Modelo de Microinfusadora"; - -/* Recovery instruction for a certain bolus failure */ -"It is safe to retry" = "Es seguro intentarlo de nuevo."; - -/* The title of the cell describing an awake radio */ -"Last Awake" = "último despierto"; - -/* The title of the cell describing no radio awake data */ -"Listening Off" = "Escuchando apagado"; - -/* The title of the command to pair with mysentry */ -"MySentry Pair" = "Junta de MySentry"; - -/* The title of the cell showing device name */ -"Name" = "Nombre"; - -/* Message display when no response from tuning pump */ -"No response" = "No respuesta"; - -/* The title of the cell showing the last idle */ -"On Idle" = "En Inactivo"; - -/* The title of the section describing the pump */ -"Pump" = "Microinfusadora"; - -/* The title of the cell showing pump ID */ -"Pump ID" = "ID de Microinfusadora"; - -/* The title of the cell showing the pump model number */ -"Pump Model" = "Modelo de Microinfusadora"; - -/* No comment provided by engineer. */ -"Pump did not respond." = "Microinfusadora no respondió."; - -/* The format string description of a Pump Error. (1: The specific error code) */ -"Pump error: %1$@" = "Error de Microinfusadora: %1$@"; - -/* No comment provided by engineer. */ -"Pump is suspended." = "Micorinfusadora está suspendida"; - -/* No comment provided by engineer. */ -"Pump responded unexpectedly." = "Micorinfusadora respondió inesperadamente."; - -/* The title of the command to read basal schedule */ -"Read Basal Schedule" = "Obtener prefil basal"; - -/* The title of the command to read pump status */ -"Read Pump Status" = "Obtener estada de microinfusadora"; - -/* Progress message for reading basal schedule */ -"Reading basal schedule…" = "Obteniendo perfil basal…"; - -/* Progress message for reading pump status */ -"Reading pump status…" = "Obteniendo estada de microinfusadora…"; - -/* No comment provided by engineer. */ -"RileyLink timed out." = "RileyLink agotó el tiempo."; - -/* The title of the command to send a button press */ -"Send Button Press" = "Enviar presion de botón"; - -/* Progress message for sending button press to pump. */ -"Sending button press…" = "Enviando presion de botón…"; - -/* The title of the cell showing BLE signal strength (RSSI) */ -"Signal Strength" = "Intensidad de señal"; - -/* A message indicating a command succeeded */ -"Succeeded" = "éxito"; - -/* The format string describing pump suspended state: (1: suspended) */ -"Suspended: %1$@\n" = "Suspendida: %1$@"; - -/* The label indicating the results of each frequency trial */ -"Trials" = "Pruebas"; - -/* The title of the command to re-tune the radio */ -"Tune Radio Frequency" = "Sintonizar frecuencia de radio"; - -/* Progress message for tuning radio */ -"Tuning radio…" = "Sintonizando frecuencia de radio…"; - -/* The detail text for an unknown pump model */ -"Unknown" = "Desconocido"; - -/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ -"Unknown pump error code: %1$@" = "Codigo desconocido de microinfusadora: %1$@"; - -/* No comment provided by engineer. */ -"Unknown pump model." = "Desconocido modelo de microinfusadora."; - -/* No comment provided by engineer. */ -"Unknown response from pump." = "Respuesta desconocida de microinfusora"; - -/* The title of the command to write a glucose history timestamp */ -"Write Glucose History Timestamp" = "Recordar la hora de glucosa historia"; - -/* Progress message for writing glucose history timestamp. */ -"Writing glucose history timestamp…" = "Recordando la hora de glucosa historia…"; - diff --git a/RileyLinkKit/nb.lproj/InfoPlist.strings b/RileyLinkKit/nb.lproj/InfoPlist.strings deleted file mode 100644 index bbcf8f904..000000000 --- a/RileyLinkKit/nb.lproj/InfoPlist.strings +++ /dev/null @@ -1,3 +0,0 @@ -/* Bundle name */ -"CFBundleName" = "$(PRODUCT_NAME)"; - diff --git a/RileyLinkKit/nb.lproj/Localizable.strings b/RileyLinkKit/nb.lproj/Localizable.strings deleted file mode 100644 index fd9cfbc60..000000000 --- a/RileyLinkKit/nb.lproj/Localizable.strings +++ /dev/null @@ -1,189 +0,0 @@ -/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ -"%1$@ MHz %2$@/%3$@ %4$@" = "%1$@ MHz %2$@/%3$@ %4$@"; - -/* Describes a certain bolus failure (1: size of the bolus in units) */ -"%1$@ U bolus failed" = "%1$@ U Bolo Falló"; - -/* Describes an uncertain bolus failure (1: size of the bolus in units) */ -"%1$@ U bolus may not have succeeded" = "%1$@ U bolo posiblemente fallado"; - -/* The format string describing units of insulin remaining: (1: number of units) */ -"%1$@ Units of insulin remaining\n" = "%1$@ Unidades de insulina restantes"; - -/* The format string describing number of basal schedule entries: (1: number of entries) */ -"%1$@ basal schedule entries\n" = "%1$@ entradas de prefil basal"; - -/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ -"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; - -/* Communications error for a bolus currently running */ -"A bolus is already in progress" = "Un bolo ya está en progreso"; - -/* The title of the cell describing an awake radio */ -"Awake Until" = "Despierto hasta"; - -/* The format string describing pump battery voltage: (1: battery voltage) */ -"Battery: %1$@ volts\n" = "Pila: %1$@ voltios"; - -/* The label indicating the best radio frequency */ -"Best Frequency" = "Mejor Frecuencia"; - -/* The format string describing pump bolusing state: (1: bolusing) */ -"Bolusing: %1$@\n" = "Bolo en progreso: %1$@"; - -/* The title of the command to change pump time */ -"Change Time" = "Cambio de Hora"; - -/* Progress message for changing pump time. */ -"Changing time…" = "Cambio de Hora..."; - -/* Recovery instruction for an uncertain bolus failure */ -"Check your pump before retrying." = "Revisar su microinfusadora antes de intentarlo de nuevo"; - -/* The title of the section describing commands */ -"Commands" = "Comandos"; - -/* No comment provided by engineer. */ -"Comms with another pump detected." = "Comunicación con otra microinfusadora detectado."; - -/* The connected state */ -"Connected" = "Conectado"; - -/* The in-progress connecting state */ -"Connecting" = "Conectando"; - -/* The title of the cell showing BLE connection state */ -"Connection State" = "Estado de Conexión"; - -/* The title of the section describing the device */ -"Device" = "Dispositivo"; - -/* The disconnected state */ -"Disconnected" = "Desconectado"; - -/* The in-progress disconnecting state */ -"Disconnecting" = "Desconectando"; - -/* The error displayed during MySentry pairing when the RX filter could not be set */ -"Error setting filter bandwidth: %@" = "Error al establecer el ancho de banda del filtro: %@"; - -/* The title of the command to fetch recent glucose */ -"Fetch Recent Glucose" = "Obtener Glucosa Reciente"; - -/* The title of the command to fetch recent history */ -"Fetch Recent History" = "Obtener Historia Reciente"; - -/* Progress message for fetching pump glucose. */ -"Fetching glucose…" = "Obteniendo glucosa…"; - -/* Progress message for fetching pump history. */ -"Fetching history…" = "Obteniendo historia…"; - -/* Progress message for fetching pump model. */ -"Fetching pump model…" = "Obteniendo modelo de microinfusadora…"; - -/* The title of the cell showing firmware version */ -"Firmware" = "Firmware"; - -/* The title of the command to get pump model */ -"Get Pump Model" = "Obtener Modelo de Microinfusadora"; - -/* Recovery instruction for a certain bolus failure */ -"It is safe to retry" = "Es seguro intentarlo de nuevo."; - -/* The title of the cell describing an awake radio */ -"Last Awake" = "último despierto"; - -/* The title of the cell describing no radio awake data */ -"Listening Off" = "Escuchando apagado"; - -/* The title of the command to pair with mysentry */ -"MySentry Pair" = "Junta de MySentry"; - -/* The title of the cell showing device name */ -"Name" = "Nombre"; - -/* Message display when no response from tuning pump */ -"No response" = "No respuesta"; - -/* The title of the cell showing the last idle */ -"On Idle" = "En Inactivo"; - -/* The title of the section describing the pump */ -"Pump" = "Microinfusadora"; - -/* The title of the cell showing pump ID */ -"Pump ID" = "ID de Microinfusadora"; - -/* The title of the cell showing the pump model number */ -"Pump Model" = "Modelo de Microinfusadora"; - -/* No comment provided by engineer. */ -"Pump did not respond." = "Microinfusadora no respondió."; - -/* The format string description of a Pump Error. (1: The specific error code) */ -"Pump error: %1$@" = "Error de Microinfusadora: %1$@"; - -/* No comment provided by engineer. */ -"Pump is suspended." = "Micorinfusadora está suspendida"; - -/* No comment provided by engineer. */ -"Pump responded unexpectedly." = "Micorinfusadora respondió inesperadamente."; - -/* The title of the command to read basal schedule */ -"Read Basal Schedule" = "Obtener prefil basal"; - -/* The title of the command to read pump status */ -"Read Pump Status" = "Obtener estada de microinfusadora"; - -/* Progress message for reading basal schedule */ -"Reading basal schedule…" = "Obteniendo perfil basal…"; - -/* Progress message for reading pump status */ -"Reading pump status…" = "Obteniendo estada de microinfusadora…"; - -/* No comment provided by engineer. */ -"RileyLink timed out." = "RileyLink agotó el tiempo."; - -/* The title of the command to send a button press */ -"Send Button Press" = "Enviar presion de botón"; - -/* Progress message for sending button press to pump. */ -"Sending button press…" = "Enviando presion de botón…"; - -/* The title of the cell showing BLE signal strength (RSSI) */ -"Signal Strength" = "Intensidad de señal"; - -/* A message indicating a command succeeded */ -"Succeeded" = "éxito"; - -/* The format string describing pump suspended state: (1: suspended) */ -"Suspended: %1$@\n" = "Suspendida: %1$@"; - -/* The label indicating the results of each frequency trial */ -"Trials" = "Pruebas"; - -/* The title of the command to re-tune the radio */ -"Tune Radio Frequency" = "Sintonizar frecuencia de radio"; - -/* Progress message for tuning radio */ -"Tuning radio…" = "Sintonizando frecuencia de radio…"; - -/* The detail text for an unknown pump model */ -"Unknown" = "Desconocido"; - -/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ -"Unknown pump error code: %1$@" = "Codigo desconocido de microinfusadora: %1$@"; - -/* No comment provided by engineer. */ -"Unknown pump model." = "Desconocido modelo de microinfusadora."; - -/* No comment provided by engineer. */ -"Unknown response from pump." = "Respuesta desconocida de microinfusora"; - -/* The title of the command to write a glucose history timestamp */ -"Write Glucose History Timestamp" = "Recordar la hora de glucosa historia"; - -/* Progress message for writing glucose history timestamp. */ -"Writing glucose history timestamp…" = "Recordando la hora de glucosa historia…"; - diff --git a/RileyLinkKit/nl.lproj/InfoPlist.strings b/RileyLinkKit/nl.lproj/InfoPlist.strings deleted file mode 100644 index bbcf8f904..000000000 --- a/RileyLinkKit/nl.lproj/InfoPlist.strings +++ /dev/null @@ -1,3 +0,0 @@ -/* Bundle name */ -"CFBundleName" = "$(PRODUCT_NAME)"; - diff --git a/RileyLinkKit/nl.lproj/Localizable.strings b/RileyLinkKit/nl.lproj/Localizable.strings deleted file mode 100644 index fd9cfbc60..000000000 --- a/RileyLinkKit/nl.lproj/Localizable.strings +++ /dev/null @@ -1,189 +0,0 @@ -/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ -"%1$@ MHz %2$@/%3$@ %4$@" = "%1$@ MHz %2$@/%3$@ %4$@"; - -/* Describes a certain bolus failure (1: size of the bolus in units) */ -"%1$@ U bolus failed" = "%1$@ U Bolo Falló"; - -/* Describes an uncertain bolus failure (1: size of the bolus in units) */ -"%1$@ U bolus may not have succeeded" = "%1$@ U bolo posiblemente fallado"; - -/* The format string describing units of insulin remaining: (1: number of units) */ -"%1$@ Units of insulin remaining\n" = "%1$@ Unidades de insulina restantes"; - -/* The format string describing number of basal schedule entries: (1: number of entries) */ -"%1$@ basal schedule entries\n" = "%1$@ entradas de prefil basal"; - -/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ -"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; - -/* Communications error for a bolus currently running */ -"A bolus is already in progress" = "Un bolo ya está en progreso"; - -/* The title of the cell describing an awake radio */ -"Awake Until" = "Despierto hasta"; - -/* The format string describing pump battery voltage: (1: battery voltage) */ -"Battery: %1$@ volts\n" = "Pila: %1$@ voltios"; - -/* The label indicating the best radio frequency */ -"Best Frequency" = "Mejor Frecuencia"; - -/* The format string describing pump bolusing state: (1: bolusing) */ -"Bolusing: %1$@\n" = "Bolo en progreso: %1$@"; - -/* The title of the command to change pump time */ -"Change Time" = "Cambio de Hora"; - -/* Progress message for changing pump time. */ -"Changing time…" = "Cambio de Hora..."; - -/* Recovery instruction for an uncertain bolus failure */ -"Check your pump before retrying." = "Revisar su microinfusadora antes de intentarlo de nuevo"; - -/* The title of the section describing commands */ -"Commands" = "Comandos"; - -/* No comment provided by engineer. */ -"Comms with another pump detected." = "Comunicación con otra microinfusadora detectado."; - -/* The connected state */ -"Connected" = "Conectado"; - -/* The in-progress connecting state */ -"Connecting" = "Conectando"; - -/* The title of the cell showing BLE connection state */ -"Connection State" = "Estado de Conexión"; - -/* The title of the section describing the device */ -"Device" = "Dispositivo"; - -/* The disconnected state */ -"Disconnected" = "Desconectado"; - -/* The in-progress disconnecting state */ -"Disconnecting" = "Desconectando"; - -/* The error displayed during MySentry pairing when the RX filter could not be set */ -"Error setting filter bandwidth: %@" = "Error al establecer el ancho de banda del filtro: %@"; - -/* The title of the command to fetch recent glucose */ -"Fetch Recent Glucose" = "Obtener Glucosa Reciente"; - -/* The title of the command to fetch recent history */ -"Fetch Recent History" = "Obtener Historia Reciente"; - -/* Progress message for fetching pump glucose. */ -"Fetching glucose…" = "Obteniendo glucosa…"; - -/* Progress message for fetching pump history. */ -"Fetching history…" = "Obteniendo historia…"; - -/* Progress message for fetching pump model. */ -"Fetching pump model…" = "Obteniendo modelo de microinfusadora…"; - -/* The title of the cell showing firmware version */ -"Firmware" = "Firmware"; - -/* The title of the command to get pump model */ -"Get Pump Model" = "Obtener Modelo de Microinfusadora"; - -/* Recovery instruction for a certain bolus failure */ -"It is safe to retry" = "Es seguro intentarlo de nuevo."; - -/* The title of the cell describing an awake radio */ -"Last Awake" = "último despierto"; - -/* The title of the cell describing no radio awake data */ -"Listening Off" = "Escuchando apagado"; - -/* The title of the command to pair with mysentry */ -"MySentry Pair" = "Junta de MySentry"; - -/* The title of the cell showing device name */ -"Name" = "Nombre"; - -/* Message display when no response from tuning pump */ -"No response" = "No respuesta"; - -/* The title of the cell showing the last idle */ -"On Idle" = "En Inactivo"; - -/* The title of the section describing the pump */ -"Pump" = "Microinfusadora"; - -/* The title of the cell showing pump ID */ -"Pump ID" = "ID de Microinfusadora"; - -/* The title of the cell showing the pump model number */ -"Pump Model" = "Modelo de Microinfusadora"; - -/* No comment provided by engineer. */ -"Pump did not respond." = "Microinfusadora no respondió."; - -/* The format string description of a Pump Error. (1: The specific error code) */ -"Pump error: %1$@" = "Error de Microinfusadora: %1$@"; - -/* No comment provided by engineer. */ -"Pump is suspended." = "Micorinfusadora está suspendida"; - -/* No comment provided by engineer. */ -"Pump responded unexpectedly." = "Micorinfusadora respondió inesperadamente."; - -/* The title of the command to read basal schedule */ -"Read Basal Schedule" = "Obtener prefil basal"; - -/* The title of the command to read pump status */ -"Read Pump Status" = "Obtener estada de microinfusadora"; - -/* Progress message for reading basal schedule */ -"Reading basal schedule…" = "Obteniendo perfil basal…"; - -/* Progress message for reading pump status */ -"Reading pump status…" = "Obteniendo estada de microinfusadora…"; - -/* No comment provided by engineer. */ -"RileyLink timed out." = "RileyLink agotó el tiempo."; - -/* The title of the command to send a button press */ -"Send Button Press" = "Enviar presion de botón"; - -/* Progress message for sending button press to pump. */ -"Sending button press…" = "Enviando presion de botón…"; - -/* The title of the cell showing BLE signal strength (RSSI) */ -"Signal Strength" = "Intensidad de señal"; - -/* A message indicating a command succeeded */ -"Succeeded" = "éxito"; - -/* The format string describing pump suspended state: (1: suspended) */ -"Suspended: %1$@\n" = "Suspendida: %1$@"; - -/* The label indicating the results of each frequency trial */ -"Trials" = "Pruebas"; - -/* The title of the command to re-tune the radio */ -"Tune Radio Frequency" = "Sintonizar frecuencia de radio"; - -/* Progress message for tuning radio */ -"Tuning radio…" = "Sintonizando frecuencia de radio…"; - -/* The detail text for an unknown pump model */ -"Unknown" = "Desconocido"; - -/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ -"Unknown pump error code: %1$@" = "Codigo desconocido de microinfusadora: %1$@"; - -/* No comment provided by engineer. */ -"Unknown pump model." = "Desconocido modelo de microinfusadora."; - -/* No comment provided by engineer. */ -"Unknown response from pump." = "Respuesta desconocida de microinfusora"; - -/* The title of the command to write a glucose history timestamp */ -"Write Glucose History Timestamp" = "Recordar la hora de glucosa historia"; - -/* Progress message for writing glucose history timestamp. */ -"Writing glucose history timestamp…" = "Recordando la hora de glucosa historia…"; - diff --git a/RileyLinkKit/ru.lproj/InfoPlist.strings b/RileyLinkKit/ru.lproj/InfoPlist.strings deleted file mode 100644 index bbcf8f904..000000000 --- a/RileyLinkKit/ru.lproj/InfoPlist.strings +++ /dev/null @@ -1,3 +0,0 @@ -/* Bundle name */ -"CFBundleName" = "$(PRODUCT_NAME)"; - diff --git a/RileyLinkKit/ru.lproj/Localizable.strings b/RileyLinkKit/ru.lproj/Localizable.strings deleted file mode 100644 index 2657d99e2..000000000 --- a/RileyLinkKit/ru.lproj/Localizable.strings +++ /dev/null @@ -1,189 +0,0 @@ -/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ -"%1$@ MHz %2$@/%3$@ %4$@" = "%1$@ MHz %2$@/%3$@ %4$@"; - -/* Describes a certain bolus failure (1: size of the bolus in units) */ -"%1$@ U bolus failed" = "Болюс %1$@ не состоялся"; - -/* Describes an uncertain bolus failure (1: size of the bolus in units) */ -"%1$@ U bolus may not have succeeded" = "Болюс %1$@ мог не состояться"; - -/* The format string describing units of insulin remaining: (1: number of units) */ -"%1$@ Units of insulin remaining\n" = "Остается %1$@ ед инсулина"; - -/* The format string describing number of basal schedule entries: (1: number of entries) */ -"%1$@ basal schedule entries\n" = "%1$@ записи графика базала"; - -/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ -"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; - -/* Communications error for a bolus currently running */ -"A bolus is already in progress" = "Болюс уже подается"; - -/* The title of the cell describing an awake radio */ -"Awake Until" = "Рабочее состояние до"; - -/* The format string describing pump battery voltage: (1: battery voltage) */ -"Battery: %1$@ volts\n" = "Батарея: %1$@ вольт"; - -/* The label indicating the best radio frequency */ -"Best Frequency" = "Лучшая частота"; - -/* The format string describing pump bolusing state: (1: bolusing) */ -"Bolusing: %1$@\n" = "Болюс: %1$@"; - -/* The title of the command to change pump time */ -"Change Time" = "Изменить время"; - -/* Progress message for changing pump time. */ -"Changing time…" = "Изменяется время…"; - -/* Recovery instruction for an uncertain bolus failure */ -"Check your pump before retrying." = "Проверьте помпу прежде чем повторить попытку."; - -/* The title of the section describing commands */ -"Commands" = "Команды"; - -/* No comment provided by engineer. */ -"Comms with another pump detected." = "Обнаружена коммуникация с другой помпой"; - -/* The connected state */ -"Connected" = "Соединение установлено"; - -/* The in-progress connecting state */ -"Connecting" = "Соединяется"; - -/* The title of the cell showing BLE connection state */ -"Connection State" = "Состояние соединения"; - -/* The title of the section describing the device */ -"Device" = "устройство"; - -/* The disconnected state */ -"Disconnected" = "Разъединено"; - -/* The in-progress disconnecting state */ -"Disconnecting" = "Разъединяется"; - -/* The error displayed during MySentry pairing when the RX filter could not be set */ -"Error setting filter bandwidth: %@" = "Ошибка при установке частоты фильтра: %@"; - -/* The title of the command to fetch recent glucose */ -"Fetch Recent Glucose" = "Получить недавние значения гликемии"; - -/* The title of the command to fetch recent history */ -"Fetch Recent History" = "Получить логи недавней истории"; - -/* Progress message for fetching pump glucose. */ -"Fetching glucose…" = "Получаю гликемию…"; - -/* Progress message for fetching pump history. */ -"Fetching history…" = "Получаю логи…"; - -/* Progress message for fetching pump model. */ -"Fetching pump model…" = "Получаю модель помпы…"; - -/* The title of the cell showing firmware version */ -"Firmware" = "Прошивка"; - -/* The title of the command to get pump model */ -"Get Pump Model" = "Получить модель помпы"; - -/* Recovery instruction for a certain bolus failure */ -"It is safe to retry" = "Можно повторить без опасений"; - -/* The title of the cell describing an awake radio */ -"Last Awake" = "Недавнее состояние активности"; - -/* The title of the cell describing no radio awake data */ -"Listening Off" = "Получаю данные от"; - -/* The title of the command to pair with mysentry */ -"MySentry Pair" = "Сопряжение с MySentry"; - -/* The title of the cell showing device name */ -"Name" = "Название"; - -/* Message display when no response from tuning pump */ -"No response" = "Нет ответа"; - -/* The title of the cell showing the last idle */ -"On Idle" = "Бездействие"; - -/* The title of the section describing the pump */ -"Pump" = "помпы"; - -/* The title of the cell showing pump ID */ -"Pump ID" = "Инд № помпы"; - -/* The title of the cell showing the pump model number */ -"Pump Model" = "Модель помпы"; - -/* No comment provided by engineer. */ -"Pump did not respond." = "Нет ответа от помпы"; - -/* The format string description of a Pump Error. (1: The specific error code) */ -"Pump error: %1$@" = "Ошибка помпы: %1$@"; - -/* No comment provided by engineer. */ -"Pump is suspended." = "Помпа приостановлена."; - -/* No comment provided by engineer. */ -"Pump responded unexpectedly." = "Неожиданный ответ помпы."; - -/* The title of the command to read basal schedule */ -"Read Basal Schedule" = "Прочитать график базала"; - -/* The title of the command to read pump status */ -"Read Pump Status" = "Прочитать статус помпы"; - -/* Progress message for reading basal schedule */ -"Reading basal schedule…" = "Чтение графика базала…"; - -/* Progress message for reading pump status */ -"Reading pump status…" = "Чтение статуса помпы…"; - -/* No comment provided by engineer. */ -"RileyLink timed out." = "Тайм-аут RileyLink"; - -/* The title of the command to send a button press */ -"Send Button Press" = "Отправить команду нажать кнопку"; - -/* Progress message for sending button press to pump. */ -"Sending button press…" = "Отправляется команда нажать кнопку…"; - -/* The title of the cell showing BLE signal strength (RSSI) */ -"Signal Strength" = "Уровень сигнала"; - -/* A message indicating a command succeeded */ -"Succeeded" = "Успешно"; - -/* The format string describing pump suspended state: (1: suspended) */ -"Suspended: %1$@\n" = "Приостановлено: %1$@"; - -/* The label indicating the results of each frequency trial */ -"Trials" = "Попытки"; - -/* The title of the command to re-tune the radio */ -"Tune Radio Frequency" = "Настроить радиочастоту"; - -/* Progress message for tuning radio */ -"Tuning radio…" = "Настраивается радиочастота…"; - -/* The detail text for an unknown pump model */ -"Unknown" = "Неизвестно"; - -/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ -"Unknown pump error code: %1$@" = "Неизвестный код ошибки помпы: %1$@"; - -/* No comment provided by engineer. */ -"Unknown pump model." = "Неизвестная модель помпы"; - -/* No comment provided by engineer. */ -"Unknown response from pump." = "Неизвестный ответ помпы"; - -/* The title of the command to write a glucose history timestamp */ -"Write Glucose History Timestamp" = "Проставить временной штамп истории гликемии"; - -/* Progress message for writing glucose history timestamp. */ -"Writing glucose history timestamp…" = "Наносится временной штамп истории гликемии"; - diff --git a/RileyLinkKit/zh-Hans.lproj/InfoPlist.strings b/RileyLinkKit/zh-Hans.lproj/InfoPlist.strings deleted file mode 100644 index bbcf8f904..000000000 --- a/RileyLinkKit/zh-Hans.lproj/InfoPlist.strings +++ /dev/null @@ -1,3 +0,0 @@ -/* Bundle name */ -"CFBundleName" = "$(PRODUCT_NAME)"; - diff --git a/RileyLinkKit/zh-Hans.lproj/Localizable.strings b/RileyLinkKit/zh-Hans.lproj/Localizable.strings deleted file mode 100644 index fd9cfbc60..000000000 --- a/RileyLinkKit/zh-Hans.lproj/Localizable.strings +++ /dev/null @@ -1,189 +0,0 @@ -/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ -"%1$@ MHz %2$@/%3$@ %4$@" = "%1$@ MHz %2$@/%3$@ %4$@"; - -/* Describes a certain bolus failure (1: size of the bolus in units) */ -"%1$@ U bolus failed" = "%1$@ U Bolo Falló"; - -/* Describes an uncertain bolus failure (1: size of the bolus in units) */ -"%1$@ U bolus may not have succeeded" = "%1$@ U bolo posiblemente fallado"; - -/* The format string describing units of insulin remaining: (1: number of units) */ -"%1$@ Units of insulin remaining\n" = "%1$@ Unidades de insulina restantes"; - -/* The format string describing number of basal schedule entries: (1: number of entries) */ -"%1$@ basal schedule entries\n" = "%1$@ entradas de prefil basal"; - -/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ -"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; - -/* Communications error for a bolus currently running */ -"A bolus is already in progress" = "Un bolo ya está en progreso"; - -/* The title of the cell describing an awake radio */ -"Awake Until" = "Despierto hasta"; - -/* The format string describing pump battery voltage: (1: battery voltage) */ -"Battery: %1$@ volts\n" = "Pila: %1$@ voltios"; - -/* The label indicating the best radio frequency */ -"Best Frequency" = "Mejor Frecuencia"; - -/* The format string describing pump bolusing state: (1: bolusing) */ -"Bolusing: %1$@\n" = "Bolo en progreso: %1$@"; - -/* The title of the command to change pump time */ -"Change Time" = "Cambio de Hora"; - -/* Progress message for changing pump time. */ -"Changing time…" = "Cambio de Hora..."; - -/* Recovery instruction for an uncertain bolus failure */ -"Check your pump before retrying." = "Revisar su microinfusadora antes de intentarlo de nuevo"; - -/* The title of the section describing commands */ -"Commands" = "Comandos"; - -/* No comment provided by engineer. */ -"Comms with another pump detected." = "Comunicación con otra microinfusadora detectado."; - -/* The connected state */ -"Connected" = "Conectado"; - -/* The in-progress connecting state */ -"Connecting" = "Conectando"; - -/* The title of the cell showing BLE connection state */ -"Connection State" = "Estado de Conexión"; - -/* The title of the section describing the device */ -"Device" = "Dispositivo"; - -/* The disconnected state */ -"Disconnected" = "Desconectado"; - -/* The in-progress disconnecting state */ -"Disconnecting" = "Desconectando"; - -/* The error displayed during MySentry pairing when the RX filter could not be set */ -"Error setting filter bandwidth: %@" = "Error al establecer el ancho de banda del filtro: %@"; - -/* The title of the command to fetch recent glucose */ -"Fetch Recent Glucose" = "Obtener Glucosa Reciente"; - -/* The title of the command to fetch recent history */ -"Fetch Recent History" = "Obtener Historia Reciente"; - -/* Progress message for fetching pump glucose. */ -"Fetching glucose…" = "Obteniendo glucosa…"; - -/* Progress message for fetching pump history. */ -"Fetching history…" = "Obteniendo historia…"; - -/* Progress message for fetching pump model. */ -"Fetching pump model…" = "Obteniendo modelo de microinfusadora…"; - -/* The title of the cell showing firmware version */ -"Firmware" = "Firmware"; - -/* The title of the command to get pump model */ -"Get Pump Model" = "Obtener Modelo de Microinfusadora"; - -/* Recovery instruction for a certain bolus failure */ -"It is safe to retry" = "Es seguro intentarlo de nuevo."; - -/* The title of the cell describing an awake radio */ -"Last Awake" = "último despierto"; - -/* The title of the cell describing no radio awake data */ -"Listening Off" = "Escuchando apagado"; - -/* The title of the command to pair with mysentry */ -"MySentry Pair" = "Junta de MySentry"; - -/* The title of the cell showing device name */ -"Name" = "Nombre"; - -/* Message display when no response from tuning pump */ -"No response" = "No respuesta"; - -/* The title of the cell showing the last idle */ -"On Idle" = "En Inactivo"; - -/* The title of the section describing the pump */ -"Pump" = "Microinfusadora"; - -/* The title of the cell showing pump ID */ -"Pump ID" = "ID de Microinfusadora"; - -/* The title of the cell showing the pump model number */ -"Pump Model" = "Modelo de Microinfusadora"; - -/* No comment provided by engineer. */ -"Pump did not respond." = "Microinfusadora no respondió."; - -/* The format string description of a Pump Error. (1: The specific error code) */ -"Pump error: %1$@" = "Error de Microinfusadora: %1$@"; - -/* No comment provided by engineer. */ -"Pump is suspended." = "Micorinfusadora está suspendida"; - -/* No comment provided by engineer. */ -"Pump responded unexpectedly." = "Micorinfusadora respondió inesperadamente."; - -/* The title of the command to read basal schedule */ -"Read Basal Schedule" = "Obtener prefil basal"; - -/* The title of the command to read pump status */ -"Read Pump Status" = "Obtener estada de microinfusadora"; - -/* Progress message for reading basal schedule */ -"Reading basal schedule…" = "Obteniendo perfil basal…"; - -/* Progress message for reading pump status */ -"Reading pump status…" = "Obteniendo estada de microinfusadora…"; - -/* No comment provided by engineer. */ -"RileyLink timed out." = "RileyLink agotó el tiempo."; - -/* The title of the command to send a button press */ -"Send Button Press" = "Enviar presion de botón"; - -/* Progress message for sending button press to pump. */ -"Sending button press…" = "Enviando presion de botón…"; - -/* The title of the cell showing BLE signal strength (RSSI) */ -"Signal Strength" = "Intensidad de señal"; - -/* A message indicating a command succeeded */ -"Succeeded" = "éxito"; - -/* The format string describing pump suspended state: (1: suspended) */ -"Suspended: %1$@\n" = "Suspendida: %1$@"; - -/* The label indicating the results of each frequency trial */ -"Trials" = "Pruebas"; - -/* The title of the command to re-tune the radio */ -"Tune Radio Frequency" = "Sintonizar frecuencia de radio"; - -/* Progress message for tuning radio */ -"Tuning radio…" = "Sintonizando frecuencia de radio…"; - -/* The detail text for an unknown pump model */ -"Unknown" = "Desconocido"; - -/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ -"Unknown pump error code: %1$@" = "Codigo desconocido de microinfusadora: %1$@"; - -/* No comment provided by engineer. */ -"Unknown pump model." = "Desconocido modelo de microinfusadora."; - -/* No comment provided by engineer. */ -"Unknown response from pump." = "Respuesta desconocida de microinfusora"; - -/* The title of the command to write a glucose history timestamp */ -"Write Glucose History Timestamp" = "Recordar la hora de glucosa historia"; - -/* Progress message for writing glucose history timestamp. */ -"Writing glucose history timestamp…" = "Recordando la hora de glucosa historia…"; - diff --git a/RileyLinkKitUI/nb.lproj/Localizable.strings b/RileyLinkKitUI/nb.lproj/Localizable.strings index 1dcee1a80..ae10cc924 100644 --- a/RileyLinkKitUI/nb.lproj/Localizable.strings +++ b/RileyLinkKitUI/nb.lproj/Localizable.strings @@ -11,7 +11,7 @@ "Connected" = "Tilkoblet"; /* The in-progress connecting state */ -"Connecting" = "Kobler Til"; +"Connecting" = "Kobler til"; /* The title of the cell showing BLE connection state */ "Connection State" = "Tilkoblingsstatus"; @@ -26,13 +26,13 @@ "Disconnected" = "Frakoblet"; /* The in-progress disconnecting state */ -"Disconnecting" = "Kobler Fra"; +"Disconnecting" = "Kobler fra"; /* The title of the cell showing firmware version */ "Firmware" = "Firmware"; /* The title of the cell describing an awake radio */ -"Last Awake" = "Sist Våken"; +"Last Awake" = "Sist våken"; /* The title of the cell describing no radio awake data */ "Listening Off" = "Lytting skrudd av skrudd av"; From 1613b4102c727bb6e233dee5ad6e4c080f4c5755 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sat, 18 Aug 2018 23:16:58 -0500 Subject: [PATCH 17/22] Decode meterbg events for x15 and x12 pumps (#438) --- MinimedKit/Messages/Models/PumpEventType.swift | 6 +++--- MinimedKitTests/HistoryPageTests.swift | 10 ++++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/MinimedKit/Messages/Models/PumpEventType.swift b/MinimedKit/Messages/Models/PumpEventType.swift index dda063ea8..8e1530107 100644 --- a/MinimedKit/Messages/Models/PumpEventType.swift +++ b/MinimedKit/Messages/Models/PumpEventType.swift @@ -40,7 +40,7 @@ public enum PumpEventType: UInt8 { case journalEntryPumpLowReservoir = 0x34 case alarmClockReminder = 0x35 case changeMeterId = 0x36 - case unknown515Event = 0x39 + case meterBGx15 = 0x39 case questionable3b = 0x3b case changeParadigmLinkID = 0x3c case bgReceived = 0x3f @@ -218,8 +218,8 @@ public enum PumpEventType: UInt8 { return ChangeMeterIDPumpEvent.self case .bolusReminder: return BolusReminderPumpEvent.self - case .unknown515Event: - return UnknownPumpEvent57.self + case .meterBGx15: + return BGReceivedPumpEvent.self default: return PlaceholderPumpEvent.self } diff --git a/MinimedKitTests/HistoryPageTests.swift b/MinimedKitTests/HistoryPageTests.swift index 6cc865eaa..a6202452f 100644 --- a/MinimedKitTests/HistoryPageTests.swift +++ b/MinimedKitTests/HistoryPageTests.swift @@ -402,7 +402,7 @@ class HistoryPageTests: XCTestCase { XCTAssert(events[23].rawData[0] == PumpEventType.changeSensorAutoCalEnable.rawValue) } - func testUnknownEventType57() throws { + func testMeterBGx15() throws { let pumpModel = PumpModel.model515 let page = try HistoryPage(pageData: Data(hexadecimalString: "1601971f174a12333b9621174a120016019621174a1233429925174a120016019925174a1233479f2a174a120016019f2a174a123343a12f174a12001601a12f174a1233419c35174a120016019c35174a123337ab39174a12001601ab39174a1207000004fc8a126c8a12090c00e80000000004fc031e3f01de25000001de2500000000000001de6408000000083334b802004b12001601b802004b123330b507004b12001601b507004b123337b90c004b12001601b90c004b1233348312004b120016018312004b1233308717004b120016018717004b12332f8b1c004b120016018b1c004b121700b32f004b121800b32f004b121e00b635000b121f008036000b1233008c36000b120016008c36000b122600a706010b12270f1206000000280000000000002601aa06010b12270f1206000000280000000000002601af06010b1227000000000000280000000000002601b806010b12270f423f000000280000000000001a01a40b010b121700b921014b121800ba21014b12010101009923414b121700a217024b121800a117024b12010101008219424b1217009a1e034b1218009a1e034b12010303008520434b12333c9425034b120016019425034b12333c9725034b120016019725034b12333c9925034b120016019925034b12333c9d25034b120016019d25034b12333ca025034b12001601a025034b1201010100841b474b123300af1b074b12001601af1b074b123300b42f074b12001601b42f074b12390bb134876b128436633300a401084b12001600a401084b1236008613080b12370be5940cdf8f3800000000000017008723084b1218008823084b121700b531094b121800b531094b1217008f38094b1218008f38094b123601ad38090b12370be5940cdf8f380000000000002000bb3a090b12011e1e00ac114a0b12010f0f0097234a4b121700a0250b4b121800a0250b4b120114130091244b0b120114140091244b0b1262008f2f0b0b126401a62f0b0b12260196300b0b12270f423f0000002800000000000026019b300b0b1227000000000000280000000000001700b9330b4b121800ba330b4b12010a0a0090194c0b12012828008d184d0b121700a5220d4b121800a5220d4b126401b82b0d0b126400822c0d0b1217008c2c0d0b121800802d0d0c12070000039a8b126c8b1209005c5c5c010000039a01b63001e434000001e43400000000000001e46409000000096201a32f0d0c126200a62f0d0c12170084310d4c12180091300d4b1207000000048c126c8c12090c00e80000000000040004640000000000000000000000000000000000000000000064018e060e0b1236009a060e0b12370be5940cdf8f380000000000002601b3060e0b12270f1206000000280000000000001a0093150e0b120000007689")!, pumpModel: pumpModel) @@ -411,8 +411,14 @@ class HistoryPageTests: XCTestCase { XCTAssertEqual(106, events.count) - XCTAssert(events[62] is UnknownPumpEvent57) + XCTAssert(events[62] is BGReceivedPumpEvent) + let bgMeter = events[62] as! BGReceivedPumpEvent + + XCTAssertEqual(bgMeter.amount, 92) + XCTAssertEqual(bgMeter.meter, "843663") + XCTAssertEqual(bgMeter.timestamp, DateComponents(gregorianYear: 2018, month: 8, day: 11, hour: 7, minute: 52, second: 49)) + } func testHistoryTimeShift() throws { From 613e1109d25355ead5c03094dd6ef6b51e56258d Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 19 Aug 2018 01:43:08 -0500 Subject: [PATCH 18/22] Update to LoopKit 2.1.1 (#439) --- Cartfile | 2 +- Cartfile.resolved | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cartfile b/Cartfile index 49519e1cf..48e92d0b4 100644 --- a/Cartfile +++ b/Cartfile @@ -1 +1 @@ -github "LoopKit/LoopKit" == 2.1 +github "LoopKit/LoopKit" == 2.1.1 diff --git a/Cartfile.resolved b/Cartfile.resolved index e71e34770..25532f0c1 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1 +1 @@ -github "LoopKit/LoopKit" "v2.1" +github "LoopKit/LoopKit" "v2.1.1" From 6604e03f0948cd22022da536b05f1d30ec7bce76 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Sun, 19 Aug 2018 08:31:31 -0500 Subject: [PATCH 19/22] re-add Localizable.strings (#440) --- RileyLink.xcodeproj/project.pbxproj | 60 ++++++++++++++--------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index a5616413c..770213c4b 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -274,14 +274,11 @@ 7D23674D21252A5E0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674B21252A5E0028B67D /* InfoPlist.strings */; }; 7D23675021252A5E0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674E21252A5E0028B67D /* InfoPlist.strings */; }; 7D23675321252A5E0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23675121252A5E0028B67D /* InfoPlist.strings */; }; - 7D23675621252A5E0028B67D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23675421252A5E0028B67D /* Localizable.strings */; }; 7D23676121252A9D0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674821252A5E0028B67D /* InfoPlist.strings */; }; 7D23676321252A9D0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674221252A5E0028B67D /* InfoPlist.strings */; }; - 7D23676521252A9D0028B67D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23675421252A5E0028B67D /* Localizable.strings */; }; 7D23676721252A9D0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674521252A5E0028B67D /* InfoPlist.strings */; }; 7D23676921252A9D0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674B21252A5E0028B67D /* InfoPlist.strings */; }; 7D23676B21252A9D0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23675121252A5E0028B67D /* InfoPlist.strings */; }; - 7D23676D21252A9D0028B67D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23675421252A5E0028B67D /* Localizable.strings */; }; 7D23679421252EBC0028B67D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23679221252EBC0028B67D /* Localizable.strings */; }; 7D23679721252EBC0028B67D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23679521252EBC0028B67D /* Localizable.strings */; }; 7D70766D1FE092D4004AC8EA /* LoopKit.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D70766F1FE092D4004AC8EA /* LoopKit.strings */; }; @@ -479,6 +476,7 @@ C1F6EB8B1F89C41200CFE393 /* MinimedPacket.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1F6EB8A1F89C41200CFE393 /* MinimedPacket.swift */; }; C1F6EB8D1F89C45500CFE393 /* MinimedPacketTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1F6EB8C1F89C45500CFE393 /* MinimedPacketTests.swift */; }; C1FDFCA91D964A3E00ADBC31 /* BolusReminderPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1FDFCA81D964A3E00ADBC31 /* BolusReminderPumpEvent.swift */; }; + C1FFAF4D212944F600C50C1D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C1FFAF4B212944F600C50C1D /* Localizable.strings */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -924,7 +922,6 @@ 7D23674C21252A5E0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23674F21252A5E0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23675221252A5E0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D23675521252A5E0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; 7D23675721252A5E0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/MinimedPumpManager.strings; sourceTree = ""; }; 7D23675821252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23675921252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -932,7 +929,6 @@ 7D23675B21252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23675C21252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23675D21252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D23675E21252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; 7D23675F21252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/MinimedPumpManager.strings; sourceTree = ""; }; 7D23676021252A9D0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23676221252A9D0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -940,43 +936,36 @@ 7D23676621252A9D0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23676821252A9D0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23676A21252A9D0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D23676C21252A9D0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; 7D23676E21252AA80028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23676F21252AA80028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677021252AA80028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677121252AA80028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677221252AA80028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677321252AA80028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D23677421252AA80028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; 7D23677521252AB70028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677621252AB70028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677721252AB70028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677821252AB70028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677921252AB70028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677A21252AB70028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D23677B21252AB70028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; 7D23677C21252AC40028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677D21252AC40028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677E21252AC40028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677F21252AC40028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23678021252AC40028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23678121252AC40028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D23678221252AC40028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Localizable.strings; sourceTree = ""; }; 7D23678321252AD30028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23678421252AD30028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23678521252AD30028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23678621252AD30028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23678721252AD30028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23678821252AD30028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D23678921252AD40028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; 7D23678A21252AE10028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; 7D23678B21252AE10028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; 7D23678C21252AE10028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; 7D23678D21252AE10028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; 7D23678E21252AE10028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; 7D23678F21252AE10028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; - 7D23679021252AE10028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; - 7D23679121252BCC0028B67D /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = ""; }; 7D23679321252EBC0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; 7D23679621252EBC0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; 7D23679821252F050028B67D /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = ""; }; @@ -1219,6 +1208,15 @@ C1F6EB8A1F89C41200CFE393 /* MinimedPacket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MinimedPacket.swift; sourceTree = ""; }; C1F6EB8C1F89C45500CFE393 /* MinimedPacketTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MinimedPacketTests.swift; sourceTree = ""; }; C1FDFCA81D964A3E00ADBC31 /* BolusReminderPumpEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BolusReminderPumpEvent.swift; sourceTree = ""; }; + C1FFAF4C212944F600C50C1D /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = ""; }; + C1FFAF4F212944FF00C50C1D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; + C1FFAF502129450200C50C1D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; + C1FFAF512129450500C50C1D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; + C1FFAF522129450800C50C1D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; + C1FFAF532129450A00C50C1D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; + C1FFAF542129450D00C50C1D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; + C1FFAF552129450F00C50C1D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; + C1FFAF562129451300C50C1D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Localizable.strings; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1443,9 +1441,9 @@ 4352A72620DEC9B700CAC200 /* MinimedKitUI */ = { isa = PBXGroup; children = ( + C1FFAF4B212944F600C50C1D /* Localizable.strings */, 4352A72720DEC9B700CAC200 /* MinimedKitUI.h */, 4352A72820DEC9B700CAC200 /* Info.plist */, - 7D23675421252A5E0028B67D /* Localizable.strings */, 7D23674E21252A5E0028B67D /* InfoPlist.strings */, 43709AC820DF1C9A00F941B3 /* MinimedKitUI.xcassets */, 43709AE020DF1D5400F941B3 /* MinimedPumpManager.storyboard */, @@ -2532,10 +2530,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 7D23676521252A9D0028B67D /* Localizable.strings in Resources */, - 7D23676D21252A9D0028B67D /* Localizable.strings in Resources */, 43709ADE20DF1D5400F941B3 /* MinimedPumpManager.storyboard in Resources */, - 7D23675621252A5E0028B67D /* Localizable.strings in Resources */, + C1FFAF4D212944F600C50C1D /* Localizable.strings in Resources */, 7D23675021252A5E0028B67D /* InfoPlist.strings in Resources */, 43709AC920DF1C9A00F941B3 /* MinimedKitUI.xcassets in Resources */, ); @@ -3355,22 +3351,6 @@ name = InfoPlist.strings; sourceTree = ""; }; - 7D23675421252A5E0028B67D /* Localizable.strings */ = { - isa = PBXVariantGroup; - children = ( - 7D23675521252A5E0028B67D /* es */, - 7D23675E21252A720028B67D /* ru */, - 7D23676C21252A9D0028B67D /* de */, - 7D23677421252AA80028B67D /* fr */, - 7D23677B21252AB70028B67D /* it */, - 7D23678221252AC40028B67D /* nb */, - 7D23678921252AD40028B67D /* nl */, - 7D23679021252AE10028B67D /* zh-Hans */, - 7D23679121252BCC0028B67D /* Base */, - ); - name = Localizable.strings; - sourceTree = ""; - }; 7D23679221252EBC0028B67D /* Localizable.strings */ = { isa = PBXVariantGroup; children = ( @@ -3542,6 +3522,22 @@ name = InfoPlist.strings; sourceTree = ""; }; + C1FFAF4B212944F600C50C1D /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + C1FFAF4C212944F600C50C1D /* Base */, + C1FFAF4F212944FF00C50C1D /* es */, + C1FFAF502129450200C50C1D /* ru */, + C1FFAF512129450500C50C1D /* fr */, + C1FFAF522129450800C50C1D /* de */, + C1FFAF532129450A00C50C1D /* zh-Hans */, + C1FFAF542129450D00C50C1D /* it */, + C1FFAF552129450F00C50C1D /* nl */, + C1FFAF562129451300C50C1D /* nb */, + ); + name = Localizable.strings; + sourceTree = ""; + }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ From 541972b11e00e2654a755a97b58052875383335a Mon Sep 17 00:00:00 2001 From: katie disimone Date: Mon, 20 Aug 2018 08:03:41 -0700 Subject: [PATCH 20/22] Polish translations (#441) --- Crypto/pl.lproj/InfoPlist.strings | 3 + MinimedKit/pl.lproj/InfoPlist.strings | 3 + MinimedKit/pl.lproj/Localizable.strings | 99 +++++++++ MinimedKitTests/pl.lproj/InfoPlist.strings | 3 + MinimedKitUI/pl.lproj/InfoPlist.strings | 3 + MinimedKitUI/pl.lproj/Localizable.strings | 195 ++++++++++++++++++ .../pl.lproj/MinimedPumpManager.strings | 73 +++++++ .../pl.lproj/InfoPlist.strings | 3 + .../pl.lproj/InfoPlist.strings | 3 + RileyLink.xcodeproj/project.pbxproj | 39 ++++ RileyLink/pl.lproj/InfoPlist.strings | 2 + RileyLink/pl.lproj/Localizable.strings | 53 +++++ RileyLink/pl.lproj/LoopKit.strings | 3 + RileyLinkBLEKit/pl.lproj/InfoPlist.strings | 3 + RileyLinkBLEKit/pl.lproj/Localizable.strings | 30 +++ .../pl.lproj/InfoPlist.strings | 3 + RileyLinkKitTests/pl.lproj/InfoPlist.strings | 3 + RileyLinkKitUI/pl.lproj/InfoPlist.strings | 3 + RileyLinkKitUI/pl.lproj/Localizable.strings | 52 +++++ RileyLinkTests/pl.lproj/InfoPlist.strings | 2 + 20 files changed, 578 insertions(+) create mode 100644 Crypto/pl.lproj/InfoPlist.strings create mode 100644 MinimedKit/pl.lproj/InfoPlist.strings create mode 100644 MinimedKit/pl.lproj/Localizable.strings create mode 100644 MinimedKitTests/pl.lproj/InfoPlist.strings create mode 100644 MinimedKitUI/pl.lproj/InfoPlist.strings create mode 100644 MinimedKitUI/pl.lproj/Localizable.strings create mode 100644 MinimedKitUI/pl.lproj/MinimedPumpManager.strings create mode 100644 NightscoutUploadKit/pl.lproj/InfoPlist.strings create mode 100644 NightscoutUploadKitTests/pl.lproj/InfoPlist.strings create mode 100644 RileyLink/pl.lproj/InfoPlist.strings create mode 100644 RileyLink/pl.lproj/Localizable.strings create mode 100644 RileyLink/pl.lproj/LoopKit.strings create mode 100644 RileyLinkBLEKit/pl.lproj/InfoPlist.strings create mode 100644 RileyLinkBLEKit/pl.lproj/Localizable.strings create mode 100644 RileyLinkBLEKitTests/pl.lproj/InfoPlist.strings create mode 100644 RileyLinkKitTests/pl.lproj/InfoPlist.strings create mode 100644 RileyLinkKitUI/pl.lproj/InfoPlist.strings create mode 100644 RileyLinkKitUI/pl.lproj/Localizable.strings create mode 100644 RileyLinkTests/pl.lproj/InfoPlist.strings diff --git a/Crypto/pl.lproj/InfoPlist.strings b/Crypto/pl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/Crypto/pl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKit/pl.lproj/InfoPlist.strings b/MinimedKit/pl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKit/pl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKit/pl.lproj/Localizable.strings b/MinimedKit/pl.lproj/Localizable.strings new file mode 100644 index 000000000..a0d6d8539 --- /dev/null +++ b/MinimedKit/pl.lproj/Localizable.strings @@ -0,0 +1,99 @@ +/* Communications error for a bolus currently running */ +"A bolus is already in progress" = "Podawanie bolusa jest już w toku"; + +/* The description of AlarmClockReminderPumpEvent */ +"AlarmClockReminder" = "AlarmClockReminder"; + +/* The description of AlarmSensorPumpEvent */ +"AlarmSensor" = "AlarmSensor"; + +/* Describing the battery chemistry as Alkaline */ +"Alkaline" = "Alkaliczna"; + +/* The format string description of a BasalProfileStartPumpEvent. (1: The index of the profile)(2: The basal rate) */ +"Basal Profile %1$@: %2$@ U/hour" = "Profil bazy %1$@: %2$@ J/godzinę"; + +/* Pump error code when bolus is in progress */ +"Bolus in progress" = "Podawanie bolusa w toku"; + +/* Suggestions for diagnosing a command refused pump error */ +"Check that the pump is not suspended or priming, or has a percent temp basal type" = "Sprawdź, czy pompa nie jest zawieszona, nie trwa wypełnianie lub nie ma ustawionej procentowej dawki tymczasowej w ustawieniach."; + +/* Pump error code returned when command refused */ +"Command refused" = "Odmowa wykonania polecenia"; + +/* No comment provided by engineer. */ +"Comms with another pump detected" = "Wykryto połączenie z inną pompą."; + +/* Error description */ +"Decoding Error" = "Błąd dekodowania"; + +/* Error description */ +"Device Error" = "Błąd urządzenia"; + +/* Describing the pump history insulin data source */ +"Event History" = "Historia zdarzeń"; + +/* Format string for failure reason. (1: The operation being performed) (2: The response data) */ +"Invalid response during %1$@: %2$@" = "Nieprawidłowa odpowiedź podczas %1$@: %2$@"; + +/* Describing the battery chemistry as Lithium */ +"Lithium" = "Litowa"; + +/* Recovery suggestion */ +"Make sure your RileyLink is nearby and powered on" = "Upewnij się, że Twój RileyLink jest w pobliżu i jest włączony"; + +/* Pump error code describing max setting exceeded */ +"Max setting exceeded" = "Maksymalne ustawienie przekroczone"; + +/* Pump title (1: model number) */ +"Minimed %@" = "Minimed %@"; + +/* Generic title of the minimed pump manager */ +"Minimed 500/700 Series" = "Minimed serii 500/700"; + +/* Describing the North America pump region */ +"North America" = "Ameryka Północna"; + +/* No comment provided by engineer. */ +"Pump did not respond" = "Pompa nie odpowiada"; + +/* Error description */ +"Pump Error" = "Błąd pompy"; + +/* No comment provided by engineer. */ +"Pump is suspended" = "Pompa jest zawieszona"; + +/* No comment provided by engineer. */ +"Pump responded unexpectedly" = "Pompa odpowiedziała w nieoczekiwany sposób"; + +/* The format string describing a pump message. (1: The packet type)(2: The message type)(3: The message address)(4: The message data */ +"PumpMessage(%1$@, %2$@, %3$@, %4$@)" = "Wiadomość od pompy(%1$@, %2$@, %3$@, %4$@)"; + +/* Describing the reservoir insulin data source */ +"Reservoir" = "Zbiornik"; + +/* Error description */ +"RileyLink radio tune failed" = "Dostrajanie radia RileyLink zakończone niepowodzeniem"; + +/* The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in minutes) */ +"Temporary Basal: %1$.3f U/hour" = "Baza tymczasowa: %1$.3f J/godz"; + +/* The format string description of a TempBasalDurationPumpEvent. (1: The duration of the temp basal in minutes) */ +"Temporary Basal: %1$d min" = "Baza tymczasowa: %1$d min"; + +/* The format string description of a TempBasalPumpEvent. (1: The rate of the temp basal in percent) */ +"Temporary Basal: %1$d%%" = "Baza tymczasowa: %1$d%%"; + +/* The format string description of an unknown pump error code. (1: The specific error code raw value) */ +"Unknown pump error code: %1$@" = "Nieznany kod błędu pompy: %1$@"; + +/* No comment provided by engineer. */ +"Unknown pump model: %@" = "Nieznany model pompy: %@"; + +/* Format string for an unknown response. (1: The operation being performed) (2: The response data) */ +"Unknown response during %1$@: %2$@" = "Nieoczekiwana odpowiedź podczas %1$@: %2$@"; + +/* Describing the worldwide pump region */ +"World-Wide" = "Ogólnoświatowa"; + diff --git a/MinimedKitTests/pl.lproj/InfoPlist.strings b/MinimedKitTests/pl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKitTests/pl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKitUI/pl.lproj/InfoPlist.strings b/MinimedKitUI/pl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/MinimedKitUI/pl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/MinimedKitUI/pl.lproj/Localizable.strings b/MinimedKitUI/pl.lproj/Localizable.strings new file mode 100644 index 000000000..af141e9f1 --- /dev/null +++ b/MinimedKitUI/pl.lproj/Localizable.strings @@ -0,0 +1,195 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The format string for displaying a frequency tune trial. Extra spaces added for emphesis: (1: frequency in MHz)(2: success count)(3: total count)(4: average RSSI) */ +"%1$@ %2$@/%3$@ %4$@" = "%1$@ %2$@/%3$@ %4$@"; + +/* The format string describing number of basal schedule entries: (1: number of entries) */ +"%1$@ basal schedule entries\n" = "%1$@ wpisów dawki podstawowej\n"; + +/* The format string describing units of insulin remaining: (1: number of units) */ +"%1$@ Units of insulin remaining\n" = "%1$@ jednostek insuliny pozostało\n"; + +/* The format string for displaying an offset from a time zone: (1: GMT)(2: -)(3: 4:00) */ +"%1$@%2$@%3$@" = "%1$@%2$@%3$@"; + +/* Instructions on selecting battery chemistry type */ +"Alkaline and Lithium batteries decay at differing rates. Alkaline tend to have a linear voltage drop over time whereas lithium cell batteries tend to maintain voltage until halfway through their lifespan. Under normal usage in a Non-MySentry compatible Minimed (x22/x15) insulin pump running Loop, Alkaline batteries last approximately 4 to 5 days. Lithium batteries last between 1-2 weeks. This selection will use different battery voltage decay rates for each of the battery chemistry types and alert the user when a battery is approximately 8 to 10 hours from failure." = "Baterie alkaliczne i litowe różnią się szybkością rozładowywania. Baterie alkaliczne mają tendencję do liniowego spadku napięcia w czasie, natomiast baterie litowe mają tendencję do utrzymywania napięcia do momentu osiągnięcia połowy żywotności. W trakcie normalnego korzystania z Loop w niekompatybilnej z MySentry pompie (x22/x15), czas życia baterii alkalicznych wynosi ok. 4-5 dni. Żywotność baterii litowych wynosi ok. 1-2 tygodni. Wybór odpowiedniego typu baterii pozwoli na wybranie lepszego algorytmu zużycia baterii, dzięki czemu Loop będzie mógł wysłać ostrzeżenie, gdy zostanie ok. 8-10 godzin do całkowitego rozładowania."; + +/* Confirmation message for deleting a pump */ +"Are you sure you want to delete this pump?" = "Jesteś pewien, że chcesz usunąć tę pompę?"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Aktywny od"; + +/* The title text for the basal rate schedule */ +"Basal Rates" = "Dawka podstawowa"; + +/* The format string describing pump battery voltage: (1: battery voltage) */ +"Battery: %1$@ volts\n" = "Bateria: %1$@ V\n"; + +/* The label indicating the best radio frequency */ +"Best Frequency" = "Najlepsza częstotliwość"; + +/* The format string describing pump bolusing state: (1: bolusing) */ +"Bolusing: %1$@\n" = "Podawanie bolusa: %1$@\n"; + +/* The title of the cancel action in an action sheet */ +"Cancel" = "Anuluj"; + +/* The title of the command to change pump time */ +"Change Time" = "Zmień godzinę"; + +/* The title of the command to change pump time zone */ +"Change Time Zone" = "Zmień strefę czasową"; + +/* Progress message for changing pump time. */ +"Changing time…" = "Zmieniam godzinę…"; + +/* The title of the section describing commands */ +"Commands" = "Komunikaty"; + +/* The title of the configuration section in settings */ +"Configuration" = "Konfiguracja"; + +/* Button title to connect to pump during setup */ +"Connect" = "Połącz"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Status połączenia"; + +/* Button title to delete pump + Title text for the button to remove a pump from Loop */ +"Delete Pump" = "Usuń pompę"; + +/* Title text for delivery limits */ +"Delivery Limits" = "Limit podawania"; + +/* The title of the section describing the device */ +"Device" = "Urządzenie"; + +/* The title of the command to discover commands */ +"Discover Commands" = "Przejrzyj komunikaty"; + +/* Progress message for discovering commands. */ +"Discovering commands…" = "Przeglądanie komunikatów…"; + +/* The title of the command to enable diagnostic LEDs */ +"Enable Diagnostic LEDs" = "Włącz diagnostyczne LEDy"; + +/* Progress message for enabling diagnostic LEDs */ +"Enabled Diagnostic LEDs" = "Diagnostyczne LEDy włączone"; + +/* The title of the command to fetch recent glucose */ +"Fetch Enlite Glucose" = "Pobierz glukozę z Enlite"; + +/* The title of the command to fetch recent history */ +"Fetch Recent History" = "Pobierz najnowszą historię"; + +/* Progress message for fetching pump glucose. */ +"Fetching glucose…" = "Pobieranie glukozy…"; + +/* Progress message for fetching pump history. */ +"Fetching history…" = "Pobieranie historii…"; + +/* Progress message for fetching pump model. */ +"Fetching pump model…" = "Pobieranie modelu pompy…"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Oprogramowanie"; + +/* The title of the command to get pump model */ +"Get Pump Model" = "Pobierz model pompy"; + +/* Progress message for getting statistics. */ +"Get Statistics…" = "Pobieranie statystyk…"; + +/* Instructions on selecting an insulin data source */ +"Insulin delivery can be determined from the pump by either interpreting the event history or comparing the reservoir volume over time. Reading event history allows for a more accurate status graph and uploading up-to-date treatment data to Nightscout, at the cost of faster pump battery drain and the possibility of a higher radio error rate compared to reading only reservoir volume. If the selected source cannot be used for any reason, the system will attempt to fall back to the other option." = "Podaż insuliny jest ustalana dzięki pobieraniu danych z pompy. Może się to odbywać na dwa sposoby: poprzez interpretację historii zdarzeń lub poprzez porównywanie objętości zbiornika na insulinę w czasie. Interpretacja historii zdarzeń pozwala na dokładniejsze odwzorowanie wykresu statusu i wysyłanie aktualnych danych dotyczących leczenia do Nightscouta. Odbywa się to kosztem szybszego zużycia baterii i większym ryzykiem błędu transmisji radiowej względem drugiego sposobu, czyli porównywania objętości zbiornika na insulinę w czasie. Jeśli wybrany sposób z jakiegoś powodu nie może być użyty, system podejmie próbę powrotu do drugiej opcji."; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "Ostatnio aktywny"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Nasłuchiwanie wyłączone"; + +/* The title of the command to pair with mysentry */ +"MySentry Pair" = "Połącz z MySentry"; + +/* The title of the cell showing device name */ +"Name" = "Nazwa"; + +/* Message display when no response from tuning pump */ +"No response" = "Brak odpowiedzi"; + +/* The title of the cell showing the last idle */ +"On Idle" = "Wsrzymany"; + +/* The title text for the preferred insulin data source config */ +"Preferred Data Source" = "Preferowane źródło danych"; + +/* The title of the section describing the pump */ +"Pump" = "Pompa"; + +/* The title text for the battery type value */ +"Pump Battery Type" = "Rodzaj baterii w pompie"; + +/* The title of the cell showing pump ID + The title text for the pump ID config value */ +"Pump ID" = "ID pompy"; + +/* The title of the cell showing the pump model number */ +"Pump Model" = "Model pompy"; + +/* Title of the pump settings view controller */ +"Pump Settings" = "Ustawienia pompy"; + +/* The title of the command to read basal schedule */ +"Read Basal Schedule" = "Sprawdź dawkę podstawową"; + +/* The title of the command to read pump status */ +"Read Pump Status" = "Sprawdź status pompy"; + +/* Progress message for reading basal schedule */ +"Reading basal schedule…" = "Sprawdzanie dawki podstawowej…"; + +/* Progress message for reading pump status */ +"Reading pump status…" = "Sprawdzanie statusu pompy…"; + +/* Button title to retry sentry setup */ +"Retry" = "Spróbuj ponownie"; + +/* The title of the command to fetch RileyLink statistics */ +"RileyLink Statistics" = "Statystyki RileyLink"; + +/* Title of button to save basal profile to pump + Title of button to save delivery limit settings to pump */ +"Save to Pump…" = "Zapisz na pompie…"; + +/* The title of the command to send a button press */ +"Send Button Press" = "Wyślij polecenie wciśnięcia przycisku"; + +/* Progress message for sending button press to pump. */ +"Sending button press…" = "Wysyłanie polecenia wciśnięcia przycisku…"; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Siła sygnału"; + +/* A message indicating a command succeeded */ +"Succeeded" = "Udało się!"; + +/* The format string describing pump suspended state: (1: suspended) */ +"Suspended: %1$@\n" = "Zawieszona: %1$@\n"; + +/* The label indicating the results of each frequency trial */ +"Trials" = "Wyniki testu"; + +/* The title of the command to re-tune the radio */ +"Tune Radio Frequency" = "Dostrój częstotliwość radiową"; + +/* Progress message for tuning radio */ +"Tuning radio…" = "Dostrajanie radia…"; + +/* The detail text for an unknown pump model */ +"Unknown" = "Nieznany"; + diff --git a/MinimedKitUI/pl.lproj/MinimedPumpManager.strings b/MinimedKitUI/pl.lproj/MinimedPumpManager.strings new file mode 100644 index 000000000..4cff197ca --- /dev/null +++ b/MinimedKitUI/pl.lproj/MinimedPumpManager.strings @@ -0,0 +1,73 @@ + +/* Class = "UITableViewController"; title = "RileyLink Setup"; ObjectID = "0MV-2k-Dty"; */ +"0MV-2k-Dty.title" = "Konfiguracja RileyLink"; + +/* Class = "UILabel"; text = "Find Device"; ObjectID = "1fp-45-qWK"; */ +"1fp-45-qWK.text" = "Znajdź urządzenie"; + +/* Class = "UILabel"; text = "Other Devices"; ObjectID = "A6i-Cb-baR"; */ +"A6i-Cb-baR.text" = "Inne urządzenia"; + +/* Class = "UILabel"; text = "Do not change the time using your pumpʼs menu."; ObjectID = "Bdb-j4-WcR"; */ +"Bdb-j4-WcR.text" = "Nie zmieniaj godziny w ustawieniach czasu swojej pompy."; + +/* Class = "UITableViewController"; title = "Pump Clock"; ObjectID = "Fps-h3-V4K"; */ +"Fps-h3-V4K.title" = "Zegar w pompie"; + +/* Class = "UITextField"; placeholder = "Enter the 6-digit pump ID"; ObjectID = "HeG-VF-L5P"; */ +"HeG-VF-L5P.placeholder" = "Wprowadź 6-cyfrowe ID pompy"; + +/* Class = "UILabel"; text = "Review your pump settings below. You can change these settings at any time in Loopʼs Settings screen."; ObjectID = "HfQ-fG-8vO"; */ +"HfQ-fG-8vO.text" = "Sprawdź poprawność znajdujących się poniżej ustawień Twojej pompy. Możesz je zmodyfikować w dowolnym momencie w zakładce Ustawienia."; + +/* Class = "UILabel"; text = "If you travel to a different time zone for an extended period of time, you can change the pumpʼs time zone at any time in Loopʼs Settings screen."; ObjectID = "HuY-fE-vM8"; */ +"HuY-fE-vM8.text" = "Jeśli podróżujesz do innej strefy czasowej na dłuższy okres, możesz zmienić strefę czasową pompy w dowolnym momencie w zakładce Ustawienia."; + +/* Class = "UILabel"; text = "Loop will keep your pumpʼs clock synchronized with your phone in the time zone youʼre in now."; ObjectID = "IQ5-53-x9s"; */ +"IQ5-53-x9s.text" = "Loop będzie synchronizował zegar pompy ze strefą czasową ustawioną aktualnie w Twoim telefonie."; + +/* Class = "UITableViewController"; title = "Setup Complete"; ObjectID = "Nwf-TJ-KmJ"; */ +"Nwf-TJ-KmJ.title" = "Konfiguracja zakończona"; + +/* Class = "UITableViewController"; title = "Pump Setup"; ObjectID = "OZk-Db-KCs"; */ +"OZk-Db-KCs.title" = "Konfiguracja pompy"; + +/* Class = "UITableViewSection"; headerTitle = "Main Menu"; ObjectID = "ZnF-zy-5gR"; */ +"ZnF-zy-5gR.headerTitle" = "Menu główne"; + +/* Class = "UILabel"; text = "Utilities"; ObjectID = "c7t-pZ-WqY"; */ +"c7t-pZ-WqY.text" = "Narzędzia"; + +/* Class = "UILabel"; text = "Connect Devices"; ObjectID = "erq-yb-anx"; */ +"erq-yb-anx.text" = "Połącz urządzenia"; + +/* Class = "UITableViewSection"; footerTitle = "The pump ID is the 6-digit numerical portion of the serial number (labeled as SN or S/N)."; ObjectID = "fVG-pl-jT9"; */ +"fVG-pl-jT9.footerTitle" = "ID pompy to 6-cyfrowy numer (oznaczony jako SN lub S/N)."; + +/* Class = "UITableViewSection"; headerTitle = "Pump ID"; ObjectID = "fVG-pl-jT9"; */ +"fVG-pl-jT9.headerTitle" = "ID pompy"; + +/* Class = "UILabel"; text = "Your pump is ready for use."; ObjectID = "g1m-3k-XI3"; */ +"g1m-3k-XI3.text" = "Twoja pompa jest gotowa do użycia."; + +/* Class = "UITableViewController"; title = "Pump Settings"; ObjectID = "iQZ-kT-QUm"; */ +"iQZ-kT-QUm.title" = "Ustawienia pompy"; + +/* Class = "UITableViewSection"; footerTitle = "The pump region and color are denoted as the last 3 letters of the the model number (labeled as REF)."; ObjectID = "lGI-LD-xR7"; */ +"lGI-LD-xR7.footerTitle" = "Region i kolor pompy są oznaczone jako 3 ostatnie litery numeru modelu (który jest określony jako REF)."; + +/* Class = "UITableViewSection"; headerTitle = "Region and Color"; ObjectID = "lGI-LD-xR7"; */ +"lGI-LD-xR7.headerTitle" = "Region i kolor"; + +/* Class = "UITableViewController"; title = "Pump Broadcasts"; ObjectID = "oBL-lh-SHI"; */ +"oBL-lh-SHI.title" = "Komunikaty pompy"; + +/* Class = "UILabel"; text = "On"; ObjectID = "ojQ-ob-gBx"; */ +"ojQ-ob-gBx.text" = "Włączony"; + +/* Class = "UILabel"; text = "Enter the pump region"; ObjectID = "tGa-FP-JqD"; */ +"tGa-FP-JqD.text" = "Wprowadź region pompy"; + +/* Class = "UILabel"; text = "Loop will listen for status messages sent by your pump. Follow the steps below on your pump to enable these messages:"; ObjectID = "yLn-Ya-p1R"; */ +"yLn-Ya-p1R.text" = "Loop będzie nasłuchiwał komunikatów wysyłanych przez Twoją pompę. Postępuj zgodnie z poniższymi krokami (na Twojej pompie), aby umożliwić wysyłanie komunikatów:"; + diff --git a/NightscoutUploadKit/pl.lproj/InfoPlist.strings b/NightscoutUploadKit/pl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/NightscoutUploadKit/pl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/NightscoutUploadKitTests/pl.lproj/InfoPlist.strings b/NightscoutUploadKitTests/pl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/NightscoutUploadKitTests/pl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 770213c4b..3a65472ed 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -853,6 +853,25 @@ 54BC44B61DB81B5100340EED /* GetGlucosePageMessageBodyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GetGlucosePageMessageBodyTests.swift; sourceTree = ""; }; 54BC44B81DB81D6100340EED /* GetGlucosePageMessageBody.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GetGlucosePageMessageBody.swift; sourceTree = ""; }; 54DA4E841DFDC0A70007F489 /* SensorValueGlucoseEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SensorValueGlucoseEvent.swift; sourceTree = ""; }; + 7D199DA3212A159900241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/MinimedPumpManager.strings; sourceTree = ""; }; + 7D199DA4212A159900241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = ""; }; + 7D199DA5212A159900241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/LoopKit.strings; sourceTree = ""; }; + 7D199DA6212A159900241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D199DA7212A159900241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D199DA8212A159900241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = ""; }; + 7D199DA9212A159900241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D199DAA212A159900241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D199DAB212A159900241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D199DAC212A159A00241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D199DAD212A159A00241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D199DAE212A159A00241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D199DAF212A159A00241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = ""; }; + 7D199DB0212A159A00241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D199DB1212A159A00241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D199DB2212A159A00241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = ""; }; + 7D199DB3212A159A00241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; + 7D199DB4212A159A00241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = ""; }; + 7D199DB5212A159A00241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; 7D2366EF212527DA0028B67D /* LocalizedString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizedString.swift; sourceTree = ""; }; 7D2366F8212528560028B67D /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = ""; }; 7D2366F9212528990028B67D /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = ""; }; @@ -2484,6 +2503,7 @@ it, nl, nb, + pl, ); mainGroup = C12EA22E198B436800309FA4; productRefGroup = C12EA238198B436800309FA4 /* Products */; @@ -3257,6 +3277,7 @@ 7D2367362125299F0028B67D /* nb */, 7D23675721252A5E0028B67D /* es */, 7D23675F21252A720028B67D /* ru */, + 7D199DA3212A159900241026 /* pl */, ); name = MinimedPumpManager.storyboard; sourceTree = ""; @@ -3272,6 +3293,7 @@ 7D23677D21252AC40028B67D /* nb */, 7D23678321252AD30028B67D /* nl */, 7D23678B21252AE10028B67D /* zh-Hans */, + 7D199DB3212A159A00241026 /* pl */, ); name = InfoPlist.strings; sourceTree = ""; @@ -3287,6 +3309,7 @@ 7D23677E21252AC40028B67D /* nb */, 7D23678421252AD30028B67D /* nl */, 7D23678C21252AE10028B67D /* zh-Hans */, + 7D199DAB212A159900241026 /* pl */, ); name = InfoPlist.strings; sourceTree = ""; @@ -3302,6 +3325,7 @@ 7D23677C21252AC40028B67D /* nb */, 7D23678521252AD30028B67D /* nl */, 7D23678A21252AE10028B67D /* zh-Hans */, + 7D199DB1212A159A00241026 /* pl */, ); name = InfoPlist.strings; sourceTree = ""; @@ -3317,6 +3341,7 @@ 7D23677F21252AC40028B67D /* nb */, 7D23678621252AD30028B67D /* nl */, 7D23678E21252AE10028B67D /* zh-Hans */, + 7D199DAA212A159900241026 /* pl */, ); name = InfoPlist.strings; sourceTree = ""; @@ -3332,6 +3357,7 @@ 7D23678121252AC40028B67D /* nb */, 7D23678821252AD30028B67D /* nl */, 7D23678D21252AE10028B67D /* zh-Hans */, + 7D199DB5212A159A00241026 /* pl */, ); name = InfoPlist.strings; sourceTree = ""; @@ -3347,6 +3373,7 @@ 7D23678021252AC40028B67D /* nb */, 7D23678721252AD30028B67D /* nl */, 7D23678F21252AE10028B67D /* zh-Hans */, + 7D199DAD212A159A00241026 /* pl */, ); name = InfoPlist.strings; sourceTree = ""; @@ -3363,6 +3390,7 @@ 7D2367A2212530300028B67D /* ru */, 7D2367A42125303D0028B67D /* zh-Hans */, 7D2367A62125304D0028B67D /* nl */, + 7D199DAF212A159A00241026 /* pl */, ); name = Localizable.strings; sourceTree = ""; @@ -3379,6 +3407,7 @@ 7D2367A3212530300028B67D /* ru */, 7D2367A52125303D0028B67D /* zh-Hans */, 7D2367A72125304D0028B67D /* nl */, + 7D199DB2212A159A00241026 /* pl */, ); name = Localizable.strings; sourceTree = ""; @@ -3394,6 +3423,7 @@ 7D236720212529890028B67D /* it */, 7D23672C212529950028B67D /* nl */, 7D236738212529A00028B67D /* nb */, + 7D199DA5212A159900241026 /* pl */, ); name = LoopKit.strings; sourceTree = ""; @@ -3409,6 +3439,7 @@ 7D2367282125298A0028B67D /* it */, 7D236734212529960028B67D /* nl */, 7D236740212529A10028B67D /* nb */, + 7D199DAE212A159A00241026 /* pl */, ); name = InfoPlist.strings; sourceTree = ""; @@ -3424,6 +3455,7 @@ 7D2367242125298A0028B67D /* it */, 7D236730212529950028B67D /* nl */, 7D23673C212529A00028B67D /* nb */, + 7D199DA9212A159900241026 /* pl */, ); name = InfoPlist.strings; sourceTree = ""; @@ -3439,6 +3471,7 @@ 7D2367292125298A0028B67D /* it */, 7D236735212529960028B67D /* nl */, 7D236741212529A10028B67D /* nb */, + 7D199DB0212A159A00241026 /* pl */, ); name = InfoPlist.strings; sourceTree = ""; @@ -3455,6 +3488,7 @@ 7D236723212529890028B67D /* it */, 7D23672F212529950028B67D /* nl */, 7D23673B212529A00028B67D /* nb */, + 7D199DA8212A159900241026 /* pl */, ); name = Localizable.strings; sourceTree = ""; @@ -3470,6 +3504,7 @@ 7D2367272125298A0028B67D /* it */, 7D236733212529950028B67D /* nl */, 7D23673F212529A00028B67D /* nb */, + 7D199DAC212A159A00241026 /* pl */, ); name = InfoPlist.strings; sourceTree = ""; @@ -3486,6 +3521,7 @@ 7D23671F212529890028B67D /* it */, 7D23672B212529950028B67D /* nl */, 7D2367372125299F0028B67D /* nb */, + 7D199DA4212A159900241026 /* pl */, ); name = Localizable.strings; sourceTree = ""; @@ -3502,6 +3538,7 @@ 7D236721212529890028B67D /* it */, 7D23672D212529950028B67D /* nl */, 7D236739212529A00028B67D /* nb */, + 7D199DA6212A159900241026 /* pl */, ); name = InfoPlist.strings; sourceTree = ""; @@ -3518,6 +3555,7 @@ 7D236722212529890028B67D /* it */, 7D23672E212529950028B67D /* nl */, 7D23673A212529A00028B67D /* nb */, + 7D199DA7212A159900241026 /* pl */, ); name = InfoPlist.strings; sourceTree = ""; @@ -3534,6 +3572,7 @@ C1FFAF542129450D00C50C1D /* it */, C1FFAF552129450F00C50C1D /* nl */, C1FFAF562129451300C50C1D /* nb */, + 7D199DB4212A159A00241026 /* pl */, ); name = Localizable.strings; sourceTree = ""; diff --git a/RileyLink/pl.lproj/InfoPlist.strings b/RileyLink/pl.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/RileyLink/pl.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + diff --git a/RileyLink/pl.lproj/Localizable.strings b/RileyLink/pl.lproj/Localizable.strings new file mode 100644 index 000000000..da259cd20 --- /dev/null +++ b/RileyLink/pl.lproj/Localizable.strings @@ -0,0 +1,53 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The title of the about section */ +"About" = "O aplikacji"; + +/* The title of the button to add the credentials for a service */ +"Add Account" = "Dodaj konto"; + +/* The title of the nightscout API secret credential */ +"API Secret" = "API Secret"; + +/* The title of the configuration section in settings */ +"Configuration" = "Konfiguracja"; + +/* The title of the button to remove the credentials for a service */ +"Delete Account" = "Usuń konto"; + +/* The placeholder text instructing users how to enter a pump ID */ +"Enter the 6-digit pump ID" = "Wprowadź 6-cyfrowe ID pompy"; + +/* The title text for the pull cgm Data cell */ +"Fetch CGM" = "Pobierz dane z CGM"; + +/* The placeholder text for the nightscout site URL credential */ +"http://mysite.azurewebsites.net" = "http://mysite.azurewebsites.net"; + +/* The title of the Nightscout service */ +"Nightscout" = "Nightscout"; + +/* The title text for the pump ID config value */ +"Pump ID" = "ID pompy"; + +/* The title text for the pump Region config value */ +"Pump Region" = "Region zakupu pompy"; + +/* Instructions on selecting the pump region */ +"Pump Region is listed on the back of your pump as two of the last three characters of the model string, which reads something like this: MMT-551NAB, or MMT-515LWWS. If your model has an \"NA\" in it, then the region is North America. If your model has an \"WW\" in it, then the region is WorldWide." = "Region zakupu pompy znajduje się na etykiecie, na odwrocie pompy. Region jest określony przez dwa z trzech ostatnich znaków określających model pompy. Jeśli Twój model zawiera sekwencję \”NA\”, wtedy region to Ameryka Północna. Jeśli Twój model zawiera sekwencję \”WW\”, wtedy region to Ogólnoświatowy. Przykładowe modele pomp z regionem: MMT-551NAB - region to Ameryka Północna; MMT-515LWWS - region to Ogólnoświatowy."; + +/* The default placeholder string for a credential */ +"Required" = "Wymagany"; + +/* The title of the nightscout site URL credential */ +"Site URL" = "URL strony"; + +/* The empty-state text for a configuration value */ +"Tap to set" = "Dotknij, aby ustawić"; + +/* The title text for the nightscout upload enabled switch cell */ +"Upload To Nightscout" = "Wysyłaj do Nightscout"; + +/* Label indicating validation is occurring */ +"Verifying" = "Weryfikacja"; diff --git a/RileyLink/pl.lproj/LoopKit.strings b/RileyLink/pl.lproj/LoopKit.strings new file mode 100644 index 000000000..bc1fda9fb --- /dev/null +++ b/RileyLink/pl.lproj/LoopKit.strings @@ -0,0 +1,3 @@ +/* The title of the action used to dismiss an error alert */ +"com.loudnate.LoopKit.errorAlertActionTitle" = "OK"; + diff --git a/RileyLinkBLEKit/pl.lproj/InfoPlist.strings b/RileyLinkBLEKit/pl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkBLEKit/pl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkBLEKit/pl.lproj/Localizable.strings b/RileyLinkBLEKit/pl.lproj/Localizable.strings new file mode 100644 index 000000000..c0399c5fc --- /dev/null +++ b/RileyLinkBLEKit/pl.lproj/Localizable.strings @@ -0,0 +1,30 @@ +/* Write size limit exceeded error description (1: size limit) */ +"Data exceeded maximum size of %@ bytes" = "Dane przekraczają maksymalną pojemność %@ bajtów"; + +/* Invalid input error description (1: input) */ +"Input %@ is invalid" = "Wprowadzona %@ jest nieprawidłowa"; + +/* Recovery suggestion for unknown peripheral characteristic */ +"Make sure the device is nearby, and the issue should resolve automatically" = "Upewnij się, że urządzenie jest w pobliżu; problem powinien rozwiązać się automatycznie"; + +/* Timeout error description */ +"Peripheral did not respond in time" = "Urz. peryferyjne nie odpowiada"; + +/* Not ready error description */ +"Peripheral isnʼt connected" = "Urz. peryferyjne jest niepodłączone"; + +/* Response timeout error description */ +"Pump did not respond in time" = "Czas oczekiwania na odpowiedź pompy został przekroczony"; + +/* Invalid response error description (1: response) */ +"Response %@ is invalid" = "Odpowiedź %@ jest nieprawidłowa"; + +/* Unsupported command error description */ +"RileyLink firmware does not support the %@ command" = "Oprogramowanie RileyLink nie obsługuje polecenia %@"; + +/* Failure reason: unknown peripheral characteristic */ +"The RileyLink was temporarily disconnected" = "RileyLink został tymczasowo rozłączony"; + +/* Error description */ +"Unknown characteristic" = "Nieznany błąd"; + diff --git a/RileyLinkBLEKitTests/pl.lproj/InfoPlist.strings b/RileyLinkBLEKitTests/pl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkBLEKitTests/pl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKitTests/pl.lproj/InfoPlist.strings b/RileyLinkKitTests/pl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKitTests/pl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKitUI/pl.lproj/InfoPlist.strings b/RileyLinkKitUI/pl.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKitUI/pl.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + diff --git a/RileyLinkKitUI/pl.lproj/Localizable.strings b/RileyLinkKitUI/pl.lproj/Localizable.strings new file mode 100644 index 000000000..668ffb0dc --- /dev/null +++ b/RileyLinkKitUI/pl.lproj/Localizable.strings @@ -0,0 +1,52 @@ +/* Unit format string for an RSSI value in decibles */ +"%@ dB" = "%@ dB"; + +/* The title of the cell describing an awake radio */ +"Awake Until" = "Aktywny od"; + +/* The title of the section describing commands */ +"Commands" = "Komendy"; + +/* The connected state */ +"Connected" = "Połączony"; + +/* The in-progress connecting state */ +"Connecting" = "Łączenie"; + +/* The title of the cell showing BLE connection state */ +"Connection State" = "Status połączenia"; + +/* The title of the section describing the device */ +"Device" = "Urządzenie"; + +/* The title of the devices table section in RileyLink settings */ +"Devices" = "Urządzenia"; + +/* The disconnected state */ +"Disconnected" = "Rozłączony"; + +/* The in-progress disconnecting state */ +"Disconnecting" = "Rozłączanie"; + +/* The title of the cell showing firmware version */ +"Firmware" = "Oprogramowanie"; + +/* The title of the cell describing an awake radio */ +"Last Awake" = "Ostatnio aktywny"; + +/* The title of the cell describing no radio awake data */ +"Listening Off" = "Brak danych o aktywności"; + +/* The title of the cell showing device name */ +"Name" = "Nazwa"; + +/* The title of the cell showing the last idle */ +"On Idle" = "Bezczynny od"; + +/* RileyLink setup description */ +"RileyLink allows for communication with the pump over Bluetooth Low Energy." = "RileyLink będzie łączył się z pompą poprzez Bluetooth Low Energy."; + +/* The title of the cell showing BLE signal strength (RSSI) */ +"Signal Strength" = "Siła sygnału"; + + diff --git a/RileyLinkTests/pl.lproj/InfoPlist.strings b/RileyLinkTests/pl.lproj/InfoPlist.strings new file mode 100644 index 000000000..477b28ff8 --- /dev/null +++ b/RileyLinkTests/pl.lproj/InfoPlist.strings @@ -0,0 +1,2 @@ +/* Localized versions of Info.plist keys */ + From a9515bccf392fcc2cf53d991c68f6a1500a87d0d Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 20 Aug 2018 10:38:51 -0500 Subject: [PATCH 21/22] Turn off automatic signing for frameworks, and fix another duplicate ref (#442) --- RileyLink.xcodeproj/project.pbxproj | 74 ++++++++++++----------- RileyLinkKitUI/en.lproj/InfoPlist.strings | 3 + 2 files changed, 41 insertions(+), 36 deletions(-) create mode 100644 RileyLinkKitUI/en.lproj/InfoPlist.strings diff --git a/RileyLink.xcodeproj/project.pbxproj b/RileyLink.xcodeproj/project.pbxproj index 3a65472ed..e87f1e28d 100644 --- a/RileyLink.xcodeproj/project.pbxproj +++ b/RileyLink.xcodeproj/project.pbxproj @@ -268,14 +268,12 @@ 7D2366F5212527DA0028B67D /* LocalizedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2366EF212527DA0028B67D /* LocalizedString.swift */; }; 7D2366F6212527DA0028B67D /* LocalizedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2366EF212527DA0028B67D /* LocalizedString.swift */; }; 7D2366F7212527DA0028B67D /* LocalizedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2366EF212527DA0028B67D /* LocalizedString.swift */; }; - 7D23674421252A5E0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674221252A5E0028B67D /* InfoPlist.strings */; }; 7D23674721252A5E0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674521252A5E0028B67D /* InfoPlist.strings */; }; 7D23674A21252A5E0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674821252A5E0028B67D /* InfoPlist.strings */; }; 7D23674D21252A5E0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674B21252A5E0028B67D /* InfoPlist.strings */; }; 7D23675021252A5E0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674E21252A5E0028B67D /* InfoPlist.strings */; }; 7D23675321252A5E0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23675121252A5E0028B67D /* InfoPlist.strings */; }; 7D23676121252A9D0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674821252A5E0028B67D /* InfoPlist.strings */; }; - 7D23676321252A9D0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674221252A5E0028B67D /* InfoPlist.strings */; }; 7D23676721252A9D0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674521252A5E0028B67D /* InfoPlist.strings */; }; 7D23676921252A9D0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23674B21252A5E0028B67D /* InfoPlist.strings */; }; 7D23676B21252A9D0028B67D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D23675121252A5E0028B67D /* InfoPlist.strings */; }; @@ -477,6 +475,7 @@ C1F6EB8D1F89C45500CFE393 /* MinimedPacketTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1F6EB8C1F89C45500CFE393 /* MinimedPacketTests.swift */; }; C1FDFCA91D964A3E00ADBC31 /* BolusReminderPumpEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1FDFCA81D964A3E00ADBC31 /* BolusReminderPumpEvent.swift */; }; C1FFAF4D212944F600C50C1D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C1FFAF4B212944F600C50C1D /* Localizable.strings */; }; + C1FFAF64212B126E00C50C1D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C1FFAF62212B126E00C50C1D /* InfoPlist.strings */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -869,7 +868,6 @@ 7D199DB0212A159A00241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; 7D199DB1212A159A00241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; 7D199DB2212A159A00241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = ""; }; - 7D199DB3212A159A00241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; 7D199DB4212A159A00241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = ""; }; 7D199DB5212A159A00241026 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; 7D2366EF212527DA0028B67D /* LocalizedString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizedString.swift; sourceTree = ""; }; @@ -935,7 +933,6 @@ 7D23673F212529A00028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; 7D236740212529A10028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; 7D236741212529A10028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D23674321252A5E0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23674621252A5E0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23674921252A5E0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23674C21252A5E0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -943,14 +940,12 @@ 7D23675221252A5E0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23675721252A5E0028B67D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/MinimedPumpManager.strings; sourceTree = ""; }; 7D23675821252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D23675921252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23675A21252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23675B21252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23675C21252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23675D21252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23675F21252A720028B67D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/MinimedPumpManager.strings; sourceTree = ""; }; 7D23676021252A9D0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D23676221252A9D0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23676421252A9D0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23676621252A9D0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23676821252A9D0028B67D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -958,29 +953,24 @@ 7D23676E21252AA80028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23676F21252AA80028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677021252AA80028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D23677121252AA80028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677221252AA80028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677321252AA80028B67D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677521252AB70028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D23677621252AB70028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677721252AB70028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677821252AB70028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677921252AB70028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677A21252AB70028B67D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677C21252AC40028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D23677D21252AC40028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677E21252AC40028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23677F21252AC40028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23678021252AC40028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23678121252AC40028B67D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; - 7D23678321252AD30028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23678421252AD30028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23678521252AD30028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23678621252AD30028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23678721252AD30028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23678821252AD30028B67D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; 7D23678A21252AE10028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; - 7D23678B21252AE10028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; 7D23678C21252AE10028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; 7D23678D21252AE10028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; 7D23678E21252AE10028B67D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; @@ -1236,6 +1226,15 @@ C1FFAF542129450D00C50C1D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; }; C1FFAF552129450F00C50C1D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; C1FFAF562129451300C50C1D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Localizable.strings; sourceTree = ""; }; + C1FFAF63212B126E00C50C1D /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; + C1FFAF66212B127C00C50C1D /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; + C1FFAF67212B127E00C50C1D /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; + C1FFAF68212B128000C50C1D /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; + C1FFAF69212B128300C50C1D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = ""; }; + C1FFAF6A212B128500C50C1D /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; + C1FFAF6B212B128800C50C1D /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = ""; }; + C1FFAF6C212B128A00C50C1D /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/InfoPlist.strings; sourceTree = ""; }; + C1FFAF6D212B128C00C50C1D /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1527,10 +1526,10 @@ 43D5E78F1FAF7BFB004ACDB7 /* RileyLinkKitUI */ = { isa = PBXGroup; children = ( + C1FFAF62212B126E00C50C1D /* InfoPlist.strings */, 43D5E7901FAF7BFB004ACDB7 /* RileyLinkKitUI.h */, 43D5E7911FAF7BFB004ACDB7 /* Info.plist */, 7D23679521252EBC0028B67D /* Localizable.strings */, - 7D23674221252A5E0028B67D /* InfoPlist.strings */, 43709AEB20E0056F00F941B3 /* RileyLinkKitUI.xcassets */, C170C98D1CECD6F300F3D8E5 /* CBPeripheralState.swift */, C170C9961CECD80000F3D8E5 /* CommandResponseViewController.swift */, @@ -2437,7 +2436,7 @@ 4352A72420DEC9B700CAC200 = { CreatedOnToolsVersion = 9.4.1; LastSwiftMigration = 0940; - ProvisioningStyle = Automatic; + ProvisioningStyle = Manual; }; 43722FAD1CB9F7630038B7F2 = { CreatedOnToolsVersion = 7.3; @@ -2455,7 +2454,7 @@ }; 43D5E78D1FAF7BFB004ACDB7 = { CreatedOnToolsVersion = 9.2; - ProvisioningStyle = Automatic; + ProvisioningStyle = Manual; }; 43FB610120DDEF26002B996B = { CreatedOnToolsVersion = 9.4.1; @@ -2586,9 +2585,8 @@ buildActionMask = 2147483647; files = ( 7D23679721252EBC0028B67D /* Localizable.strings in Resources */, + C1FFAF64212B126E00C50C1D /* InfoPlist.strings in Resources */, 43709AEC20E0056F00F941B3 /* RileyLinkKitUI.xcassets in Resources */, - 7D23676321252A9D0028B67D /* InfoPlist.strings in Resources */, - 7D23674421252A5E0028B67D /* InfoPlist.strings in Resources */, 43709AF020E0120F00F941B3 /* SetupImageTableViewCell.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3282,22 +3280,6 @@ name = MinimedPumpManager.storyboard; sourceTree = ""; }; - 7D23674221252A5E0028B67D /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - 7D23674321252A5E0028B67D /* es */, - 7D23675921252A720028B67D /* ru */, - 7D23676221252A9D0028B67D /* de */, - 7D23677121252AA80028B67D /* fr */, - 7D23677621252AB70028B67D /* it */, - 7D23677D21252AC40028B67D /* nb */, - 7D23678321252AD30028B67D /* nl */, - 7D23678B21252AE10028B67D /* zh-Hans */, - 7D199DB3212A159A00241026 /* pl */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; 7D23674521252A5E0028B67D /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( @@ -3577,6 +3559,22 @@ name = Localizable.strings; sourceTree = ""; }; + C1FFAF62212B126E00C50C1D /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + C1FFAF63212B126E00C50C1D /* de */, + C1FFAF66212B127C00C50C1D /* es */, + C1FFAF67212B127E00C50C1D /* ru */, + C1FFAF68212B128000C50C1D /* fr */, + C1FFAF69212B128300C50C1D /* zh-Hans */, + C1FFAF6A212B128500C50C1D /* it */, + C1FFAF6B212B128800C50C1D /* nl */, + C1FFAF6C212B128A00C50C1D /* nb */, + C1FFAF6D212B128C00C50C1D /* pl */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ @@ -3712,7 +3710,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; + CODE_SIGN_STYLE = Manual; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; @@ -3730,6 +3728,7 @@ MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = com.ps2.MinimedKitUI; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -3750,7 +3749,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; + CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; @@ -3769,6 +3768,7 @@ MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = com.ps2.MinimedKitUI; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VERSION_INFO_PREFIX = ""; @@ -3966,7 +3966,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - CODE_SIGN_STYLE = Automatic; + CODE_SIGN_STYLE = Manual; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; @@ -3984,6 +3984,7 @@ MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.RileyLinkKitUI; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -4003,7 +4004,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - CODE_SIGN_STYLE = Automatic; + CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; @@ -4022,6 +4023,7 @@ MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = com.rileylink.RileyLinkKitUI; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VERSION_INFO_PREFIX = ""; diff --git a/RileyLinkKitUI/en.lproj/InfoPlist.strings b/RileyLinkKitUI/en.lproj/InfoPlist.strings new file mode 100644 index 000000000..bbcf8f904 --- /dev/null +++ b/RileyLinkKitUI/en.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +/* Bundle name */ +"CFBundleName" = "$(PRODUCT_NAME)"; + From 2dc383044350a9b8c58ebad2707a19a7cffee1b3 Mon Sep 17 00:00:00 2001 From: Pete Schwamb Date: Mon, 20 Aug 2018 13:26:14 -0500 Subject: [PATCH 22/22] Use LoopKit 2.1.2 --- Cartfile | 2 +- Cartfile.resolved | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cartfile b/Cartfile index 48e92d0b4..18619d826 100644 --- a/Cartfile +++ b/Cartfile @@ -1 +1 @@ -github "LoopKit/LoopKit" == 2.1.1 +github "LoopKit/LoopKit" == 2.1.2 diff --git a/Cartfile.resolved b/Cartfile.resolved index 25532f0c1..87e8897cc 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1 +1 @@ -github "LoopKit/LoopKit" "v2.1.1" +github "LoopKit/LoopKit" "v2.1.2"