MinimedPumpSentrySetupViewController.swift 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. //
  2. // MinimedPumpSentrySetupViewController.swift
  3. // Loop
  4. //
  5. // Copyright © 2018 LoopKit Authors. All rights reserved.
  6. //
  7. import UIKit
  8. import LoopKit
  9. import LoopKitUI
  10. import MinimedKit
  11. class MinimedPumpSentrySetupViewController: SetupTableViewController {
  12. var pumpManager: MinimedPumpManager?
  13. @IBOutlet weak var activityIndicator: SetupIndicatorView!
  14. @IBOutlet weak var loadingLabel: UILabel!
  15. override func viewDidLoad() {
  16. super.viewDidLoad()
  17. lastError = nil
  18. }
  19. override func viewDidAppear(_ animated: Bool) {
  20. super.viewDidAppear(animated)
  21. if pumpManager == nil {
  22. navigationController?.popViewController(animated: true)
  23. }
  24. // Select the first row
  25. tableView.selectRow(at: [1, 0], animated: true, scrollPosition: .none)
  26. }
  27. override func continueButtonPressed(_ sender: Any) {
  28. switch continueState {
  29. case .notStarted:
  30. listenForPairing()
  31. case .listening:
  32. break
  33. case .completed:
  34. if let setupViewController = navigationController as? MinimedPumpManagerSetupViewController,
  35. let pumpManager = pumpManager
  36. {
  37. super.continueButtonPressed(sender)
  38. setupViewController.pumpManagerSetupComplete(pumpManager)
  39. }
  40. }
  41. }
  42. // MARK: -
  43. private enum State {
  44. case notStarted
  45. case listening
  46. case completed
  47. }
  48. private var continueState: State = .notStarted {
  49. didSet {
  50. switch continueState {
  51. case .notStarted:
  52. footerView.primaryButton.isEnabled = true
  53. activityIndicator.state = .hidden
  54. footerView.primaryButton.setTitle(LocalizedString("Retry", comment: "Button title to retry sentry setup"), for: .normal)
  55. case .listening:
  56. lastError = nil
  57. activityIndicator.state = .indeterminantProgress
  58. footerView.primaryButton.isEnabled = false
  59. case .completed:
  60. lastError = nil
  61. activityIndicator.state = .completed
  62. footerView.primaryButton.isEnabled = true
  63. footerView.primaryButton.resetTitle()
  64. }
  65. }
  66. }
  67. private func listenForPairing() {
  68. guard let pumpManager = pumpManager else {
  69. continueState = .notStarted
  70. lastError = PumpManagerError.connection(MinimedPumpManagerError.noRileyLink)
  71. return
  72. }
  73. continueState = .listening
  74. pumpManager.pumpOps.runSession(withName: "MySentry Pairing", usingSelector: pumpManager.rileyLinkDeviceProvider.firstConnectedDevice) { (session) in
  75. guard let session = session else {
  76. DispatchQueue.main.async {
  77. self.continueState = .notStarted
  78. self.lastError = PumpManagerError.connection(MinimedPumpManagerError.noRileyLink)
  79. }
  80. return
  81. }
  82. let watchdogID = Data([0xd0, 0x00, 0x07])
  83. do {
  84. try session.changeWatchdogMarriageProfile(watchdogID)
  85. DispatchQueue.main.async {
  86. self.continueState = .completed
  87. }
  88. } catch let error {
  89. DispatchQueue.main.async {
  90. self.continueState = .notStarted
  91. self.lastError = error
  92. }
  93. }
  94. }
  95. }
  96. private var lastError: Error? {
  97. didSet {
  98. guard oldValue != nil || lastError != nil else {
  99. return
  100. }
  101. var errorText = lastError?.localizedDescription
  102. if let error = lastError as? LocalizedError {
  103. let localizedText = [error.errorDescription, error.failureReason, error.recoverySuggestion].compactMap({ $0 }).joined(separator: ". ")
  104. if !localizedText.isEmpty {
  105. errorText = localizedText
  106. }
  107. }
  108. tableView.beginUpdates()
  109. loadingLabel.text = errorText
  110. let isHidden = (errorText == nil)
  111. loadingLabel.isHidden = isHidden
  112. tableView.endUpdates()
  113. }
  114. }
  115. }
  116. class PumpMenuItemTableViewCell: UITableViewCell {
  117. override func awakeFromNib() {
  118. super.awakeFromNib()
  119. updateLabel(selected: false)
  120. }
  121. private func updateLabel(selected: Bool) {
  122. let font = UIFont(name: "Menlo-Bold", size: 14) ?? UIFont.monospacedDigitSystemFont(ofSize: 14, weight: .medium)
  123. let metrics = UIFontMetrics(forTextStyle: .body)
  124. metrics.scaledFont(for: font)
  125. let paragraphStyle = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle
  126. paragraphStyle.firstLineHeadIndent = 15
  127. let bundle = Bundle(for: type(of: self))
  128. let textColor = UIColor(named: "Pump Screen Text", in: bundle, compatibleWith: traitCollection)!
  129. let backgroundColor = UIColor(named: "Pump Screen Background", in: bundle, compatibleWith: traitCollection)!
  130. textLabel?.backgroundColor = backgroundColor
  131. textLabel?.attributedText = NSAttributedString(
  132. string: textLabel?.text ?? "",
  133. attributes: [
  134. .backgroundColor: selected ? textColor : backgroundColor,
  135. .foregroundColor: selected ? backgroundColor : textColor,
  136. .font: metrics.scaledFont(for: font),
  137. .paragraphStyle: paragraphStyle,
  138. ]
  139. )
  140. }
  141. override func setSelected(_ selected: Bool, animated: Bool) {
  142. super.setSelected(selected, animated: animated)
  143. updateLabel(selected: selected)
  144. }
  145. }