WatchState+Requests.swift 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. import Foundation
  2. import WatchConnectivity
  3. // MARK: - Send Data to Phone
  4. extension WatchState {
  5. /// Sends a bolus insulin request to the paired iPhone
  6. /// - Parameters:
  7. /// - amount: The insulin amount to be delivered
  8. func sendBolusRequest(_ amount: Decimal) {
  9. guard let session = session, session.isReachable else {
  10. Task {
  11. await WatchLogger.shared.log("⌚️ Bolus request aborted: session unreachable")
  12. }
  13. return
  14. }
  15. Task {
  16. await WatchLogger.shared.log("⌚️ Sending bolus request: \(amount)U")
  17. }
  18. let message: [String: Any] = [
  19. WatchMessageKeys.bolus: amount
  20. ]
  21. session.sendMessage(message, replyHandler: nil) { error in
  22. Task {
  23. await WatchLogger.shared.log("Error sending bolus request: \(error.localizedDescription)")
  24. }
  25. }
  26. // Display pending communication animation
  27. showCommsAnimation = true
  28. Task {
  29. await WatchLogger.shared.log("⌚️ showCommsAnimation = true")
  30. }
  31. }
  32. /// Sends a carbohydrate entry request to the paired iPhone
  33. /// - Parameters:
  34. /// - amount: The amount of carbs in grams
  35. /// - date: The timestamp for the carb entry (defaults to current time)
  36. func sendCarbsRequest(_ amount: Int, _ date: Date = Date()) {
  37. guard let session = session, session.isReachable else {
  38. Task {
  39. await WatchLogger.shared.log("⌚️ Carbs request aborted: session unreachable")
  40. }
  41. return
  42. }
  43. Task {
  44. await WatchLogger.shared.log("⌚️ Sending carbs request: \(amount)g at \(date)")
  45. }
  46. let message: [String: Any] = [
  47. WatchMessageKeys.carbs: amount,
  48. WatchMessageKeys.date: date.timeIntervalSince1970
  49. ]
  50. session.sendMessage(message, replyHandler: nil) { error in
  51. Task {
  52. await WatchLogger.shared.log("Error sending carbs request: \(error.localizedDescription)")
  53. await WatchLogger.shared.log("⌚️ Saving logs to disk as fallback!")
  54. await WatchLogger.shared.persistLogsLocally()
  55. }
  56. }
  57. // Display pending communication animation
  58. showCommsAnimation = true
  59. Task {
  60. await WatchLogger.shared.log("⌚️ showCommsAnimation = true")
  61. }
  62. }
  63. /// Sends a request to cancel the current override preset to the paired iPhone
  64. func sendCancelOverrideRequest() {
  65. guard let session = session, session.isReachable else {
  66. Task {
  67. await WatchLogger.shared.log("⌚️ Cancel override request aborted: session unreachable")
  68. }
  69. return
  70. }
  71. Task {
  72. await WatchLogger.shared.log("⌚️ Sending cancel override request")
  73. }
  74. let message: [String: Any] = [
  75. WatchMessageKeys.cancelOverride: true
  76. ]
  77. session.sendMessage(message, replyHandler: nil) { error in
  78. Task {
  79. await WatchLogger.shared.log("⌚️ Error sending cancel override request: \(error.localizedDescription)")
  80. await WatchLogger.shared.log("⌚️ Saving logs to disk as fallback!")
  81. await WatchLogger.shared.persistLogsLocally()
  82. }
  83. }
  84. // Display pending communication animation
  85. showCommsAnimation = true
  86. Task {
  87. await WatchLogger.shared.log("⌚️ showCommsAnimation = true")
  88. }
  89. }
  90. /// Sends a request to activate an override preset to the paired iPhone
  91. /// - Parameter presetName: The name of the override preset to activate
  92. func sendActivateOverrideRequest(presetName: String) {
  93. guard let session = session, session.isReachable else {
  94. Task {
  95. await WatchLogger.shared.log("⌚️ Activate override request aborted: session unreachable")
  96. }
  97. return
  98. }
  99. Task {
  100. await WatchLogger.shared.log("⌚️ Sending activate override request for preset: \(presetName)")
  101. }
  102. let message: [String: Any] = [
  103. WatchMessageKeys.activateOverride: presetName
  104. ]
  105. session.sendMessage(message, replyHandler: nil) { error in
  106. Task {
  107. await WatchLogger.shared.log("⌚️ Error sending activate override request: \(error.localizedDescription)")
  108. await WatchLogger.shared.log("⌚️ Saving logs to disk as fallback!")
  109. await WatchLogger.shared.persistLogsLocally()
  110. }
  111. }
  112. // Display pending communication animation
  113. showCommsAnimation = true
  114. Task {
  115. await WatchLogger.shared.log("⌚️ showCommsAnimation = true")
  116. }
  117. }
  118. /// Sends a request to cancel the current temporary target to the paired iPhone
  119. func sendCancelTempTargetRequest() {
  120. guard let session = session, session.isReachable else {
  121. Task {
  122. await WatchLogger.shared.log("⌚️ Cancel temp target request aborted: session unreachable")
  123. }
  124. return
  125. }
  126. Task {
  127. await WatchLogger.shared.log("⌚️ Sending cancel temp target request")
  128. }
  129. let message: [String: Any] = [
  130. WatchMessageKeys.cancelTempTarget: true
  131. ]
  132. session.sendMessage(message, replyHandler: nil) { error in
  133. Task {
  134. await WatchLogger.shared.log("⌚️ Error sending cancel temp target request: \(error.localizedDescription)")
  135. await WatchLogger.shared.log("⌚️ Saving logs to disk as fallback!")
  136. await WatchLogger.shared.persistLogsLocally()
  137. }
  138. }
  139. // Display pending communication animation
  140. showCommsAnimation = true
  141. Task {
  142. await WatchLogger.shared.log("⌚️ showCommsAnimation = true")
  143. }
  144. }
  145. /// Sends a request to activate a temporary target preset to the paired iPhone
  146. /// - Parameter presetName: The name of the temporary target preset to activate
  147. func sendActivateTempTargetRequest(presetName: String) {
  148. guard let session = session, session.isReachable else {
  149. Task {
  150. await WatchLogger.shared.log("⌚️ Activate temp target request aborted: session unreachable")
  151. }
  152. return
  153. }
  154. Task {
  155. await WatchLogger.shared.log("⌚️ Sending activate temp target request for preset: \(presetName)")
  156. }
  157. let message: [String: Any] = [
  158. WatchMessageKeys.activateTempTarget: presetName
  159. ]
  160. session.sendMessage(message, replyHandler: nil) { error in
  161. Task {
  162. await WatchLogger.shared.log("⌚️ Error sending activate temp target request: \(error.localizedDescription)")
  163. await WatchLogger.shared.log("⌚️ Saving logs to disk as fallback!")
  164. await WatchLogger.shared.persistLogsLocally()
  165. }
  166. }
  167. // Display pending communication animation
  168. showCommsAnimation = true
  169. Task {
  170. await WatchLogger.shared.log("⌚️ showCommsAnimation = true")
  171. }
  172. }
  173. /// Sends a request to calculate a bolus recommendation based on the current carbs amount
  174. func requestBolusRecommendation() {
  175. guard let session = session, session.isReachable else {
  176. Task {
  177. await WatchLogger.shared.log("⌚️ Bolus recommendation request aborted: session unreachable")
  178. }
  179. return
  180. }
  181. Task {
  182. await WatchLogger.shared.log("⌚️ Requesting bolus recommendation for carbs: \(carbsAmount)")
  183. }
  184. let message: [String: Any] = [
  185. WatchMessageKeys.requestBolusRecommendation: true,
  186. WatchMessageKeys.carbs: carbsAmount
  187. ]
  188. session.sendMessage(message, replyHandler: nil) { error in
  189. Task {
  190. await WatchLogger.shared.log("Error requesting bolus recommendation: \(error.localizedDescription)")
  191. await WatchLogger.shared.log("⌚️ Saving logs to disk as fallback!")
  192. await WatchLogger.shared.persistLogsLocally()
  193. }
  194. }
  195. }
  196. func requestWatchStateUpdate() {
  197. guard let session = session else {
  198. Task {
  199. await WatchLogger.shared.log("⌚️ No session available for state update")
  200. }
  201. return
  202. }
  203. guard session.activationState == .activated else {
  204. Task {
  205. await WatchLogger.shared.log("⌚️ Session not activated. Activating...")
  206. }
  207. session.activate()
  208. return
  209. }
  210. if session.isReachable {
  211. Task {
  212. await WatchLogger.shared.log("⌚️ Requesting WatchState update from iPhone")
  213. }
  214. let message = [WatchMessageKeys.requestWatchUpdate: WatchMessageKeys.watchState]
  215. session.sendMessage(message, replyHandler: nil) { error in
  216. Task {
  217. await WatchLogger.shared.log("⌚️ Error requesting WatchState update: \(error.localizedDescription)")
  218. await WatchLogger.shared.log("⌚️ Saving logs to disk as fallback!")
  219. await WatchLogger.shared.persistLogsLocally()
  220. }
  221. }
  222. } else {
  223. Task {
  224. await WatchLogger.shared.log("⌚️ Phone not reachable for WatchState update")
  225. }
  226. }
  227. }
  228. }