SettingsMigrationManager.swift 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // LoopFollow
  2. // SettingsMigrationManager.swift
  3. import Foundation
  4. class SettingsMigrationManager {
  5. // MARK: - Current Version
  6. static let currentVersion = "1.0"
  7. // MARK: - Migration Methods
  8. static func migrateSettings(_ data: Data) -> CombinedSettingsExport? {
  9. // Try to decode with the current version
  10. do {
  11. let currentSettings = try JSONDecoder().decode(CombinedSettingsExport.self, from: data)
  12. LogManager.shared.log(category: .general, message: "Successfully decoded CombinedSettingsExport", isDebug: true)
  13. return currentSettings
  14. } catch {
  15. LogManager.shared.log(category: .general, message: "Failed to decode CombinedSettingsExport: \(String(describing: type(of: error)))", isDebug: true)
  16. // Try to decode as individual components
  17. return tryDecodeIndividualComponents(data)
  18. }
  19. }
  20. private static func tryDecodeIndividualComponents(_ data: Data) -> CombinedSettingsExport? {
  21. // Try to decode as AlarmSettingsExport
  22. if let alarmSettings = try? JSONDecoder().decode(AlarmSettingsExport.self, from: data) {
  23. LogManager.shared.log(category: .general, message: "Successfully decoded as AlarmSettingsExport", isDebug: true)
  24. return CombinedSettingsExport(
  25. alarms: alarmSettings,
  26. exportType: "Alarm Settings"
  27. )
  28. }
  29. // Try to decode as NightscoutSettingsExport
  30. if let nightscoutSettings = try? JSONDecoder().decode(NightscoutSettingsExport.self, from: data) {
  31. LogManager.shared.log(category: .general, message: "Successfully decoded as NightscoutSettingsExport", isDebug: true)
  32. return CombinedSettingsExport(
  33. nightscout: nightscoutSettings,
  34. exportType: "Nightscout Settings"
  35. )
  36. }
  37. // Try to decode as DexcomSettingsExport
  38. if let dexcomSettings = try? JSONDecoder().decode(DexcomSettingsExport.self, from: data) {
  39. LogManager.shared.log(category: .general, message: "Successfully decoded as DexcomSettingsExport", isDebug: true)
  40. return CombinedSettingsExport(
  41. dexcom: dexcomSettings,
  42. exportType: "Dexcom Settings"
  43. )
  44. }
  45. // Try to decode as RemoteSettingsExport
  46. if let remoteSettings = try? JSONDecoder().decode(RemoteSettingsExport.self, from: data) {
  47. LogManager.shared.log(category: .general, message: "Successfully decoded as RemoteSettingsExport", isDebug: true)
  48. return CombinedSettingsExport(
  49. remote: remoteSettings,
  50. exportType: "Remote Settings"
  51. )
  52. }
  53. LogManager.shared.log(category: .general, message: "Failed to decode as any known component", isDebug: true)
  54. return nil
  55. }
  56. // MARK: - Version Compatibility
  57. static func isCompatibleVersion(_ version: String) -> Bool {
  58. let currentVersionComponents = currentVersion.split(separator: ".").compactMap { Int($0) }
  59. let importVersionComponents = version.split(separator: ".").compactMap { Int($0) }
  60. // For now, accept any version (can be made more strict later)
  61. return true
  62. }
  63. static func getCompatibilityMessage(for version: String) -> String {
  64. return "Settings from version \(version) may not be fully compatible with current version \(currentVersion). Some features may not work as expected."
  65. }
  66. // MARK: - Error Handling
  67. enum SettingsImportError: Error {
  68. case unsupportedVersion(String)
  69. case migrationFailed(String)
  70. case corruptedData
  71. case incompatibleAlarmFormat
  72. case unknownError
  73. }
  74. }