StoredCarbEntry.swift 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. //
  2. // StoredCarbEntry.swift
  3. // Naterade
  4. //
  5. // Created by Nathan Racklyeft on 1/22/16.
  6. // Copyright © 2016 Nathan Racklyeft. All rights reserved.
  7. //
  8. import HealthKit
  9. import CoreData
  10. public struct StoredCarbEntry: CarbEntry, Equatable {
  11. public let uuid: UUID?
  12. // MARK: - HealthKit Sync Support
  13. public let provenanceIdentifier: String
  14. public let syncIdentifier: String?
  15. public let syncVersion: Int?
  16. // MARK: - SampleValue
  17. public let startDate: Date
  18. public let quantity: HKQuantity
  19. // MARK: - CarbEntry
  20. public let foodType: String?
  21. public let absorptionTime: TimeInterval?
  22. public let createdByCurrentApp: Bool
  23. // MARK: - User dates
  24. public let userCreatedDate: Date?
  25. public let userUpdatedDate: Date?
  26. public init(
  27. uuid: UUID?,
  28. provenanceIdentifier: String,
  29. syncIdentifier: String?,
  30. syncVersion: Int?,
  31. startDate: Date,
  32. quantity: HKQuantity,
  33. foodType: String?,
  34. absorptionTime: TimeInterval?,
  35. createdByCurrentApp: Bool,
  36. userCreatedDate: Date?,
  37. userUpdatedDate: Date?
  38. ) {
  39. self.uuid = uuid
  40. self.provenanceIdentifier = provenanceIdentifier
  41. self.syncIdentifier = syncIdentifier
  42. self.syncVersion = syncVersion
  43. self.startDate = startDate
  44. self.quantity = quantity
  45. self.foodType = foodType
  46. self.absorptionTime = absorptionTime
  47. self.createdByCurrentApp = createdByCurrentApp
  48. self.userCreatedDate = userCreatedDate
  49. self.userUpdatedDate = userUpdatedDate
  50. }
  51. }
  52. extension StoredCarbEntry {
  53. init(managedObject: CachedCarbObject) {
  54. self.init(
  55. uuid: managedObject.uuid,
  56. provenanceIdentifier: managedObject.provenanceIdentifier,
  57. syncIdentifier: managedObject.syncIdentifier,
  58. syncVersion: managedObject.syncVersion,
  59. startDate: managedObject.startDate,
  60. quantity: managedObject.quantity,
  61. foodType: managedObject.foodType,
  62. absorptionTime: managedObject.absorptionTime,
  63. createdByCurrentApp: managedObject.createdByCurrentApp,
  64. userCreatedDate: managedObject.userCreatedDate,
  65. userUpdatedDate: managedObject.userUpdatedDate
  66. )
  67. }
  68. }
  69. extension StoredCarbEntry: Codable {
  70. public init(from decoder: Decoder) throws {
  71. let container = try decoder.container(keyedBy: CodingKeys.self)
  72. self.init(uuid: try container.decodeIfPresent(UUID.self, forKey: .uuid),
  73. provenanceIdentifier: try container.decode(String.self, forKey: .provenanceIdentifier),
  74. syncIdentifier: try container.decodeIfPresent(String.self, forKey: .syncIdentifier),
  75. syncVersion: try container.decodeIfPresent(Int.self, forKey: .syncVersion),
  76. startDate: try container.decode(Date.self, forKey: .startDate),
  77. quantity: HKQuantity(unit: .gram(), doubleValue: try container.decode(Double.self, forKey: .quantity)),
  78. foodType: try container.decodeIfPresent(String.self, forKey: .foodType),
  79. absorptionTime: try container.decodeIfPresent(TimeInterval.self, forKey: .absorptionTime),
  80. createdByCurrentApp: try container.decode(Bool.self, forKey: .createdByCurrentApp),
  81. userCreatedDate: try container.decodeIfPresent(Date.self, forKey: .userCreatedDate),
  82. userUpdatedDate: try container.decodeIfPresent(Date.self, forKey: .userUpdatedDate)
  83. )
  84. }
  85. public func encode(to encoder: Encoder) throws {
  86. var container = encoder.container(keyedBy: CodingKeys.self)
  87. try container.encodeIfPresent(uuid, forKey: .uuid)
  88. try container.encode(provenanceIdentifier, forKey: .provenanceIdentifier)
  89. try container.encodeIfPresent(syncIdentifier, forKey: .syncIdentifier)
  90. try container.encodeIfPresent(syncVersion, forKey: .syncVersion)
  91. try container.encode(startDate, forKey: .startDate)
  92. try container.encode(quantity.doubleValue(for: .gram()), forKey: .quantity)
  93. try container.encodeIfPresent(foodType, forKey: .foodType)
  94. try container.encodeIfPresent(absorptionTime, forKey: .absorptionTime)
  95. try container.encode(createdByCurrentApp, forKey: .createdByCurrentApp)
  96. try container.encodeIfPresent(userCreatedDate, forKey: .userCreatedDate)
  97. try container.encodeIfPresent(userUpdatedDate, forKey: .userUpdatedDate)
  98. }
  99. private enum CodingKeys: String, CodingKey {
  100. case uuid
  101. case provenanceIdentifier
  102. case syncIdentifier
  103. case syncVersion
  104. case startDate
  105. case quantity
  106. case foodType
  107. case absorptionTime
  108. case createdByCurrentApp
  109. case userCreatedDate
  110. case userUpdatedDate
  111. }
  112. }
  113. // MARK: - DEPRECATED - Used only for migration
  114. extension StoredCarbEntry {
  115. typealias RawValue = [String: Any]
  116. init?(rawValue: RawValue) {
  117. guard let
  118. sampleUUIDString = rawValue["sampleUUID"] as? String,
  119. let uuid = UUID(uuidString: sampleUUIDString),
  120. let startDate = rawValue["startDate"] as? Date,
  121. let unitString = rawValue["unitString"] as? String,
  122. let value = rawValue["value"] as? Double,
  123. let createdByCurrentApp = rawValue["createdByCurrentApp"] as? Bool else
  124. {
  125. return nil
  126. }
  127. var syncIdentifier: String?
  128. var syncVersion: Int?
  129. if let externalID = rawValue["externalId"] as? String {
  130. syncIdentifier = externalID
  131. syncVersion = 1
  132. }
  133. self.init(
  134. uuid: uuid,
  135. provenanceIdentifier: createdByCurrentApp ? HKSource.default().bundleIdentifier : "",
  136. syncIdentifier: syncIdentifier,
  137. syncVersion: syncVersion,
  138. startDate: startDate,
  139. quantity: HKQuantity(unit: HKUnit(from: unitString), doubleValue: value),
  140. foodType: rawValue["foodType"] as? String,
  141. absorptionTime: rawValue["absorptionTime"] as? TimeInterval,
  142. createdByCurrentApp: createdByCurrentApp,
  143. userCreatedDate: nil,
  144. userUpdatedDate: nil
  145. )
  146. }
  147. }