Explorar o código

Adopt new String(localized:'xxx') syntax; small fixes

Deniz Cengiz hai 1 ano
pai
achega
8d6b795ab1
Modificáronse 65 ficheiros con 1064 adicións e 502 borrados
  1. 6 6
      Model/Helper/CoreDataError.swift
  2. 1 1
      Trio/Sources/APS/CGM/AppGroupSource.swift
  3. 8 7
      Trio/Sources/APS/CGM/CGMType.swift
  4. 1 1
      Trio/Sources/APS/Storage/ContactImageStorage.swift
  5. 2 2
      Trio/Sources/APS/Storage/GlucoseStorage.swift
  6. 2 2
      Trio/Sources/APS/Storage/OverrideStorage.swift
  7. 4 4
      Trio/Sources/Helpers/BuildDetails.swift
  8. 4 4
      Trio/Sources/Helpers/HKUnit.swift
  9. 521 3
      Trio/Sources/Localizations/Main/Localizable.xcstrings
  10. 16 16
      Trio/Sources/Models/ContactTrickEntry.swift
  11. 2 2
      Trio/Sources/Models/ForecastDisplayType.swift
  12. 2 2
      Trio/Sources/Models/HbA1cDisplayUnit.swift
  13. 2 2
      Trio/Sources/Models/LockScreenView.swift
  14. 2 2
      Trio/Sources/Models/TimeInRangeChartStyle.swift
  15. 2 2
      Trio/Sources/Models/TotalInsulinDisplayType.swift
  16. 2 5
      Trio/Sources/Modules/Adjustments/AdjustmentsDataFlow.swift
  17. 2 2
      Trio/Sources/Modules/Adjustments/AdjustmentsStateModel+Extensions/AdjustmentsStateModel+Overrides.swift
  18. 2 2
      Trio/Sources/Modules/Adjustments/AdjustmentsStateModel+Extensions/AdjustmentsStateModel+TempTargets.swift
  19. 65 34
      Trio/Sources/Modules/AlgorithmAdvancedSettings/View/AlgorithmAdvancedSettingsRootView.swift
  20. 9 9
      Trio/Sources/Modules/AutosensSettings/View/AutosensSettingsRootView.swift
  21. 15 15
      Trio/Sources/Modules/BolusCalculatorConfig/View/BolusCalculatorConfigRootView.swift
  22. 4 4
      Trio/Sources/Modules/CGMSettings/View/CGMRootView.swift
  23. 11 11
      Trio/Sources/Modules/CalendarEventSettings/View/CalendarEventSettingsRootView.swift
  24. 6 6
      Trio/Sources/Modules/ContactImage/View/ContactImageHelpView.swift
  25. 17 23
      Trio/Sources/Modules/DataTable/DataTableDataFlow.swift
  26. 15 15
      Trio/Sources/Modules/DataTable/View/DataTableRootView.swift
  27. 28 26
      Trio/Sources/Modules/DynamicSettings/View/DynamicSettingsRootView.swift
  28. 12 12
      Trio/Sources/Modules/GeneralSettings/View/UnitsLimitsSettingsRootView.swift
  29. 26 26
      Trio/Sources/Modules/GlucoseNotificationSettings/View/GlucoseNotificationSettingsRootView.swift
  30. 5 5
      Trio/Sources/Modules/HealthKit/View/AppleHealthKitRootView.swift
  31. 2 2
      Trio/Sources/Modules/Home/View/Chart/ChartElements/SelectionPopoverView.swift
  32. 17 17
      Trio/Sources/Modules/Home/View/Chart/ChartLegendView.swift
  33. 2 2
      Trio/Sources/Modules/Home/View/Header/CurrentGlucoseView.swift
  34. 25 25
      Trio/Sources/Modules/Home/View/Header/LoopStatusHelpView.swift
  35. 1 1
      Trio/Sources/Modules/Home/View/Header/LoopView.swift
  36. 7 7
      Trio/Sources/Modules/Home/View/Header/PumpView.swift
  37. 14 13
      Trio/Sources/Modules/Home/View/HomeRootView.swift
  38. 6 6
      Trio/Sources/Modules/LiveActivitySettings/View/LiveActivitySettingsRootView.swift
  39. 4 4
      Trio/Sources/Modules/Main/MainStateModel.swift
  40. 23 21
      Trio/Sources/Modules/MealSettings/View/MealSettingsRootView.swift
  41. 3 3
      Trio/Sources/Modules/NightscoutConfig/View/NightscoutConfigRootView.swift
  42. 5 5
      Trio/Sources/Modules/NightscoutConfig/View/NightscoutFetchView.swift
  43. 7 7
      Trio/Sources/Modules/NightscoutConfig/View/NightscoutUploadView.swift
  44. 5 5
      Trio/Sources/Modules/NightscoutConfig/View/ProfileImport/ReviewInsulinActionView.swift
  45. 1 1
      Trio/Sources/Modules/PumpConfig/View/PumpConfigRootView.swift
  46. 5 5
      Trio/Sources/Modules/RemoteControlConfig/View/RemoteControlConfig.swift
  47. 28 26
      Trio/Sources/Modules/SMBSettings/View/SMBSettingsRootView.swift
  48. 1 1
      Trio/Sources/Modules/Settings/SettingItems.swift
  49. 7 7
      Trio/Sources/Modules/Settings/View/SettingsRootView.swift
  50. 7 7
      Trio/Sources/Modules/Settings/View/Subviews/NotificationsView.swift
  51. 1 1
      Trio/Sources/Modules/Settings/View/TidepoolStartView.swift
  52. 4 4
      Trio/Sources/Modules/ShortcutsConfig/View/ShortcutsConfigView.swift
  53. 5 5
      Trio/Sources/Modules/Snooze/View/SnoozeRootView.swift
  54. 18 10
      Trio/Sources/Modules/Stat/View/ChartsView.swift
  55. 1 1
      Trio/Sources/Modules/Stat/View/StatRootView.swift
  56. 16 12
      Trio/Sources/Modules/TargetBehavoir/View/TargetBehavoirRootView.swift
  57. 2 3
      Trio/Sources/Modules/Treatments/TreatmentsStateModel.swift
  58. 3 3
      Trio/Sources/Modules/Treatments/View/PopupView.swift
  59. 2 1
      Trio/Sources/Modules/Treatments/View/TreatmentsRootView.swift
  60. 17 17
      Trio/Sources/Modules/UserInterfaceSettings/View/UserInterfaceSettingsRootView.swift
  61. 5 5
      Trio/Sources/Modules/WatchConfig/View/WatchConfigAppleWatchView.swift
  62. 1 1
      Trio/Sources/Modules/WatchConfig/View/WatchConfigGarminView.swift
  63. 20 18
      Trio/Sources/Services/UserNotifications/UserNotificationsManager.swift
  64. 4 4
      Trio/Sources/Shortcuts/State/ListStateView.swift
  65. 1 1
      Trio/Sources/Shortcuts/State/StateIntentRequest.swift

+ 6 - 6
Model/Helper/CoreDataError.swift

@@ -13,17 +13,17 @@ extension CoreDataError: LocalizedError {
     var errorDescription: String? {
         switch self {
         case .creationError:
-            return NSLocalizedString("Failed to create a new object.", comment: "")
+            return String(localized: "Failed to create a new object.", comment: "")
         case .batchInsertError:
-            return NSLocalizedString("Failed to execute a batch insert request.", comment: "")
+            return String(localized: "Failed to execute a batch insert request.", comment: "")
         case .batchDeleteError:
-            return NSLocalizedString("Failed to execute a batch delete request.", comment: "")
+            return String(localized: "Failed to execute a batch delete request.", comment: "")
         case .persistentHistoryChangeError:
-            return NSLocalizedString("Failed to execute a persistent history change request.", comment: "")
+            return String(localized: "Failed to execute a persistent history change request.", comment: "")
         case let .unexpectedError(error):
-            return NSLocalizedString("Received unexpected error. \(error.localizedDescription)", comment: "")
+            return String(localized: "Received unexpected error. \(error.localizedDescription)", comment: "")
         case .fetchError:
-            return NSLocalizedString("Failed to fetch object \(DebuggingIdentifiers.failed).", comment: "")
+            return String(localized: "Failed to fetch object \(DebuggingIdentifiers.failed).", comment: "")
         }
     }
 }

+ 1 - 1
Trio/Sources/APS/CGM/AppGroupSource.swift

@@ -115,7 +115,7 @@ struct AppGroupSource: GlucoseSource {
     }
 
     func sourceInfo() -> [String: Any]? {
-        [GlucoseSourceKey.description.rawValue: "Group ID: \(Bundle.main.appGroupSuiteName ?? "Not set"))"]
+        [GlucoseSourceKey.description.rawValue: "Group ID: \(Bundle.main.appGroupSuiteName ?? String(localized: "Not set"))"]
     }
 }
 

+ 8 - 7
Trio/Sources/APS/CGM/CGMType.swift

@@ -18,7 +18,7 @@ enum CGMType: String, JSON, CaseIterable, Identifiable {
         case .xdrip:
             return "xDrip4iOS"
         case .simulator:
-            return NSLocalizedString("Glucose Simulator", comment: "Glucose Simulator CGM type")
+            return String(localized: "Glucose Simulator", comment: "Glucose Simulator CGM type")
         case .enlite:
             return "Medtronic Enlite"
         case .plugin:
@@ -52,20 +52,21 @@ enum CGMType: String, JSON, CaseIterable, Identifiable {
     var subtitle: String {
         switch self {
         case .none:
-            return NSLocalizedString("None", comment: "No CGM selected")
+            return String(localized: "None", comment: "No CGM selected")
         case .nightscout:
-            return NSLocalizedString("Uses your Nightscout as CGM", comment: "Online or internal server")
+            return String(localized: "Uses your Nightscout as CGM", comment: "Online or internal server")
         case .xdrip:
-            return NSLocalizedString(
+            return String(
+                localized:
                 "Using shared app group with external CGM app xDrip4iOS",
                 comment: "Shared app group xDrip4iOS"
             )
         case .simulator:
-            return NSLocalizedString("Glucose Simulator for Demo Only", comment: "Simple simulator")
+            return String(localized: "Glucose Simulator for Demo Only", comment: "Simple simulator")
         case .enlite:
-            return NSLocalizedString("Minilink transmitter", comment: "Minilink transmitter")
+            return String(localized: "Minilink transmitter", comment: "Minilink transmitter")
         case .plugin:
-            return NSLocalizedString("Plugin CGM", comment: "Plugin CGM")
+            return String(localized: "Plugin CGM", comment: "Plugin CGM")
         }
     }
 }

+ 1 - 1
Trio/Sources/APS/Storage/ContactImageStorage.swift

@@ -39,7 +39,7 @@ final class BaseContactImageStorage: ContactImageStorage, Injectable {
 
             return fetchedContactImageEntries.compactMap { entry in
                 ContactImageEntry(
-                    name: entry.name ?? "No name provided",
+                    name: entry.name ?? String(localized: "No name provided"),
                     layout: ContactImageLayout(rawValue: entry.layout ?? "Default") ?? .default,
                     ring: ContactImageLargeRing(rawValue: entry.ring ?? "Hidden") ?? .none,
                     primary: ContactImageValue(rawValue: entry.primary ?? "Glucose Reading") ?? .glucose,

+ 2 - 2
Trio/Sources/APS/Storage/GlucoseStorage.swift

@@ -538,9 +538,9 @@ enum GlucoseAlarm {
     var displayName: String {
         switch self {
         case .high:
-            return NSLocalizedString("LOWALERT!", comment: "LOWALERT!")
+            return String(localized: "LOWALERT!", comment: "LOWALERT!")
         case .low:
-            return NSLocalizedString("HIGHALERT!", comment: "HIGHALERT!")
+            return String(localized: "HIGHALERT!", comment: "HIGHALERT!")
         }
     }
 }

+ 2 - 2
Trio/Sources/APS/Storage/OverrideStorage.swift

@@ -225,7 +225,7 @@ final class BaseOverrideStorage: @preconcurrency OverrideStorage, Injectable {
                     eventType: OverrideStored.EventType.nsExercise,
                     createdAt: override.date ?? Date(),
                     enteredBy: NightscoutExercise.local,
-                    notes: override.name ?? "Custom Override",
+                    notes: override.name ?? String(localized: "Custom Override"),
                     id: UUID(uuidString: override.id ?? UUID().uuidString)
                 )
             }
@@ -256,7 +256,7 @@ final class BaseOverrideStorage: @preconcurrency OverrideStorage, Injectable {
                     eventType: OverrideStored.EventType.nsExercise,
                     createdAt: (overrideRun.startDate ?? overrideRun.override?.date) ?? Date(),
                     enteredBy: NightscoutExercise.local,
-                    notes: overrideRun.name ?? "Custom Override",
+                    notes: overrideRun.name ?? String(localized: "Custom Override"),
                     id: overrideRun.id
                 )
             }

+ 4 - 4
Trio/Sources/Helpers/BuildDetails.swift

@@ -27,8 +27,8 @@ class BuildDetails {
     }
 
     var branchAndSha: String {
-        let branch = dict["com-trio-branch"] as? String ?? "Unknown"
-        let sha = dict["com-trio-commit-sha"] as? String ?? "Unknown"
+        let branch = dict["com-trio-branch"] as? String ?? String(localized: "Unknown")
+        let sha = dict["com-trio-commit-sha"] as? String ?? String(localized: "Unknown")
         return "\(branch) \(sha)"
     }
 
@@ -75,9 +75,9 @@ class BuildDetails {
     // Expiration header based on build type
     var expirationHeaderString: String {
         if isTestFlightBuild() {
-            return "Beta (TestFlight) Expires"
+            return String(localized: "Beta (TestFlight) Expires")
         } else {
-            return "App Expires"
+            return String(localized: "App Expires")
         }
     }
 }

+ 4 - 4
Trio/Sources/Helpers/HKUnit.swift

@@ -44,13 +44,13 @@ extension HKUnit {
 
     var localizedShortUnitString: String {
         if self == HKUnit.millimolesPerLiter {
-            return NSLocalizedString("mmol/L", comment: "The short unit display string for millimoles of glucose per liter")
+            return String(localized: "mmol/L", comment: "The short unit display string for millimoles of glucose per liter")
         } else if self == .milligramsPerDeciliter {
-            return NSLocalizedString("mg/dL", comment: "The short unit display string for milligrams of glucose per decilter")
+            return String(localized: "mg/dL", comment: "The short unit display string for milligrams of glucose per decilter")
         } else if self == .internationalUnit() {
-            return NSLocalizedString("U", comment: "The short unit display string for international units of insulin")
+            return String(localized: "U", comment: "The short unit display string for international units of insulin")
         } else if self == .gram() {
-            return NSLocalizedString("g", comment: "The short unit display string for grams")
+            return String(localized: "g", comment: "The short unit display string for grams")
         } else {
             return String(describing: self)
         }

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 521 - 3
Trio/Sources/Localizations/Main/Localizable.xcstrings


+ 16 - 16
Trio/Sources/Models/ContactTrickEntry.swift

@@ -130,23 +130,23 @@ enum ContactImageValue: String, JSON, CaseIterable, Identifiable, Codable {
     var displayName: String {
         switch self {
         case .none:
-            return NSLocalizedString("None", comment: "")
+            return String(localized: "None", comment: "")
         case .glucose:
-            return NSLocalizedString("Glucose Reading", comment: "")
+            return String(localized: "Glucose Reading", comment: "")
         case .eventualBG:
-            return NSLocalizedString("Eventual Glucose", comment: "")
+            return String(localized: "Eventual Glucose", comment: "")
         case .delta:
-            return NSLocalizedString("Glucose Delta", comment: "")
+            return String(localized: "Glucose Delta", comment: "")
         case .trend:
-            return NSLocalizedString("Glucose Trend", comment: "")
+            return String(localized: "Glucose Trend", comment: "")
         case .lastLoopDate:
-            return NSLocalizedString("Last Loop Time", comment: "")
+            return String(localized: "Last Loop Time", comment: "")
         case .cob:
-            return NSLocalizedString("COB", comment: "")
+            return String(localized: "COB", comment: "")
         case .iob:
-            return NSLocalizedString("IOB", comment: "")
+            return String(localized: "IOB", comment: "")
         case .ring:
-            return NSLocalizedString("Loop Status", comment: "")
+            return String(localized: "Loop Status", comment: "")
         }
     }
 }
@@ -159,9 +159,9 @@ enum ContactImageLayout: String, JSON, CaseIterable, Identifiable, Codable {
     var displayName: String {
         switch self {
         case .default:
-            return NSLocalizedString("Default", comment: "")
+            return String(localized: "Default", comment: "")
         case .split:
-            return NSLocalizedString("Split", comment: "")
+            return String(localized: "Split", comment: "")
         }
     }
 }
@@ -178,15 +178,15 @@ enum ContactImageLargeRing: String, JSON, CaseIterable, Identifiable, Codable {
     var displayName: String {
         switch self {
         case .none:
-            return NSLocalizedString("Hidden", comment: "")
+            return String(localized: "Hidden", comment: "")
         case .loop:
-            return NSLocalizedString("Loop Status", comment: "")
+            return String(localized: "Loop Status", comment: "")
 //        case .iob:
-//            return NSLocalizedString("Insulin on Board (IOB)", comment: "")
+//            return String(localized: "Insulin on Board (IOB)", comment: "")
 //        case .cob:
-//            return NSLocalizedString("Carbs on Board (COB)", comment: "")
+//            return String(localized: "Carbs on Board (COB)", comment: "")
 //        case .iobcob:
-//            return NSLocalizedString("IOB + COB", comment: "")
+//            return String(localized: "IOB + COB", comment: "")
         }
     }
 }

+ 2 - 2
Trio/Sources/Models/ForecastDisplayType.swift

@@ -7,10 +7,10 @@ enum ForecastDisplayType: String, JSON, CaseIterable, Identifiable, Codable, Has
     var displayName: String {
         switch self {
         case .cone:
-            return NSLocalizedString("Cone", comment: "")
+            return String(localized: "Cone", comment: "")
 
         case .lines:
-            return NSLocalizedString("Lines", comment: "")
+            return String(localized: "Lines", comment: "")
         }
     }
 }

+ 2 - 2
Trio/Sources/Models/HbA1cDisplayUnit.swift

@@ -8,9 +8,9 @@ enum HbA1cDisplayUnit: String, JSON, CaseIterable, Identifiable, Codable, Hashab
     var displayName: String {
         switch self {
         case .percent:
-            return NSLocalizedString("Percent", comment: "")
+            return String(localized: "Percent", comment: "")
         case .mmolMol:
-            return NSLocalizedString("mmol/mol", comment: "")
+            return String(localized: "mmol/mol", comment: "")
         }
     }
 }

+ 2 - 2
Trio/Sources/Models/LockScreenView.swift

@@ -7,9 +7,9 @@ enum LockScreenView: String, JSON, CaseIterable, Identifiable, Codable, Hashable
     var displayName: String {
         switch self {
         case .simple:
-            return NSLocalizedString("Simple", comment: "")
+            return String(localized: "Simple", comment: "")
         case .detailed:
-            return NSLocalizedString("Detailed", comment: "")
+            return String(localized: "Detailed", comment: "")
         }
     }
 }

+ 2 - 2
Trio/Sources/Models/TimeInRangeChartStyle.swift

@@ -8,9 +8,9 @@ enum TimeInRangeChartStyle: String, JSON, CaseIterable, Identifiable, Codable, H
     var displayName: String {
         switch self {
         case .vertical:
-            return NSLocalizedString("Vertical", comment: "")
+            return String(localized: "Vertical", comment: "")
         case .horizontal:
-            return NSLocalizedString("Horizontal", comment: "")
+            return String(localized: "Horizontal", comment: "")
         }
     }
 }

+ 2 - 2
Trio/Sources/Models/TotalInsulinDisplayType.swift

@@ -14,9 +14,9 @@ enum TotalInsulinDisplayType: String, JSON, CaseIterable, Identifiable, Codable,
     var displayName: String {
         switch self {
         case .totalDailyDose:
-            return NSLocalizedString("TDD", comment: "")
+            return String(localized: "TDD", comment: "")
         case .totalInsulinInScope:
-            return NSLocalizedString("TINS", comment: "")
+            return String(localized: "TINS", comment: "")
         }
     }
 }

+ 2 - 5
Trio/Sources/Modules/Adjustments/AdjustmentsDataFlow.swift

@@ -11,15 +11,12 @@ enum Adjustments {
         var id: String { rawValue }
 
         var name: String {
-            var name: String = ""
             switch self {
             case .overrides:
-                name = "Overrides"
+                return String(localized: "Overrides", comment: "Selected Tab")
             case .tempTargets:
-                name = "Temp Targets"
+                return String(localized: "Temp Targets", comment: "Selected Tab")
             }
-
-            return NSLocalizedString(name, comment: "Selected Tab")
         }
     }
 }

+ 2 - 2
Trio/Sources/Modules/Adjustments/AdjustmentsStateModel+Extensions/AdjustmentsStateModel+Overrides.swift

@@ -224,7 +224,7 @@ extension Adjustments.StateModel {
 
             if let overrideToEdit = try viewContext.existingObject(with: firstID) as? OverrideStored {
                 currentActiveOverride = overrideToEdit
-                activeOverrideName = overrideToEdit.name ?? "Custom Override"
+                activeOverrideName = overrideToEdit.name ?? String(localized: "Custom Override")
             }
         } catch {
             debugPrint(
@@ -248,7 +248,7 @@ extension Adjustments.StateModel {
 
             if let overrideToEdit = try viewContext.existingObject(with: duplicateId) as? OverrideStored {
                 currentActiveOverride = overrideToEdit
-                activeOverrideName = overrideToEdit.name ?? "Custom Override"
+                activeOverrideName = overrideToEdit.name ?? String(localized: "Custom Override")
             }
         } catch {
             debugPrint(

+ 2 - 2
Trio/Sources/Modules/Adjustments/AdjustmentsStateModel+Extensions/AdjustmentsStateModel+TempTargets.swift

@@ -44,7 +44,7 @@ extension Adjustments.StateModel {
 
             if let tempTargetToEdit = try viewContext.existingObject(with: firstID) as? TempTargetStored {
                 currentActiveTempTarget = tempTargetToEdit
-                activeTempTargetName = tempTargetToEdit.name ?? "Custom Temp Target"
+                activeTempTargetName = tempTargetToEdit.name ?? String(localized: "Custom Temp Target")
                 tempTargetTarget = tempTargetToEdit.target?.decimalValue ?? 0
             }
         } catch {
@@ -333,7 +333,7 @@ extension Adjustments.StateModel {
             if let tempTargetToEdit = try viewContext.existingObject(with: duplidateId) as? TempTargetStored
             {
                 currentActiveTempTarget = tempTargetToEdit
-                activeTempTargetName = tempTargetToEdit.name ?? "Custom Temp Target"
+                activeTempTargetName = tempTargetToEdit.name ?? String(localized: "Custom Temp Target")
             }
         } catch {
             debugPrint(

+ 65 - 34
Trio/Sources/Modules/AlgorithmAdvancedSettings/View/AlgorithmAdvancedSettingsRootView.swift

@@ -38,13 +38,16 @@ extension AlgorithmAdvancedSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Max Daily Safety Multiplier", comment: "Max Daily Safety Multiplier")
+                            hintLabel = String(localized: "Max Daily Safety Multiplier", comment: "Max Daily Safety Multiplier")
                         }
                     ),
                     units: state.units,
                     type: .decimal("maxDailySafetyMultiplier"),
-                    label: NSLocalizedString("Max Daily Safety Multiplier", comment: "Max Daily Safety Multiplier"),
-                    miniHint: "Limits temporary basal rates to this percentage of your largest basal rate.",
+                    label: String(localized: "Max Daily Safety Multiplier", comment: "Max Daily Safety Multiplier"),
+                    miniHint: String(
+                        localized: "Limits temporary basal rates to this percentage of your largest basal rate.",
+                        comment: "Mini Hint for Max Daily Safety Multiplier"
+                    ),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: 300%").bold()
@@ -64,7 +67,8 @@ extension AlgorithmAdvancedSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString(
+                            hintLabel = String(
+                                localized:
                                 "Current Basal Safety Multiplier",
                                 comment: "Current Basal Safety Multiplier"
                             )
@@ -72,8 +76,11 @@ extension AlgorithmAdvancedSettings {
                     ),
                     units: state.units,
                     type: .decimal("currentBasalSafetyMultiplier"),
-                    label: NSLocalizedString("Current Basal Safety Multiplier", comment: "Current Basal Safety Multiplier"),
-                    miniHint: "Limits temporary basal rates to this percentage of the current basal rate.",
+                    label: String(localized: "Current Basal Safety Multiplier", comment: "Current Basal Safety Multiplier"),
+                    miniHint: String(
+                        localized: "Limits temporary basal rates to this percentage of the current basal rate.",
+                        comment: "Mini Hint for Current Basal Safety Multiplier"
+                    ),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: 400%").bold()
@@ -95,13 +102,16 @@ extension AlgorithmAdvancedSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Duration of Insulin Action"
+                            hintLabel = String(localized: "Duration of Insulin Action", comment: "Duration of Insulin Action")
                         }
                     ),
                     units: state.units,
                     type: .decimal("dia"),
-                    label: "Duration of Insulin Action",
-                    miniHint: "Number of hours insulin is active in your body.",
+                    label: String(localized: "Duration of Insulin Action", comment: "Duration of Insulin Action"),
+                    miniHint: String(
+                        localized: "Number of hours insulin is active in your body.",
+                        comment: "Mini Hint for Duration of Insulin Action"
+                    ),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: 10 hours").bold()
@@ -125,14 +135,17 @@ extension AlgorithmAdvancedSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Use Custom Peak Time", comment: "Use Custom Peak Time")
+                            hintLabel = String(localized: "Use Custom Peak Time", comment: "Use Custom Peak Time")
                         }
                     ),
                     units: state.units,
                     type: .conditionalDecimal("insulinPeakTime"),
-                    label: NSLocalizedString("Use Custom Peak Time", comment: "Use Custom Peak Time"),
-                    conditionalLabel: NSLocalizedString("Insulin Peak Time", comment: "Insulin Peak Time"),
-                    miniHint: "Set a custom time for peak insulin effect.",
+                    label: String(localized: "Use Custom Peak Time", comment: "Use Custom Peak Time"),
+                    conditionalLabel: String(localized: "Insulin Peak Time", comment: "Insulin Peak Time"),
+                    miniHint: String(
+                        localized: "Set a custom time for peak insulin effect.",
+                        comment: "Mini Hint for Insulin Peak Time"
+                    ),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: Set by Insulin Type").bold()
@@ -156,13 +169,16 @@ extension AlgorithmAdvancedSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Skip Neutral Temps", comment: "Skip Neutral Temps")
+                            hintLabel = String(localized: "Skip Neutral Temps", comment: "Skip Neutral Temps")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: NSLocalizedString("Skip Neutral Temps", comment: "Skip Neutral Temps"),
-                    miniHint: "Skip neutral temporary basal rates to reduce MDT pump alerts.",
+                    label: String(localized: "Skip Neutral Temps", comment: "Skip Neutral Temps"),
+                    miniHint: String(
+                        localized: "Skip neutral temporary basal rates to reduce MDT pump alerts.",
+                        comment: "Mini Hint for Skip Neutral Temps"
+                    ),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: OFF").bold()
@@ -183,13 +199,16 @@ extension AlgorithmAdvancedSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Unsuspend If No Temp", comment: "Unsuspend If No Temp")
+                            hintLabel = String(localized: "Unsuspend If No Temp", comment: "Unsuspend If No Temp")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: NSLocalizedString("Unsuspend If No Temp", comment: "Unsuspend If No Temp"),
-                    miniHint: "Resume pump automatically after suspension.",
+                    label: String(localized: "Unsuspend If No Temp", comment: "Unsuspend If No Temp"),
+                    miniHint: String(
+                        localized: "Resume pump automatically after suspension.",
+                        comment: "Mini Hint for Unsuspend If No Temp"
+                    ),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: OFF").bold()
@@ -208,13 +227,16 @@ extension AlgorithmAdvancedSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Suspend Zeros IOB", comment: "Suspend Zeros IOB")
+                            hintLabel = String(localized: "Suspend Zeros IOB", comment: "Suspend Zeros IOB")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: NSLocalizedString("Suspend Zeros IOB", comment: "Suspend Zeros IOB"),
-                    miniHint: "Clear temporary basal rates and reset IOB when suspended.",
+                    label: String(localized: "Suspend Zeros IOB", comment: "Suspend Zeros IOB"),
+                    miniHint: String(
+                        localized: "Clear temporary basal rates and reset IOB when suspended.",
+                        comment: "Mini Hint for Suspend Zeros IOB"
+                    ),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: OFF").bold()
@@ -236,12 +258,12 @@ extension AlgorithmAdvancedSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Min 5m Carb Impact", comment: "Min 5m Carb Impact")
+                            hintLabel = String(localized: "Min 5m Carb Impact", comment: "Min 5m Carb Impact")
                         }
                     ),
                     units: state.units,
                     type: .decimal("min5mCarbimpact"),
-                    label: NSLocalizedString("Min 5m Carb Impact", comment: "Min 5m Carb Impact"),
+                    label: String(localized: "Min 5m Carb Impact", comment: "Min 5m Carb Impact"),
                     miniHint: "Default impact of carb absorption over a 5 minute interval.",
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
@@ -265,13 +287,16 @@ extension AlgorithmAdvancedSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Remaining Carbs Percentage", comment: "Remaining Carbs Percentage")
+                            hintLabel = String(localized: "Remaining Carbs Percentage", comment: "Remaining Carbs Percentage")
                         }
                     ),
                     units: state.units,
                     type: .decimal("remainingCarbsFraction"),
-                    label: NSLocalizedString("Remaining Carbs Percentage", comment: "Remaining Carbs Percentage"),
-                    miniHint: "Percentage of carbs still available if no absorption is detected.",
+                    label: String(localized: "Remaining Carbs Percentage", comment: "Remaining Carbs Percentage"),
+                    miniHint: String(
+                        localized: "Percentage of carbs still available if no absorption is detected.",
+                        comment: "Mini Hint for Remaining Carbs Percentage"
+                    ),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: 100%").bold()
@@ -292,13 +317,16 @@ extension AlgorithmAdvancedSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Remaining Carbs Cap", comment: "Remaining Carbs Cap")
+                            hintLabel = String(localized: "Remaining Carbs Cap", comment: "Remaining Carbs Cap")
                         }
                     ),
                     units: state.units,
                     type: .decimal("remainingCarbsCap"),
-                    label: NSLocalizedString("Remaining Carbs Cap", comment: "Remaining Carbs Cap"),
-                    miniHint: "Maximum amount of carbs still available if no absorption is detected.",
+                    label: String(localized: "Remaining Carbs Cap", comment: "Remaining Carbs Cap"),
+                    miniHint: String(
+                        localized: "Maximum amount of carbs still available if no absorption is detected.",
+                        comment: "Mini hint for Remaining Carbs Cap"
+                    ),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: 90 g").bold()
@@ -319,13 +347,16 @@ extension AlgorithmAdvancedSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Noisy CGM Target Multiplier", comment: "Noisy CGM Target Multiplier")
+                            hintLabel = String(localized: "Noisy CGM Target Multiplier", comment: "Noisy CGM Target Multiplier")
                         }
                     ),
                     units: state.units,
                     type: .decimal("noisyCGMTargetMultiplier"),
-                    label: NSLocalizedString("Noisy CGM Target Increase", comment: "Noisy CGM Target Increase"),
-                    miniHint: "Percentage increase of glucose target when CGM is inconsistent.",
+                    label: String(localized: "Noisy CGM Target Increase", comment: "Noisy CGM Target Increase"),
+                    miniHint: String(
+                        localized: "Percentage increase of glucose target when CGM is inconsistent.",
+                        comment: "Mini Hint for Noisy CGM Target Increase"
+                    ),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: 130%").bold()
@@ -346,7 +377,7 @@ extension AlgorithmAdvancedSettings {
                     shouldDisplayHint: $shouldDisplayHint,
                     hintLabel: hintLabel ?? "",
                     hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                    sheetTitle: "Help"
+                    sheetTitle: String(localized: "Help", comment: "Help sheet title")
                 )
             }
             .scrollContentBackground(.hidden)

+ 9 - 9
Trio/Sources/Modules/AutosensSettings/View/AutosensSettingsRootView.swift

@@ -105,7 +105,7 @@ extension AutosensSettings {
                         Spacer()
                         Button(
                             action: {
-                                hintLabel = "Autosens"
+                                hintLabel = String(localized: "Autosens")
                                 selectedVerboseHint = AnyView(autosensVerboseHint)
                                 shouldDisplayHint.toggle()
                             },
@@ -134,12 +134,12 @@ extension AutosensSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Autosens Max", comment: "Autosens Max")
+                            hintLabel = String(localized: "Autosens Max", comment: "Autosens Max")
                         }
                     ),
                     units: state.units,
                     type: .decimal("autosensMax"),
-                    label: NSLocalizedString("Autosens Max", comment: "Autosens Max"),
+                    label: String(localized: "Autosens Max", comment: "Autosens Max"),
                     miniHint: "Upper limit of the Autosens Ratio.",
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
@@ -154,7 +154,7 @@ extension AutosensSettings {
                             "Tip: Increasing this value allows automatic adjustments of basal rates to be higher, ISF to be lower, and CR to be lower."
                         )
                     },
-                    headerText: "Glucose Deviations Algorithm"
+                    headerText: String(localized: "Glucose Deviations Algorithm")
                 )
 
                 SettingInputSection(
@@ -165,12 +165,12 @@ extension AutosensSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Autosens Min", comment: "Autosens Min")
+                            hintLabel = String(localized: "Autosens Min", comment: "Autosens Min")
                         }
                     ),
                     units: state.units,
                     type: .decimal("autosensMin"),
-                    label: NSLocalizedString("Autosens Min", comment: "Autosens Min"),
+                    label: String(localized: "Autosens Min", comment: "Autosens Min"),
                     miniHint: "Lower limit of the Autosens Ratio.",
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
@@ -195,12 +195,12 @@ extension AutosensSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Rewind Resets Autosens", comment: "Rewind Resets Autosens")
+                            hintLabel = String(localized: "Rewind Resets Autosens", comment: "Rewind Resets Autosens")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: NSLocalizedString("Rewind Resets Autosens", comment: "Rewind Resets Autosens"),
+                    label: String(localized: "Rewind Resets Autosens", comment: "Rewind Resets Autosens"),
                     miniHint: "Pump rewind initiates a reset in Autosens Ratio.",
                     verboseHint: VStack(alignment: .leading, spacing: 5) {
                         Text("Default: ON").bold()
@@ -226,7 +226,7 @@ extension AutosensSettings {
                     shouldDisplayHint: $shouldDisplayHint,
                     hintLabel: hintLabel ?? "",
                     hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                    sheetTitle: "Help"
+                    sheetTitle: String(localized: "Help", comment: "Help sheet title")
                 )
             }
             .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))

+ 15 - 15
Trio/Sources/Modules/BolusCalculatorConfig/View/BolusCalculatorConfigRootView.swift

@@ -41,12 +41,12 @@ extension BolusCalculatorConfig {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Display Meal Presets"
+                            hintLabel = String(localized: "Display Meal Presets")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: "Display Meal Presets",
+                    label: String(localized: "Display Meal Presets"),
                     miniHint: "Allow the creation of saved, preset meals.",
                     verboseHint: VStack(alignment: .leading, spacing: 10) {
                         Text("Default: ON").bold()
@@ -62,13 +62,13 @@ extension BolusCalculatorConfig {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Recommended Bolus Percentage"
+                            hintLabel = String(localized: "Recommended Bolus Percentage")
                         }
                     ),
                     units: state.units,
                     type: .decimal("overrideFactor"),
-                    label: "Recommended Bolus Percentage",
-                    miniHint: "Percentage of bolus suggested in bolus calculator.",
+                    label: String(localized: "Recommended Bolus Percentage"),
+                    miniHint: String(localized: "Percentage of bolus suggested in bolus calculator."),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: 80%").bold()
@@ -82,7 +82,7 @@ extension BolusCalculatorConfig {
                             "Tip: If you are a new Trio user, it is not advised to set this to 100% until you have verified that your core settings (basal rates, ISF, and CR) do not need adjusting."
                         )
                     },
-                    headerText: "Calculator Configuration"
+                    headerText: String(localized: "Calculator Configuration")
                 )
 
                 SettingInputSection(
@@ -93,14 +93,14 @@ extension BolusCalculatorConfig {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Fatty Meal"
+                            hintLabel = String(localized: "Fatty Meal")
                         }
                     ),
                     units: state.units,
                     type: .conditionalDecimal("fattyMealFactor"),
-                    label: "Enable Fatty Meal Option",
-                    conditionalLabel: "Fatty Meal Bolus Percentage",
-                    miniHint: "Add and set a bolus option for meals that absorb slowly.",
+                    label: String(localized: "Enable Fatty Meal Option"),
+                    conditionalLabel: String(localized: "Fatty Meal Bolus Percentage"),
+                    miniHint: String(localized: "Add and set a bolus option for meals that absorb slowly."),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: OFF").bold()
@@ -127,14 +127,14 @@ extension BolusCalculatorConfig {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Super Bolus"
+                            hintLabel = String(localized: "Super Bolus")
                         }
                     ),
                     units: state.units,
                     type: .conditionalDecimal("sweetMealFactor"),
-                    label: "Enable Super Bolus Option",
-                    conditionalLabel: "Super Bolus Percentage",
-                    miniHint: "Add and set a bolus option for meals that absorb quickly.",
+                    label: String(localized: "Enable Super Bolus Option"),
+                    conditionalLabel: String(localized: "Super Bolus Percentage"),
+                    miniHint: String(localized: "Add and set a bolus option for meals that absorb quickly."),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: OFF").bold()
@@ -160,7 +160,7 @@ extension BolusCalculatorConfig {
                     shouldDisplayHint: $shouldDisplayHint,
                     hintLabel: hintLabel ?? "",
                     hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                    sheetTitle: "Help"
+                    sheetTitle: String(localized: "Help", comment: "Help sheet title")
                 )
             }
             .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))

+ 4 - 4
Trio/Sources/Modules/CGMSettings/View/CGMRootView.swift

@@ -99,13 +99,13 @@ extension CGMSettings {
                             get: { selectedVerboseHint },
                             set: {
                                 selectedVerboseHint = $0.map { AnyView($0) }
-                                hintLabel = "Smooth Glucose Value"
+                                hintLabel = String(localized: "Smooth Glucose Value")
                             }
                         ),
                         units: state.units,
                         type: .boolean,
-                        label: "Smooth Glucose Value",
-                        miniHint: "Smooth CGM readings using Savitzky-Golay filtering.",
+                        label: String(localized: "Smooth Glucose Value"),
+                        miniHint: String(localized: "Smooth CGM readings using Savitzky-Golay filtering."),
                         verboseHint:
                         VStack(alignment: .leading, spacing: 10) {
                             Text("Default: OFF").bold()
@@ -192,7 +192,7 @@ extension CGMSettings {
                                 )
                             }
                         ),
-                        sheetTitle: "Help"
+                        sheetTitle: String(localized: "Help", comment: "Help sheet title")
                     )
                 }
                 .confirmationDialog("CGM Model", isPresented: $showCGMSelection) {

+ 11 - 11
Trio/Sources/Modules/CalendarEventSettings/View/CalendarEventSettingsRootView.swift

@@ -26,13 +26,13 @@ extension CalendarEventSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Create Events in Calendar"
+                            hintLabel = String(localized: "Create Events in Calendar")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: "Create Events in Calendar",
-                    miniHint: "Use calendar events to display current data.",
+                    label: String(localized: "Create Events in Calendar"),
+                    miniHint: String(localized: "Use calendar events to display current data."),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: OFF").bold()
@@ -47,7 +47,7 @@ extension CalendarEventSettings {
                         )
                         Text("Note: Once a new calendar event is created, the previous event will be deleted.")
                     },
-                    headerText: "Diabetes Data as Calendar Event"
+                    headerText: String(localized: "Diabetes Data as Calendar Event")
                 )
 
                 if state.calendarIDs.isNotEmpty, state.useCalendar {
@@ -69,13 +69,13 @@ extension CalendarEventSettings {
                             get: { selectedVerboseHint },
                             set: {
                                 selectedVerboseHint = $0.map { AnyView($0) }
-                                hintLabel = "Display Emojis as Labels"
+                                hintLabel = String(localized: "Display Emojis as Labels")
                             }
                         ),
                         units: state.units,
                         type: .boolean,
-                        label: "Display Emojis as Labels",
-                        miniHint: "Use emojis for calendar events. See hint for more details.",
+                        label: String(localized: "Display Emojis as Labels"),
+                        miniHint: String(localized: "Use emojis for calendar events. See hint for more details."),
                         verboseHint: VStack(alignment: .leading, spacing: 10) {
                             Text("Default: OFF").bold()
                             VStack(alignment: .leading, spacing: 5) {
@@ -104,13 +104,13 @@ extension CalendarEventSettings {
                             get: { selectedVerboseHint },
                             set: {
                                 selectedVerboseHint = $0.map { AnyView($0) }
-                                hintLabel = "Display IOB and COB"
+                                hintLabel = String(localized: "Display IOB and COB")
                             }
                         ),
                         units: state.units,
                         type: .boolean,
-                        label: "Display IOB and COB",
-                        miniHint: "Include IOB & COB in the calendar event data.",
+                        label: String(localized: "Display IOB and COB"),
+                        miniHint: String(localized: "Include IOB & COB in the calendar event data."),
                         verboseHint: VStack(alignment: .leading, spacing: 10) {
                             Text("Default: OFF").bold()
                             Text(
@@ -140,7 +140,7 @@ extension CalendarEventSettings {
                     shouldDisplayHint: $shouldDisplayHint,
                     hintLabel: hintLabel ?? "",
                     hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                    sheetTitle: "Help"
+                    sheetTitle: String(localized: "Help", comment: "Help sheet title")
                 )
             }
             .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))

+ 6 - 6
Trio/Sources/Modules/ContactImage/View/ContactImageHelpView.swift

@@ -8,20 +8,20 @@ struct ContactImageHelpView: View {
         NavigationStack {
             List {
                 DefinitionRow(
-                    term: "How Trio Manages Contact Images",
+                    term: String(localized: "How Trio Manages Contact Images"),
                     definition: Text(
                         "Trio will automatically assign a name like 'Trio 1' to any contact image you add, and a create an entry under your iOS Contacts. Use the 'Save' button at the bottom to save your customized contact image."
                     )
                 ).listRowBackground(Color.gray.opacity(0.1))
 
                 DefinitionRow(
-                    term: "Preview Contact Image",
+                    term: String(localized: "Preview Contact Image"),
                     definition: Text(
                         "See a live preview of your contact image design at the top of the screen. Changes made to styles, layouts, or settings are instantly reflected."
                     )
                 ).listRowBackground(Color.gray.opacity(0.1))
 
-                DefinitionRow(term: "Customize Layout and Style", definition: VStack(alignment: .leading) {
+                DefinitionRow(term: String(localized: "Customize Layout and Style"), definition: VStack(alignment: .leading) {
                     Text("Choose from multiple layout options using the Layout Picker in the 'Style' section.")
                     Text("Enable High Contrast Mode for better visibility in certain conditions.")
                     Text("Available Layouts:")
@@ -29,7 +29,7 @@ struct ContactImageHelpView: View {
                     Text("• Split: Divides values into two separate areas of same size.")
                 }).listRowBackground(Color.gray.opacity(0.1))
 
-                DefinitionRow(term: "Set Display Values", definition: VStack(alignment: .leading) {
+                DefinitionRow(term: String(localized: "Set Display Values"), definition: VStack(alignment: .leading) {
                     Text("Select what values to show on the contact image (e.g., glucose, trend, none) for the available slots:")
                     Text("• None: No value displayed.")
                     Text("• Glucose Reading: Current CGM provided glucose value.")
@@ -42,7 +42,7 @@ struct ContactImageHelpView: View {
                     Text("• Last Loop Time: Time of the last algorithm run.")
                 }).listRowBackground(Color.gray.opacity(0.1))
 
-                DefinitionRow(term: "Adjust Ring Settings", definition: VStack(alignment: .leading) {
+                DefinitionRow(term: String(localized: "Adjust Ring Settings"), definition: VStack(alignment: .leading) {
                     Text("Add visual Rings around the contact image to highlight information.")
                     Text("Fine-tune the ring’s Width and Gap to suit your design preferences.")
                     Text("Available Rings:")
@@ -50,7 +50,7 @@ struct ContactImageHelpView: View {
                     Text("• Loop Status: Indicates current loop status (green, yellow, red).")
                 }).listRowBackground(Color.gray.opacity(0.1))
 
-                DefinitionRow(term: "Customize Fonts", definition: VStack(alignment: .leading) {
+                DefinitionRow(term: String(localized: "Customize Fonts"), definition: VStack(alignment: .leading) {
                     Text("Select font size, weight, and width to match your style:")
                     Text("• Font Size: Adjust the main text size.")
                     Text("• Secondary Font Size: Adjust text size for values in split layouts.")

+ 17 - 23
Trio/Sources/Modules/DataTable/DataTableDataFlow.swift

@@ -15,19 +15,16 @@ enum DataTable {
         var id: String { rawValue }
 
         var name: String {
-            var name: String = ""
             switch self {
             case .treatments:
-                name = "Treatments"
+                return String(localized: "Treatments", comment: "History Mode")
             case .meals:
-                name = "Meals"
+                return String(localized: "Meals", comment: "History Mode")
             case .glucose:
-                name = "Glucose"
+                return String(localized: "Glucose", comment: "History Mode")
             case .adjustments:
-                name = "Adjustments"
+                return String(localized: "Adjustments", comment: "History Mode")
             }
-
-            return NSLocalizedString(name, comment: "History Mode")
         }
     }
 
@@ -41,25 +38,22 @@ enum DataTable {
         case resume
 
         var name: String {
-            var name: String = ""
             switch self {
             case .carbs:
-                name = "Carbs"
+                return String(localized: "Carbs", comment: "Treatment type")
             case .fpus:
-                name = "Protein / Fat"
+                return String(localized: "Protein / Fat", comment: "Treatment type")
             case .bolus:
-                name = "Bolus"
+                return String(localized: "Bolus", comment: "Treatment type")
             case .tempBasal:
-                name = "Temp Basal"
+                return String(localized: "Temp Basal", comment: "Treatment type")
             case .tempTarget:
-                name = "Temp Target"
+                return String(localized: "Temp Target", comment: "Treatment type")
             case .suspend:
-                name = "Suspend"
+                return String(localized: "Suspend", comment: "Treatment type")
             case .resume:
-                name = "Resume"
+                return String(localized: "Resume", comment: "Treatment type")
             }
-
-            return NSLocalizedString(name, comment: "Treatment type")
         }
     }
 
@@ -142,24 +136,24 @@ enum DataTable {
             switch type {
             case .carbs:
                 return numberFormatter
-                    .string(from: amount as NSNumber)! + NSLocalizedString(" g", comment: "gram of carbs")
+                    .string(from: amount as NSNumber)! + String(localized: " g", comment: "gram of carbs")
             case .fpus:
                 return numberFormatter
-                    .string(from: amount as NSNumber)! + NSLocalizedString(" g", comment: "gram of carb equilvalents")
+                    .string(from: amount as NSNumber)! + String(localized: " g", comment: "gram of carb equilvalents")
             case .bolus:
                 var bolusText = " "
                 if isSMB ?? false {}
                 else if isExternal ?? false {
-                    bolusText += NSLocalizedString("External", comment: "External Insulin")
+                    bolusText += String(localized: "External", comment: "External Insulin")
                 } else {
-                    bolusText += NSLocalizedString("Manual", comment: "Manual Bolus")
+                    bolusText += String(localized: "Manual", comment: "Manual Bolus")
                 }
 
                 return numberFormatter
-                    .string(from: amount as NSNumber)! + NSLocalizedString(" U", comment: "Insulin unit") + bolusText
+                    .string(from: amount as NSNumber)! + String(localized: " U", comment: "Insulin unit") + bolusText
             case .tempBasal:
                 return numberFormatter
-                    .string(from: amount as NSNumber)! + NSLocalizedString(" U/hr", comment: "Unit insulin per hour")
+                    .string(from: amount as NSNumber)! + String(localized: " U/hr", comment: "Unit insulin per hour")
             case .tempTarget:
                 var converted = amount
                 if units == .mmolL {

+ 15 - 15
Trio/Sources/Modules/DataTable/View/DataTableRootView.swift

@@ -227,7 +227,7 @@ extension DataTable {
             let overrides = overrideRunStored.map { override -> AdjustmentItem in
                 AdjustmentItem(
                     id: override.objectID,
-                    name: override.name ?? "Override",
+                    name: override.name ?? String(localized: "Override"),
                     startDate: override.startDate ?? Date(),
                     endDate: override.endDate ?? Date(),
                     target: override.target?.decimalValue,
@@ -238,7 +238,7 @@ extension DataTable {
             let tempTargets = tempTargetRunStored.map { tempTarget -> AdjustmentItem in
                 AdjustmentItem(
                     id: tempTarget.objectID,
-                    name: tempTarget.name ?? "Temp Target",
+                    name: tempTarget.name ?? String(localized: "Temp Target"),
                     startDate: tempTarget.startDate ?? Date(),
                     endDate: tempTarget.endDate ?? Date(),
                     target: tempTarget.target?.decimalValue,
@@ -367,7 +367,7 @@ extension DataTable {
                             ).tint(.red)
                         }
                         .alert(
-                            Text(NSLocalizedString(alertTitle, comment: "")),
+                            Text(alertTitle),
                             isPresented: $isRemoveHistoryItemAlertPresented
                         ) {
                             Button("Cancel", role: .cancel) {}
@@ -380,7 +380,7 @@ extension DataTable {
                                 state.invokeGlucoseDeletionTask(glucoseToDeleteObjectID)
                             }
                         } message: {
-                            Text("\n" + NSLocalizedString(alertMessage, comment: ""))
+                            Text("\n" + alertMessage)
                         }
                     }
                 } else {
@@ -482,18 +482,18 @@ extension DataTable {
                     Text(bolus.isSMB ? "SMB" : item.type ?? "Bolus")
                     Text(
                         (Formatter.decimalFormatterWithTwoFractionDigits.string(from: amount) ?? "0") +
-                            NSLocalizedString(" U", comment: "Insulin unit")
+                            String(localized: " U", comment: "Insulin unit")
                     )
                     .foregroundColor(.secondary)
                     if bolus.isExternal {
-                        Text(NSLocalizedString("External", comment: "External Insulin")).foregroundColor(.secondary)
+                        Text(String(localized: "External", comment: "External Insulin")).foregroundColor(.secondary)
                     }
                 } else if let tempBasal = item.tempBasal, let rate = tempBasal.rate {
                     Image(systemName: "circle.fill").foregroundColor(Color.insulin.opacity(0.4))
                     Text("Temp Basal")
                     Text(
                         (Formatter.decimalFormatterWithTwoFractionDigits.string(from: rate) ?? "0") +
-                            NSLocalizedString(" U/hr", comment: "Unit insulin per hour")
+                            String(localized: " U/hr", comment: "Unit insulin per hour")
                     )
                     .foregroundColor(.secondary)
                     if tempBasal.duration > 0 {
@@ -518,7 +518,7 @@ extension DataTable {
                             alertMessage = Formatter.dateFormatter
                                 .string(from: item.timestamp ?? Date()) + ", " +
                                 (Formatter.decimalFormatterWithTwoFractionDigits.string(from: item.bolus?.amount ?? 0) ?? "0") +
-                                NSLocalizedString(" U", comment: "Insulin unit")
+                                String(localized: " U", comment: "Insulin unit")
 
                             if let bolus = item.bolus {
                                 // Add text snippet, so that alert message is more descriptive for SMBs
@@ -531,7 +531,7 @@ extension DataTable {
                 }
             }
             .alert(
-                Text(NSLocalizedString(alertTitle, comment: "")),
+                Text(alertTitle),
                 isPresented: $isRemoveHistoryItemAlertPresented
             ) {
                 Button("Cancel", role: .cancel) {}
@@ -545,7 +545,7 @@ extension DataTable {
                     state.invokeInsulinDeletionTask(treatmentObjectID)
                 }
             } message: {
-                Text("\n" + NSLocalizedString(alertMessage, comment: ""))
+                Text("\n" + alertMessage)
             }
         }
 
@@ -557,14 +557,14 @@ extension DataTable {
                         Text("Fat / Protein")
                         Text(
                             (Formatter.decimalFormatterWithTwoFractionDigits.string(for: meal.carbs) ?? "0") +
-                                NSLocalizedString(" g", comment: "gram of carbs")
+                                String(localized: " g", comment: "gram of carbs")
                         )
                     } else {
                         Image(systemName: "circle.fill").foregroundColor(Color.loopYellow)
                         Text("Carbs")
                         Text(
                             (Formatter.decimalFormatterWithTwoFractionDigits.string(for: meal.carbs) ?? "0") +
-                                NSLocalizedString(" g", comment: "gram of carb equilvalents")
+                                String(localized: " g", comment: "gram of carb equilvalents")
                         )
                     }
 
@@ -595,7 +595,7 @@ extension DataTable {
                             alertMessage = Formatter.dateFormatter
                                 .string(from: meal.date ?? Date()) + ", " +
                                 (Formatter.decimalFormatterWithTwoFractionDigits.string(for: meal.carbs) ?? "0") +
-                                NSLocalizedString(" g", comment: "gram of carbs")
+                                String(localized: " g", comment: "gram of carbs")
                         }
                         // meal is complex-meal or fpu-only
                         else {
@@ -620,7 +620,7 @@ extension DataTable {
                 .disabled(!state.settingsManager.settings.useFPUconversion && meal.isFPU)
             }
             .alert(
-                Text(NSLocalizedString(alertTitle, comment: "")),
+                Text(alertTitle),
                 isPresented: $isRemoveHistoryItemAlertPresented
             ) {
                 Button("Cancel", role: .cancel) {}
@@ -637,7 +637,7 @@ extension DataTable {
                     )
                 }
             } message: {
-                Text("\n" + NSLocalizedString(alertMessage, comment: ""))
+                Text("\n" + alertMessage)
             }
         }
 

+ 28 - 26
Trio/Sources/Modules/DynamicSettings/View/DynamicSettingsRootView.swift

@@ -49,13 +49,15 @@ extension DynamicSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Activate Dynamic Sensitivity (Dynamic ISF)"
+                            hintLabel = String(localized: "Activate Dynamic Sensitivity (Dynamic ISF)")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: "Activate Dynamic ISF",
-                    miniHint: "Dynamically adjust insulin sensitivity using Dynamic Ratio rather than Autosens Ratio.",
+                    label: String(localized: "Activate Dynamic ISF"),
+                    miniHint: String(
+                        localized: "Dynamically adjust insulin sensitivity using Dynamic Ratio rather than Autosens Ratio."
+                    ),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: OFF").bold()
@@ -73,7 +75,7 @@ extension DynamicSettings {
                         )
                         .bold()
                     },
-                    headerText: "Dynamic Settings"
+                    headerText: String(localized: "Dynamic Settings")
                 )
 
                 if state.useNewFormula {
@@ -85,13 +87,13 @@ extension DynamicSettings {
                             get: { selectedVerboseHint },
                             set: {
                                 selectedVerboseHint = $0.map { AnyView($0) }
-                                hintLabel = "Activate Dynamic CR (Carb Ratio)"
+                                hintLabel = String(localized: "Activate Dynamic CR (Carb Ratio)")
                             }
                         ),
                         units: state.units,
                         type: .boolean,
-                        label: "Activate Dynamic CR (Carb Ratio)",
-                        miniHint: "Dynamically adjust your Carb Ratio (CR).",
+                        label: String(localized: "Activate Dynamic CR (Carb Ratio)"),
+                        miniHint: String(localized: "Dynamically adjust your Carb Ratio (CR)."),
                         verboseHint:
 
                         VStack(alignment: .leading, spacing: 10) {
@@ -116,13 +118,13 @@ extension DynamicSettings {
                             get: { selectedVerboseHint },
                             set: {
                                 selectedVerboseHint = $0.map { AnyView($0) }
-                                hintLabel = "Use Sigmoid Formula"
+                                hintLabel = String(localized: "Use Sigmoid Formula")
                             }
                         ),
                         units: state.units,
                         type: .boolean,
-                        label: "Use Sigmoid Formula",
-                        miniHint: "Adjust insulin sensitivity using a sigmoid-shaped curve.",
+                        label: String(localized: "Use Sigmoid Formula"),
+                        miniHint: String(localized: "Adjust insulin sensitivity using a sigmoid-shaped curve."),
                         verboseHint:
                         VStack(alignment: .leading, spacing: 10) {
                             Text("Default: OFF").bold()
@@ -152,14 +154,14 @@ extension DynamicSettings {
                                 get: { selectedVerboseHint },
                                 set: {
                                     selectedVerboseHint = $0.map { AnyView($0) }
-                                    hintLabel = "Adjustment Factor (AF)"
+                                    hintLabel = String(localized: "Adjustment Factor (AF)")
                                 }
                             ),
                             // TODO?: include conditional links to Desmos logarithmic graphs based on which .glucose setting is used
                             units: state.units,
                             type: .decimal("adjustmentFactor"),
-                            label: "Adjustment Factor (AF)",
-                            miniHint: "Alter the rate of Dynamic ISF (Sensitivity) adjustments.",
+                            label: String(localized: "Adjustment Factor (AF)"),
+                            miniHint: String(localized: "Alter the rate of Dynamic ISF (Sensitivity) adjustments."),
                             verboseHint:
                             VStack(alignment: .leading, spacing: 10) {
                                 Text("Default: 80%").bold()
@@ -183,13 +185,13 @@ extension DynamicSettings {
                                 get: { selectedVerboseHint },
                                 set: {
                                     selectedVerboseHint = $0.map { AnyView($0) }
-                                    hintLabel = "Sigmoid Adjustment Factor"
+                                    hintLabel = String(localized: "Sigmoid Adjustment Factor")
                                 }
                             ),
                             units: state.units,
                             type: .decimal("adjustmentFactorSigmoid"),
-                            label: "Sigmoid Adjustment Factor",
-                            miniHint: "Alter the rate of dynamic sensitivity adjustments for Sigmoid.",
+                            label: String(localized: "Sigmoid Adjustment Factor"),
+                            miniHint: String(localized: "Alter the rate of dynamic sensitivity adjustments for Sigmoid."),
                             verboseHint:
                             VStack(alignment: .leading, spacing: 10) {
                                 Text("Default: 50%").bold()
@@ -217,13 +219,13 @@ extension DynamicSettings {
                             get: { selectedVerboseHint },
                             set: {
                                 selectedVerboseHint = $0.map { AnyView($0) }
-                                hintLabel = "Weighted Average of TDD"
+                                hintLabel = String(localized: "Weighted Average of TDD")
                             }
                         ),
                         units: state.units,
                         type: .decimal("weightPercentage"),
-                        label: "Weighted Average of TDD",
-                        miniHint: "Weight of 24-hr TDD against 10-day TDD.",
+                        label: String(localized: "Weighted Average of TDD"),
+                        miniHint: String(localized: "Weight of 24-hr TDD against 10-day TDD."),
                         verboseHint:
                         VStack(alignment: .leading, spacing: 10) {
                             Text("Default: 35%").bold()
@@ -246,13 +248,13 @@ extension DynamicSettings {
                             get: { selectedVerboseHint },
                             set: {
                                 selectedVerboseHint = $0.map { AnyView($0) }
-                                hintLabel = "Adjust Basal"
+                                hintLabel = String(localized: "Adjust Basal")
                             }
                         ),
                         units: state.units,
                         type: .boolean,
-                        label: "Adjust Basal",
-                        miniHint: "Use Dynamic Ratio to adjust basal rates.",
+                        label: String(localized: "Adjust Basal"),
+                        miniHint: String(localized: "Use Dynamic Ratio to adjust basal rates."),
                         verboseHint: VStack(alignment: .leading, spacing: 10) {
                             Text("Default: OFF").bold()
                             Text(
@@ -274,13 +276,13 @@ extension DynamicSettings {
                             get: { selectedVerboseHint },
                             set: {
                                 selectedVerboseHint = $0.map { AnyView($0) }
-                                hintLabel = "Minimum Safety Threshold"
+                                hintLabel = String(localized: "Minimum Safety Threshold")
                             }
                         ),
                         units: state.units,
                         type: .decimal("threshold_setting"),
-                        label: "Minimum Safety Threshold",
-                        miniHint: "Increase the safety threshold used to suspend insulin delivery.",
+                        label: String(localized: "Minimum Safety Threshold"),
+                        miniHint: String(localized: "Increase the safety threshold used to suspend insulin delivery."),
                         verboseHint:
                         VStack(alignment: .leading, spacing: 10) {
                             Text("Default: Set by Algorithm").bold()
@@ -317,7 +319,7 @@ extension DynamicSettings {
                     shouldDisplayHint: $shouldDisplayHint,
                     hintLabel: hintLabel ?? "",
                     hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                    sheetTitle: "Help"
+                    sheetTitle: String(localized: "Help", comment: "Help sheet title")
                 )
             }
             .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))

+ 12 - 12
Trio/Sources/Modules/GeneralSettings/View/UnitsLimitsSettingsRootView.swift

@@ -36,12 +36,12 @@ extension UnitsLimitsSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Max IOB", comment: "Max IOB")
+                            hintLabel = String(localized: "Max IOB", comment: "Max IOB")
                         }
                     ),
                     units: state.units,
                     type: .decimal("maxIOB"),
-                    label: NSLocalizedString("Max IOB", comment: "Max IOB"),
+                    label: String(localized: "Max IOB", comment: "Max IOB"),
                     miniHint: "Maximum units of insulin allowed to be active.",
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
@@ -69,13 +69,13 @@ extension UnitsLimitsSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Max Bolus"
+                            hintLabel = String(localized: "Max Bolus")
                         }
                     ),
                     units: state.units,
                     type: .decimal("maxBolus"),
-                    label: "Max Bolus",
-                    miniHint: "Largest bolus of insulin allowed.",
+                    label: String(localized: "Max Bolus"),
+                    miniHint: String(localized: "Largest bolus of insulin allowed."),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: 10 units").bold()
@@ -95,13 +95,13 @@ extension UnitsLimitsSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Max Basal"
+                            hintLabel = String(localized: "Max Basal")
                         }
                     ),
                     units: state.units,
                     type: .decimal("maxBasal"),
-                    label: "Max Basal",
-                    miniHint: "Largest basal rate allowed.",
+                    label: String(localized: "Max Basal"),
+                    miniHint: String(localized: "Largest basal rate allowed."),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: 2 units").bold()
@@ -122,13 +122,13 @@ extension UnitsLimitsSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Max COB", comment: "Max COB")
+                            hintLabel = String(localized: "Max COB", comment: "Max COB")
                         }
                     ),
                     units: state.units,
                     type: .decimal("maxCOB"),
-                    label: NSLocalizedString("Max COB", comment: "Max COB"),
-                    miniHint: "Maximum Carbs On Board (COB) allowed.",
+                    label: String(localized: "Max COB", comment: "Max COB"),
+                    miniHint: String(localized: "Maximum Carbs On Board (COB) allowed."),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: 120 grams of carbs").bold()
@@ -149,7 +149,7 @@ extension UnitsLimitsSettings {
                     shouldDisplayHint: $shouldDisplayHint,
                     hintLabel: hintLabel ?? "",
                     hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                    sheetTitle: "Help"
+                    sheetTitle: String(localized: "Help", comment: "Help sheet title")
                 )
             }
             .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))

+ 26 - 26
Trio/Sources/Modules/GlucoseNotificationSettings/View/GlucoseNotificationSettingsRootView.swift

@@ -48,13 +48,13 @@ extension GlucoseNotificationSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Play Alarm Sound"
+                            hintLabel = String(localized: "Play Alarm Sound")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: "Play Alarm Sound",
-                    miniHint: "Alarm with every Trio notification.",
+                    label: String(localized: "Play Alarm Sound"),
+                    miniHint: String(localized: "Alarm with every Trio notification."),
                     verboseHint: VStack(alignment: .leading, spacing: 10) {
                         Text("Default: OFF").bold()
                         Text(
@@ -70,13 +70,13 @@ extension GlucoseNotificationSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Always Notify Pump"
+                            hintLabel = String(localized: "Always Notify Pump")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: "Always Notify Pump",
-                    miniHint: "Always Notify Pump Warnings.",
+                    label: String(localized: "Always Notify Pump"),
+                    miniHint: String(localized: "Always Notify Pump Warnings."),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: ON").bold()
@@ -86,7 +86,7 @@ extension GlucoseNotificationSettings {
                         Text("If iOS Trio Notifications is disabled, Trio will display these messages in-app as a banner only.")
                         Text("An example of a Pump Warning is 'Pod Expiration Reminder'")
                     },
-                    headerText: "Trio Information Notifications"
+                    headerText: String(localized: "Trio Information Notifications")
                 )
                 SettingInputSection(
                     decimalValue: $decimalPlaceholder,
@@ -96,13 +96,13 @@ extension GlucoseNotificationSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Always Notify CGM"
+                            hintLabel = String(localized: "Always Notify CGM")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: "Always Notify CGM",
-                    miniHint: "Always Notify CGM Warnings.",
+                    label: String(localized: "Always Notify CGM"),
+                    miniHint: String(localized: "Always Notify CGM Warnings."),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: ON").bold()
@@ -121,13 +121,13 @@ extension GlucoseNotificationSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Always Notify Carb"
+                            hintLabel = String(localized: "Always Notify Carb")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: "Always Notify Carb",
-                    miniHint: "Always Notify Carb Warnings.",
+                    label: String(localized: "Always Notify Carb"),
+                    miniHint: String(localized: "Always Notify Carb Warnings."),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: ON").bold()
@@ -146,13 +146,13 @@ extension GlucoseNotificationSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Always Notify Algorithm"
+                            hintLabel = String(localized: "Always Notify Algorithm")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: "Always Notify Algorithm",
-                    miniHint: "Always Notify Algorithm Warnings.",
+                    label: String(localized: "Always Notify Algorithm"),
+                    miniHint: String(localized: "Always Notify Algorithm Warnings."),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: ON").bold()
@@ -174,20 +174,20 @@ extension GlucoseNotificationSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Show Glucose App Badge"
+                            hintLabel = String(localized: "Show Glucose App Badge")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: "Show Glucose App Badge",
-                    miniHint: "Show your current glucose on Trio app icon.",
+                    label: String(localized: "Show Glucose App Badge"),
+                    miniHint: String(localized: "Show your current glucose on Trio app icon."),
                     verboseHint: VStack(alignment: .leading, spacing: 10) {
                         Text("Default: OFF").bold()
                         Text(
                             "This will add your current glucose on the top right of your Trio icon as a red notification badge. Changing setting takes effect on next Glucose reading."
                         )
                     },
-                    headerText: "Various Glucose Notifications"
+                    headerText: String(localized: "Various Glucose Notifications")
                 )
 
                 Section {
@@ -211,7 +211,7 @@ extension GlucoseNotificationSettings {
                             Spacer()
                             Button(
                                 action: {
-                                    hintLabel = "Glucose Notifications"
+                                    hintLabel = String(localized: "Glucose Notifications")
                                     selectedVerboseHint =
                                         AnyView(
                                             VStack(alignment: .leading, spacing: 10) {
@@ -258,13 +258,13 @@ extension GlucoseNotificationSettings {
                             get: { selectedVerboseHint },
                             set: {
                                 selectedVerboseHint = $0.map { AnyView($0) }
-                                hintLabel = "Add Glucose Source to Alarm"
+                                hintLabel = String(localized: "Add Glucose Source to Alarm")
                             }
                         ),
                         units: state.units,
                         type: .boolean,
-                        label: "Add Glucose Source to Alarm",
-                        miniHint: "Source of the glucose reading will be added to the notification.",
+                        label: String(localized: "Add Glucose Source to Alarm"),
+                        miniHint: String(localized: "Source of the glucose reading will be added to the notification."),
                         verboseHint: VStack(alignment: .leading, spacing: 10) {
                             Text("Default: OFF").bold()
                             Text("The source of the glucose reading will be added to the notification.")
@@ -279,7 +279,7 @@ extension GlucoseNotificationSettings {
                     shouldDisplayHint: $shouldDisplayHint,
                     hintLabel: hintLabel ?? "",
                     hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                    sheetTitle: "Help"
+                    sheetTitle: String(localized: "Help", comment: "Help sheet title")
                 )
             }
             .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))
@@ -374,7 +374,7 @@ extension GlucoseNotificationSettings {
                         Spacer()
                         Button(
                             action: {
-                                hintLabel = "Low and High Glucose Alarm Limits"
+                                hintLabel = String(localized: "Low and High Glucose Alarm Limits")
                                 selectedVerboseHint =
                                     AnyView(VStack(alignment: .leading, spacing: 10) {
                                         let low: Decimal = 70

+ 5 - 5
Trio/Sources/Modules/HealthKit/View/AppleHealthKitRootView.swift

@@ -26,20 +26,20 @@ extension AppleHealthKit {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Connect to Apple Health"
+                            hintLabel = String(localized: "Connect to Apple Health")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: "Connect to Apple Health",
-                    miniHint: "Allow Trio to read from and write to Apple Health.",
+                    label: String(localized: "Connect to Apple Health"),
+                    miniHint: String(localized: "Allow Trio to read from and write to Apple Health."),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: OFF").bold()
                         Text("This allows Trio to read from and write to Apple Health.")
                         Text("Warning: You must also give permissions in iOS System Settings for the Health app.").bold()
                     },
-                    headerText: "Apple Health Integration"
+                    headerText: String(localized: "Apple Health Integration")
                 )
 
                 if !state.needShowInformationTextForSetPermissions {
@@ -71,7 +71,7 @@ extension AppleHealthKit {
                     shouldDisplayHint: $shouldDisplayHint,
                     hintLabel: hintLabel ?? "",
                     hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                    sheetTitle: "Help"
+                    sheetTitle: String(localized: "Help", comment: "Help sheet title")
                 )
             }
             .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))

+ 2 - 2
Trio/Sources/Modules/Home/View/Chart/ChartElements/SelectionPopoverView.swift

@@ -80,7 +80,7 @@ struct SelectionPopoverView: ChartContent {
                     Image(systemName: "syringe.fill").frame(width: 15)
                     Text(Formatter.bolusFormatter.string(from: iob) ?? "")
                         .bold()
-                        + Text(NSLocalizedString(" U", comment: "Insulin unit"))
+                        + Text(String(localized: " U", comment: "Insulin unit"))
                 }
                 .foregroundStyle(Color.insulin).font(.body)
             }
@@ -90,7 +90,7 @@ struct SelectionPopoverView: ChartContent {
                     Image(systemName: "fork.knife").frame(width: 15)
                     Text(Formatter.integerFormatter.string(from: selectedCOBValue.cob as NSNumber) ?? "")
                         .bold()
-                        + Text(NSLocalizedString(" g", comment: "gram of carbs"))
+                        + Text(String(localized: " g", comment: "gram of carbs"))
                 }
                 .foregroundStyle(Color.orange).font(.body)
             }

+ 17 - 17
Trio/Sources/Modules/Home/View/Chart/ChartLegendView.swift

@@ -38,7 +38,7 @@ struct ChartLegendView: View {
                         Text("Other Elements & Shapes").bold().padding(.bottom, 5).textCase(.uppercase)
 
                         DefinitionRow(
-                            term: "Scheduled Basal Rate",
+                            term: String(localized: "Scheduled Basal Rate"),
                             definition: VStack(alignment: .leading, spacing: 10) {
                                 Text("This dotted line represents the hourly insulin rate of your scheduled basal insulin.")
                                 Text("To review or change your scheduled basal rates, go to Settings > Therapy > Basal Rates.")
@@ -48,7 +48,7 @@ struct ChartLegendView: View {
                         )
 
                         DefinitionRow(
-                            term: "Temporary Basal Rate (TBR)",
+                            term: String(localized: "Temporary Basal Rate (TBR)"),
                             definition: Text(
                                 "Shows current or past TBRs, which can be set by the oref algorithm or manually."
                             ),
@@ -57,14 +57,14 @@ struct ChartLegendView: View {
                         )
 
                         DefinitionRow(
-                            term: "Pump Suspension",
+                            term: String(localized: "Pump Suspension"),
                             definition: Text("Indicates when insulin delivery was paused, i.e. pump is suspended."),
                             color: Color.loopGray.opacity(colorScheme == .dark ? 0.3 : 0.8),
                             iconString: "square.fill"
                         )
 
                         DefinitionRow(
-                            term: "CGM Glucose Value",
+                            term: String(localized: "CGM Glucose Value"),
                             definition: VStack(alignment: .leading, spacing: 10) {
                                 if state.settingsManager.settings.smoothGlucose {
                                     Text(
@@ -92,14 +92,14 @@ struct ChartLegendView: View {
                         )
 
                         DefinitionRow(
-                            term: "Manual Glucose Measurement",
+                            term: String(localized: "Manual Glucose Measurement"),
                             definition: Text("Manually entered blood glucose, such as a fingerstick test."),
                             color: Color.red,
                             iconString: "drop.fill"
                         )
 
                         DefinitionRow(
-                            term: "Bolus",
+                            term: String(localized: "Bolus"),
                             definition: Text(
                                 "Shows an insulin dose, which can be a small automated dose (super-micro-bolus), a manually entered dose, or one given externally (e.g., a pen shot)."
                             ),
@@ -108,7 +108,7 @@ struct ChartLegendView: View {
                         )
 
                         DefinitionRow(
-                            term: "Carb Entry",
+                            term: String(localized: "Carb Entry"),
                             definition: Text("Tracks the carbohydrates you eat, entered to guide insulin dosing."),
                             color: Color.orange,
                             iconString: "arrowtriangle.down.fill",
@@ -116,7 +116,7 @@ struct ChartLegendView: View {
                         )
 
                         DefinitionRow(
-                            term: "Fat-Protein Carb Equivalent",
+                            term: String(localized: "Fat-Protein Carb Equivalent"),
                             definition: VStack(alignment: .leading, spacing: 10) {
                                 Text(
                                     "Represents carb equivalent for fat and protein, calculated using the Warsaw Method."
@@ -130,7 +130,7 @@ struct ChartLegendView: View {
                         )
 
                         DefinitionRow(
-                            term: "Override",
+                            term: String(localized: "Override"),
                             definition: Text(
                                 "Indicates when an override is or was active, temporarily changing therapy settings (e.g., basal rate, insulin sensitivity, carb ratio, target glucose, or whether Trio can dose SMBs)."
                             ),
@@ -139,7 +139,7 @@ struct ChartLegendView: View {
                         )
 
                         DefinitionRow(
-                            term: "Temporary Target",
+                            term: String(localized: "Temporary Target"),
                             definition: Text(
                                 "Marks when a short-term temporary glucose target is or was active, (potentially) altering when or how much insulin is delivered."
                             ),
@@ -148,7 +148,7 @@ struct ChartLegendView: View {
                         )
 
                         DefinitionRow(
-                            term: "Past Insulin-on-Board (IOB)",
+                            term: String(localized: "Past Insulin-on-Board (IOB)"),
                             definition: Text(
                                 "Shows the IOB value calculated by the algorithm at a specific time in the past. These values are snapshots and won’t change if insulin is added or removed after the fact."
                             ),
@@ -157,7 +157,7 @@ struct ChartLegendView: View {
                         )
 
                         DefinitionRow(
-                            term: "Past Carbs-on-Board (COB)",
+                            term: String(localized: "Past Carbs-on-Board (COB)"),
                             definition: Text(
                                 "Shows the COB value calculated by the algorithm at a specific time in the past. These values are snapshots and won’t change if carbs are added or removed after the fact."
                             ),
@@ -192,7 +192,7 @@ struct ChartLegendView: View {
     var legendLinesView: some View {
         Group {
             DefinitionRow(
-                term: "IOB (Insulin on Board)",
+                term: String(localized: "IOB (Insulin on Board)"),
                 definition: Text(
                     "Forecasts future glucose readings based on the amount of insulin still active in the body."
                 ),
@@ -200,7 +200,7 @@ struct ChartLegendView: View {
             )
 
             DefinitionRow(
-                term: "ZT (Zero-Temp)",
+                term: String(localized: "ZT (Zero-Temp)"),
                 definition: Text(
                     "Forecasts the worst-case future glucose reading scenario if no carbs are absorbed and insulin delivery is stopped until glucose starts rising."
                 ),
@@ -208,7 +208,7 @@ struct ChartLegendView: View {
             )
 
             DefinitionRow(
-                term: "COB (Carbs on Board)",
+                term: String(localized: "COB (Carbs on Board)"),
                 definition: Text(
                     "Forecasts future glucose reading changes by considering the amount of carbohydrates still being absorbed in the body."
                 ),
@@ -216,7 +216,7 @@ struct ChartLegendView: View {
             )
 
             DefinitionRow(
-                term: "UAM (Unannounced Meal)",
+                term: String(localized: "UAM (Unannounced Meal)"),
                 definition: Text(
                     "Forecasts future glucose levels and insulin dosing needs for unexpected meals or other causes of glucose reading increases without prior notice."
                 ),
@@ -227,7 +227,7 @@ struct ChartLegendView: View {
 
     var legendConeOfUncertaintyView: some View {
         DefinitionRow(
-            term: "Cone of Uncertainty",
+            term: String(localized: "Cone of Uncertainty"),
             definition: VStack(alignment: .leading, spacing: 10) {
                 Text(
                     "For simplicity reasons, oref's various forecast curves are displayed as a \"Cone of Uncertainty\" that depicts a possible, forecasted range of future glucose fluctuation based on the current data and the algothim's result."

+ 2 - 2
Trio/Sources/Modules/Home/View/Header/CurrentGlucoseView.swift

@@ -93,9 +93,9 @@ struct CurrentGlucoseView: View {
                         let minutesAgo = -1 * (glucose.last?.date?.timeIntervalSinceNow ?? 0) / 60
                         let text = timaAgoFormatter.string(for: Double(minutesAgo)) ?? ""
                         Text(
-                            minutesAgo <= 1 ? "< 1 " + NSLocalizedString("min", comment: "Short form for minutes") : (
+                            minutesAgo <= 1 ? "< 1 " + String(localized: "min", comment: "Short form for minutes") : (
                                 text + " " +
-                                    NSLocalizedString("min", comment: "Short form for minutes") + " "
+                                    String(localized: "min", comment: "Short form for minutes") + " "
                             )
                         )
                         .font(.caption2).foregroundStyle(colorScheme == .dark ? Color.white.opacity(0.9) : Color.secondary)

+ 25 - 25
Trio/Sources/Modules/Home/View/Header/LoopStatusHelpView.swift

@@ -20,7 +20,7 @@ struct LoopStatusHelpView: View {
 
                 List {
                     DefinitionRow(
-                        term: "Autosens Ratio",
+                        term: String(localized: "Autosens Ratio"),
                         definition: Text(
                             "The ratio of how sensitive or resistant to insulin you are in the current loop cycle. Baseline = 1.0, Sensitive < 1.0, Resistant > 1.0"
                         ),
@@ -28,7 +28,7 @@ struct LoopStatusHelpView: View {
                     ).listRowBackground(Color.gray.opacity(0.1))
 
                     DefinitionRow(
-                        term: "ISF",
+                        term: String(localized: "ISF"),
                         definition: Text(
                             "The first value is your profile Insulin Sensitivity Factor (ISF). The second value, after the arrow, is your adjusted ISF used for the most recent automated dosing calculation."
                         ),
@@ -36,7 +36,7 @@ struct LoopStatusHelpView: View {
                     ).listRowBackground(Color.gray.opacity(0.1))
 
                     DefinitionRow(
-                        term: "COB",
+                        term: String(localized: "COB"),
                         definition: Text(
                             "Amount of Carbs on Board (COB) used in the most recent automated dosing calculation."
                         ),
@@ -44,7 +44,7 @@ struct LoopStatusHelpView: View {
                     ).listRowBackground(Color.gray.opacity(0.1))
 
                     DefinitionRow(
-                        term: "Dev",
+                        term: String(localized: "Dev"),
                         definition: Text(
                             "Abbreviation for 'Deviation'. How much the actual glucose change deviated from the BGI."
                         ),
@@ -52,7 +52,7 @@ struct LoopStatusHelpView: View {
                     ).listRowBackground(Color.gray.opacity(0.1))
 
                     DefinitionRow(
-                        term: "BGI",
+                        term: String(localized: "BGI"),
                         definition: Text(
                             "The degree to which your glucose should be rising or falling based solely on insulin activity."
                         ),
@@ -60,7 +60,7 @@ struct LoopStatusHelpView: View {
                     ).listRowBackground(Color.gray.opacity(0.1))
 
                     DefinitionRow(
-                        term: "CR",
+                        term: String(localized: "CR"),
                         definition: Text(
                             "The first value is your profile Carb Ratio (CR). The second value, after the arrow, is your adjusted CR used for the most recent automated dosing calculation."
                         ),
@@ -68,7 +68,7 @@ struct LoopStatusHelpView: View {
                     ).listRowBackground(Color.gray.opacity(0.1))
 
                     DefinitionRow(
-                        term: "Target",
+                        term: String(localized: "Target"),
                         definition: Text(
                             "The first value is your target glucose from your settings. The second value, after the arrow, is your adjusted target glucose used for the most recent automated dosing calculation. A second value is shown if you have a temp target, override, or one of the Target Behavior options enabled."
                         ),
@@ -76,7 +76,7 @@ struct LoopStatusHelpView: View {
                     ).listRowBackground(Color.gray.opacity(0.1))
 
                     DefinitionRow(
-                        term: "minPredBG",
+                        term: String(localized: "minPredBG"),
                         definition: Text(
                             "The lowest forecasted value that Trio has estimated for your future glucose."
                         ),
@@ -84,7 +84,7 @@ struct LoopStatusHelpView: View {
                     ).listRowBackground(Color.gray.opacity(0.1))
 
                     DefinitionRow(
-                        term: "minGuardBG",
+                        term: String(localized: "minGuardBG"),
                         definition: Text(
                             "The lowest forecasted glucose during the remaining duration of insulin action (DIA)."
                         ),
@@ -92,7 +92,7 @@ struct LoopStatusHelpView: View {
                     ).listRowBackground(Color.gray.opacity(0.1))
 
                     DefinitionRow(
-                        term: "IOBpredBG",
+                        term: String(localized: "IOBpredBG"),
                         definition: Text(
                             "The forecasted glucose value in 4 hours calculated based on IOB only."
                         ),
@@ -100,7 +100,7 @@ struct LoopStatusHelpView: View {
                     ).listRowBackground(Color.gray.opacity(0.1))
 
                     DefinitionRow(
-                        term: "COBpredBG",
+                        term: String(localized: "COBpredBG"),
                         definition: Text(
                             "The forecasted glucose value in 4 hours calculated based on current IOB and COB."
                         ),
@@ -108,7 +108,7 @@ struct LoopStatusHelpView: View {
                     ).listRowBackground(Color.gray.opacity(0.1))
 
                     DefinitionRow(
-                        term: "UAMpredBG",
+                        term: String(localized: "UAMpredBG"),
                         definition: Text(
                             "The forecasted glucose value in 4 hours based on current deviations ramping down to zero at the same rate they have been recently."
                         ),
@@ -116,7 +116,7 @@ struct LoopStatusHelpView: View {
                     ).listRowBackground(Color.gray.opacity(0.1))
 
                     DefinitionRow(
-                        term: "TDD",
+                        term: String(localized: "TDD"),
                         definition: Text(
                             "Abbreviation for 'Total Daily Dose'. Last 24 hours of total insulin administered, both basal and bolus."
                         ),
@@ -124,7 +124,7 @@ struct LoopStatusHelpView: View {
                     ).listRowBackground(Color.gray.opacity(0.1))
 
                     DefinitionRow(
-                        term: "Bolus/Basal %",
+                        term: String(localized: "Bolus/Basal %"),
                         definition: Text(
                             "Of the total insulin delivered in the past 24 hours, this indicates what percentage was administered through basals and what was given through bolus."
                         ),
@@ -132,7 +132,7 @@ struct LoopStatusHelpView: View {
                     ).listRowBackground(Color.gray.opacity(0.1))
 
                     DefinitionRow(
-                        term: "Dynamic ISF/CR",
+                        term: String(localized: "Dynamic ISF/CR"),
                         definition: Text(
                             "A display of On/On indicates both Dynamic ISF and CR are enabled. On/Off indicates only Dynamic ISF is enabled. Dynamic CR cannot be enabled when Dynamic ISF is disabled."
                         ),
@@ -140,19 +140,19 @@ struct LoopStatusHelpView: View {
                     ).listRowBackground(Color.gray.opacity(0.1))
 
                     DefinitionRow(
-                        term: "Sigmoid function",
+                        term: String(localized: "Sigmoid function"),
                         definition: Text("If shown, Sigmoid Dynamic ISF is enabled."),
                         color: .zt
                     ).listRowBackground(Color.gray.opacity(0.1))
 
                     DefinitionRow(
-                        term: "Logarithmic formula",
+                        term: String(localized: "Logarithmic formula"),
                         definition: Text("If shown, Logarithmic Dynamic ISF is enabled."),
                         color: .zt
                     ).listRowBackground(Color.gray.opacity(0.1))
 
                     DefinitionRow(
-                        term: "AF",
+                        term: String(localized: "AF"),
                         definition: Text(
                             "Displays the Adjustment Factor (AF) for either Logathmic or Sigmoid Dynamic ISF in use."
                         ),
@@ -160,7 +160,7 @@ struct LoopStatusHelpView: View {
                     ).listRowBackground(Color.gray.opacity(0.1))
 
                     DefinitionRow(
-                        term: "SMB Ratio",
+                        term: String(localized: "SMB Ratio"),
                         definition: Text(
                             "SMB Delivery Ratio of calculated insulin required that is given as SMB."
                         ),
@@ -168,7 +168,7 @@ struct LoopStatusHelpView: View {
                     ).listRowBackground(Color.gray.opacity(0.1))
 
                     DefinitionRow(
-                        term: "Smoothing",
+                        term: String(localized: "Smoothing"),
                         definition: Text("Indicates glucose smoothing is enabled."),
                         color: .gray
                     ).listRowBackground(Color.gray.opacity(0.1))
@@ -198,7 +198,7 @@ struct LoopStatusHelpView: View {
     var legendLinesView: some View {
         Group {
             DefinitionRow(
-                term: "IOB (Insulin on Board)",
+                term: String(localized: "IOB (Insulin on Board)"),
                 definition: Text(
                     "Forecasts future glucose readings based on the amount of insulin still active in the body."
                 ),
@@ -206,7 +206,7 @@ struct LoopStatusHelpView: View {
             )
 
             DefinitionRow(
-                term: "ZT (Zero-Temp)",
+                term: String(localized: "ZT (Zero-Temp)"),
                 definition: Text(
                     "Forecasts the worst-case future glucose reading scenario if no carbs are absorbed and insulin delivery is stopped until glucose starts rising."
                 ),
@@ -214,7 +214,7 @@ struct LoopStatusHelpView: View {
             )
 
             DefinitionRow(
-                term: "COB (Carbs on Board)",
+                term: String(localized: "COB (Carbs on Board)"),
                 definition: Text(
                     "Forecasts future glucose reading changes by considering the amount of carbohydrates still being absorbed in the body."
                 ),
@@ -222,7 +222,7 @@ struct LoopStatusHelpView: View {
             )
 
             DefinitionRow(
-                term: "UAM (Unannounced Meal)",
+                term: String(localized: "UAM (Unannounced Meal)"),
                 definition: Text(
                     "Forecasts future glucose levels and insulin dosing needs for unexpected meals or other causes of glucose reading increases without prior notice."
                 ),
@@ -233,7 +233,7 @@ struct LoopStatusHelpView: View {
 
     var legendConeOfUncertaintyView: some View {
         DefinitionRow(
-            term: "Cone of Uncertainty",
+            term: String(localized: "Cone of Uncertainty"),
             definition: VStack(alignment: .leading, spacing: 10) {
                 Text(
                     "For simplicity reasons, oref's various forecast curves are displayed as a \"Cone of Uncertainty\" that depicts a possible, forecasted range of future glucose fluctuation based on the current data and the algothim's result."

+ 1 - 1
Trio/Sources/Modules/Home/View/Header/LoopView.swift

@@ -61,7 +61,7 @@ struct LoopView: View {
         if minAgo > 1440 {
             return "--"
         }
-        return "\(minAgo) " + NSLocalizedString("min", comment: "Minutes ago since last loop")
+        return "\(minAgo) " + String(localized: "min", comment: "Minutes ago since last loop")
     }
 
     private var color: Color {

+ 7 - 7
Trio/Sources/Modules/Home/View/Header/PumpView.swift

@@ -46,14 +46,14 @@ struct PumpView: View {
                             .font(.callout)
 
                         if reservoir == 0xDEAD_BEEF {
-                            Text("50+ " + NSLocalizedString("U", comment: "Insulin unit"))
+                            Text("50+ " + String(localized: "U", comment: "Insulin unit"))
                                 .font(.callout)
                                 .fontWeight(.bold)
                                 .fontDesign(.rounded)
                         } else {
                             Text(
                                 Formatter.integerFormatter
-                                    .string(from: reservoir as NSNumber)! + NSLocalizedString(" U", comment: "Insulin unit")
+                                    .string(from: reservoir as NSNumber)! + String(localized: " U", comment: "Insulin unit")
                             )
                             .font(.callout)
                             .fontWeight(.bold)
@@ -109,7 +109,7 @@ struct PumpView: View {
 
     private func remainingTimeString(time: TimeInterval) -> String {
         guard time > 0 else {
-            return NSLocalizedString("Replace pod", comment: "View/Header when pod expired")
+            return String(localized: "Replace pod", comment: "View/Header when pod expired")
         }
 
         var time = time
@@ -120,15 +120,15 @@ struct PumpView: View {
         let minutes = Int(time / 1.minutes.timeInterval)
 
         if days >= 1 {
-            return "\(days)" + NSLocalizedString("d", comment: "abbreviation for days") + " \(hours)" +
-                NSLocalizedString("h", comment: "abbreviation for hours")
+            return "\(days)" + String(localized: "d", comment: "abbreviation for days") + " \(hours)" +
+                String(localized: "h", comment: "abbreviation for hours")
         }
 
         if hours >= 1 {
-            return "\(hours)" + NSLocalizedString("h", comment: "abbreviation for hours")
+            return "\(hours)" + String(localized: "h", comment: "abbreviation for hours")
         }
 
-        return "\(minutes)" + NSLocalizedString("m", comment: "abbreviation for minutes")
+        return "\(minutes)" + String(localized: "m", comment: "abbreviation for minutes")
     }
 
     private var batteryColor: Color {

+ 14 - 13
Trio/Sources/Modules/Home/View/HomeRootView.swift

@@ -86,7 +86,7 @@ extension Home {
                 Image(uiImage: badgeImage.withRenderingMode(.alwaysTemplate))
                     .font(.system(size: 14))
                     .colorMultiply(badgeColor)
-                Text(NSLocalizedString("Time Change Detected", comment: ""))
+                Text(String(localized: "Time Change Detected", comment: ""))
                     .bold()
                     .font(.system(size: 14))
                     .foregroundStyle(badgeColor)
@@ -170,13 +170,14 @@ extension Home {
             var manualBasalString = ""
 
             if let apsManager = state.apsManager, apsManager.isManualTempBasal {
-                manualBasalString = NSLocalizedString(
+                manualBasalString = String(
+                    localized:
                     " - Manual Basal ⚠️",
                     comment: "Manual Temp basal"
                 )
             }
 
-            return rateString + " " + NSLocalizedString(" U/hr", comment: "Unit per hour with space") + manualBasalString
+            return rateString + " " + String(localized: " U/hr", comment: "Unit per hour with space") + manualBasalString
         }
 
         var overrideString: String? {
@@ -291,11 +292,11 @@ extension Home {
                         Group {
                             if button.active {
                                 Text(
-                                    NSLocalizedString(button.hours.description, comment: "") + " " +
-                                        NSLocalizedString("h", comment: "h")
+                                    button.hours.description + " " +
+                                        String(localized: "h", comment: "h")
                                 )
                             } else {
-                                Text(NSLocalizedString(button.hours.description, comment: ""))
+                                Text(button.hours.description)
                             }
                         }
                         .font(.footnote)
@@ -435,7 +436,7 @@ extension Home {
                             Formatter.decimalFormatterWithTwoFractionDigits
                                 .string(from: (state.enactedAndNonEnactedDeterminations.first?.iob ?? 0) as NSNumber) ?? "0"
                         ) +
-                            NSLocalizedString(" U", comment: "Insulin unit")
+                            String(localized: " U", comment: "Insulin unit")
                     )
                     .font(.callout).fontWeight(.bold).fontDesign(.rounded)
                 }
@@ -452,7 +453,7 @@ extension Home {
                                 from: NSNumber(value: state.enactedAndNonEnactedDeterminations.first?.cob ?? 0)
                             ) ?? "0"
                         ) +
-                            NSLocalizedString(" g", comment: "gram of carbs")
+                            String(localized: " g", comment: "gram of carbs")
                     )
                     .font(.callout).fontWeight(.bold).fontDesign(.rounded)
                 }
@@ -496,7 +497,7 @@ extension Home {
                                     .string(from: (state.determinationsFromPersistence.first?.totalDailyDose ?? 0) as NSNumber) ??
                                     "0"
                             ) +
-                            NSLocalizedString(" U", comment: "Insulin unit")
+                            String(localized: " U", comment: "Insulin unit")
                     )
                     .font(.callout).fontWeight(.bold).fontDesign(.rounded)
                 } else {
@@ -504,7 +505,7 @@ extension Home {
                     HStack {
                         Text(
                             "TINS: \(state.roundedTotalBolus)" +
-                                NSLocalizedString(" U", comment: "Unit in number of units delivered (keep the space character!)")
+                                String(localized: " U", comment: "Unit in number of units delivered (keep the space character!)")
                         )
                         .font(.callout).fontWeight(.bold).fontDesign(.rounded)
                         .onChange(of: state.hours) {
@@ -526,7 +527,7 @@ extension Home {
                     .font(.title2)
                     .foregroundStyle(Color.primary, Color.purple)
                 VStack(alignment: .leading) {
-                    Text(latestOverride.first?.name ?? "Custom Override")
+                    Text(latestOverride.first?.name ?? String(localized: "Custom Override"))
                         .font(.subheadline)
                         .frame(alignment: .leading)
 
@@ -545,7 +546,7 @@ extension Home {
                     .font(.title2)
                     .foregroundStyle(Color.loopGreen)
                 VStack(alignment: .leading) {
-                    Text(latestTempTarget.first?.name ?? "Temp Target")
+                    Text(latestTempTarget.first?.name ?? String(localized: "Temp Target"))
                         .font(.subheadline)
                     Text(tempTargetString)
                         .font(.caption)
@@ -759,7 +760,7 @@ extension Home {
                     (bolusProgressFormatter.string(from: bolusFraction as NSNumber) ?? "0")
                         + " of " +
                         (Formatter.decimalFormatterWithTwoFractionDigits.string(from: bolusTotal as NSNumber) ?? "0")
-                        + NSLocalizedString(" U", comment: "Insulin unit")
+                        + String(localized: " U", comment: "Insulin unit")
 
                 ZStack {
                     /// rectangle as background

+ 6 - 6
Trio/Sources/Modules/LiveActivitySettings/View/LiveActivitySettingsRootView.swift

@@ -53,13 +53,13 @@ extension LiveActivitySettings {
                             get: { selectedVerboseHint },
                             set: {
                                 selectedVerboseHint = $0.map { AnyView($0) }
-                                hintLabel = "Enable Live Activity"
+                                hintLabel = String(localized: "Enable Live Activity")
                             }
                         ),
                         units: state.units,
                         type: .boolean,
-                        label: "Enable Live Activity",
-                        miniHint: "Display customizable data on Lock Screen and Dynamic Island.",
+                        label: String(localized: "Enable Live Activity"),
+                        miniHint: String(localized: "Display customizable data on Lock Screen and Dynamic Island."),
                         verboseHint: VStack(alignment: .leading, spacing: 10) {
                             Text("Default: OFF").bold()
                             VStack(alignment: .leading, spacing: 10) {
@@ -78,7 +78,7 @@ extension LiveActivitySettings {
                                 )
                             }
                         },
-                        headerText: "Display Live Data From Trio"
+                        headerText: String(localized: "Display Live Data From Trio")
                     )
 
                     if state.useLiveActivity {
@@ -103,7 +103,7 @@ extension LiveActivitySettings {
                                     Spacer()
                                     Button(
                                         action: {
-                                            hintLabel = "Lock Screen Widget Style"
+                                            hintLabel = String(localized: "Lock Screen Widget Style")
                                             selectedVerboseHint =
                                                 AnyView(
                                                     VStack(alignment: .leading, spacing: 10) {
@@ -164,7 +164,7 @@ extension LiveActivitySettings {
                     shouldDisplayHint: $shouldDisplayHint,
                     hintLabel: hintLabel ?? "",
                     hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                    sheetTitle: "Help"
+                    sheetTitle: String(localized: "Help", comment: "Help sheet title")
                 )
             }
             .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))

+ 4 - 4
Trio/Sources/Modules/Main/MainStateModel.swift

@@ -155,7 +155,7 @@ extension Main {
 
             view.configureContent(
                 title: "title",
-                body: NSLocalizedString(message.content, comment: "Info message"),
+                body: message.content,
                 iconImage: nil,
                 iconText: nil,
                 buttonImage: nil,
@@ -177,15 +177,15 @@ extension Main {
             case .info,
                  .other:
                 config.duration = .seconds(seconds: 5)
-                titleContent = message.title != "" ? message.title : NSLocalizedString("Info", comment: "Info title")
+                titleContent = message.title != "" ? message.title : String(localized: "Info", comment: "Info title")
             case .warning:
                 config.duration = .forever
                 titleContent = message.title != "" ? message
-                    .title : NSLocalizedString("Warning", comment: "Warning title")
+                    .title : String(localized: "Warning", comment: "Warning title")
             case .error:
                 config.duration = .forever
                 titleContent = message.title != "" ? message
-                    .title : NSLocalizedString("Error", comment: "Error title")
+                    .title : String(localized: "Error", comment: "Error title")
             }
 
             view.titleLabel?.text = titleContent

+ 23 - 21
Trio/Sources/Modules/MealSettings/View/MealSettingsRootView.swift

@@ -157,7 +157,7 @@ extension MealSettings {
                                 Spacer()
                                 Button(
                                     action: {
-                                        hintLabel = "Limits per Entry"
+                                        hintLabel = String(localized: "Limits per Entry")
                                         selectedVerboseHint =
                                             AnyView(
                                                 VStack(alignment: .leading, spacing: 5) {
@@ -190,13 +190,15 @@ extension MealSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Maximum Meal Absorption Time"
+                            hintLabel = String(localized: "Maximum Meal Absorption Time")
                         }
                     ),
                     units: state.units,
                     type: .decimal("maxMealAbsorptionTime"),
-                    label: "Max Meal Absorption Time",
-                    miniHint: "The maximum duration for tracking carb entries in estimating Carbs on Board (COB)",
+                    label: String(localized: "Max Meal Absorption Time"),
+                    miniHint: String(
+                        localized: "The maximum duration for tracking carb entries in estimating Carbs on Board (COB)"
+                    ),
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
                         Text("Default: 6 hours").bold()
@@ -220,13 +222,13 @@ extension MealSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Enable Fat and Protein Entries"
+                            hintLabel = String(localized: "Enable Fat and Protein Entries")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: "Enable Fat and Protein Entries",
-                    miniHint: "Add fat and protein macros to meal entries.",
+                    label: String(localized: "Enable Fat and Protein Entries"),
+                    miniHint: String(localized: "Add fat and protein macros to meal entries."),
                     verboseHint: VStack(alignment: .leading, spacing: 10) {
                         Text("Default: OFF").bold()
                         VStack(spacing: 10) {
@@ -262,7 +264,7 @@ extension MealSettings {
                             }
                         }
                     },
-                    headerText: "Fat and Protein"
+                    headerText: String(localized: "Fat and Protein")
                 )
                 if state.useFPUconversion {
                     SettingInputSection(
@@ -273,13 +275,13 @@ extension MealSettings {
                             get: { selectedVerboseHint },
                             set: {
                                 selectedVerboseHint = $0.map { AnyView($0) }
-                                hintLabel = "Fat and Protein Delay"
+                                hintLabel = String(localized: "Fat and Protein Delay")
                             }
                         ),
                         units: state.units,
                         type: .decimal("delay"),
-                        label: "Fat and Protein Delay",
-                        miniHint: "Delay between fat & protein entry and first FPU entry.",
+                        label: String(localized: "Fat and Protein Delay"),
+                        miniHint: String(localized: "Delay between fat & protein entry and first FPU entry."),
                         verboseHint:
                         VStack(alignment: .leading, spacing: 10) {
                             Text("Default: 60 min").bold()
@@ -300,13 +302,13 @@ extension MealSettings {
                             get: { selectedVerboseHint },
                             set: {
                                 selectedVerboseHint = $0.map { AnyView($0) }
-                                hintLabel = "Maximum Duration"
+                                hintLabel = String(localized: "Maximum Duration")
                             }
                         ),
                         units: state.units,
                         type: .decimal("timeCap"),
-                        label: "Maximum Duration",
-                        miniHint: "Set the maximum timeframe to extend FPUs.",
+                        label: String(localized: "Maximum Duration"),
+                        miniHint: String(localized: "Set the maximum timeframe to extend FPUs."),
                         verboseHint:
                         VStack(alignment: .leading, spacing: 10) {
                             Text("Default: 8 hours").bold()
@@ -329,13 +331,13 @@ extension MealSettings {
                             get: { selectedVerboseHint },
                             set: {
                                 selectedVerboseHint = $0.map { AnyView($0) }
-                                hintLabel = "Spread Interval"
+                                hintLabel = String(localized: "Spread Interval")
                             }
                         ),
                         units: state.units,
                         type: .decimal("minuteInterval"),
-                        label: "Spread Interval",
-                        miniHint: "Time interval between FPUs.",
+                        label: String(localized: "Spread Interval"),
+                        miniHint: String(localized: "Time interval between FPUs."),
                         verboseHint:
                         VStack(alignment: .leading, spacing: 10) {
                             Text("Default: 30 minutes").bold()
@@ -356,13 +358,13 @@ extension MealSettings {
                             get: { selectedVerboseHint },
                             set: {
                                 selectedVerboseHint = $0.map { AnyView($0) }
-                                hintLabel = "Fat and Protein Percentage"
+                                hintLabel = String(localized: "Fat and Protein Percentage")
                             }
                         ),
                         units: state.units,
                         type: .decimal("individualAdjustmentFactor"),
-                        label: "Fat and Protein Percentage",
-                        miniHint: "Adjust the Warsaw Method FPU Conversion rate.",
+                        label: String(localized: "Fat and Protein Percentage"),
+                        miniHint: String(localized: "Adjust the Warsaw Method FPU Conversion rate."),
                         verboseHint: VStack(alignment: .leading, spacing: 10) {
                             Text("Default: 50%").bold()
                             VStack(spacing: 10) {
@@ -392,7 +394,7 @@ extension MealSettings {
                     shouldDisplayHint: $shouldDisplayHint,
                     hintLabel: hintLabel ?? "",
                     hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                    sheetTitle: "Help"
+                    sheetTitle: String(localized: "Help", comment: "Help sheet title")
                 )
             }
             .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))

+ 3 - 3
Trio/Sources/Modules/NightscoutConfig/View/NightscoutConfigRootView.swift

@@ -97,7 +97,7 @@ extension NightscoutConfig {
                                 Spacer()
                                 Button(
                                     action: {
-                                        hintLabel = "Import Settings from Nightscout"
+                                        hintLabel = String(localized: "Import Settings from Nightscout")
                                         selectedVerboseHint =
                                             AnyView(
                                                 VStack(alignment: .leading, spacing: 10) {
@@ -150,7 +150,7 @@ extension NightscoutConfig {
                                     Spacer()
                                     Button(
                                         action: {
-                                            hintLabel = "Backfill Glucose from Nightscout"
+                                            hintLabel = String(localized: "Backfill Glucose from Nightscout")
                                             selectedVerboseHint =
                                                 AnyView(
                                                     Text(
@@ -186,7 +186,7 @@ extension NightscoutConfig {
                     shouldDisplayHint: $shouldDisplayHint,
                     hintLabel: hintLabel ?? "",
                     hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                    sheetTitle: "Help"
+                    sheetTitle: String(localized: "Help", comment: "Help sheet title")
                 )
             }
             .navigationBarTitle("Nightscout")

+ 5 - 5
Trio/Sources/Modules/NightscoutConfig/View/NightscoutFetchView.swift

@@ -24,20 +24,20 @@ struct NightscoutFetchView: View {
                     get: { selectedVerboseHint },
                     set: {
                         selectedVerboseHint = $0.map { AnyView($0) }
-                        hintLabel = "Allow Fetching from Nightscout"
+                        hintLabel = String(localized: "Allow Fetching from Nightscout")
                     }
                 ),
                 units: state.units,
                 type: .boolean,
-                label: "Allow Fetching from Nightscout",
-                miniHint: "Enable fetching of selected data sets from Nightscout.",
+                label: String(localized: "Allow Fetching from Nightscout"),
+                miniHint: String(localized: "Enable fetching of selected data sets from Nightscout."),
                 verboseHint: VStack(alignment: .leading, spacing: 10) {
                     Text("Default: OFF").bold()
                     Text(
                         "The Fetch Treatments toggle enables fetching of carbs and temp targets entered in Careportal or by another uploading device than Trio from Nightscout."
                     )
                 },
-                headerText: "Fetch NS Care Portal Data"
+                headerText: String(localized: "Fetch NS Care Portal Data")
             )
         }
         .listSectionSpacing(sectionSpacing)
@@ -47,7 +47,7 @@ struct NightscoutFetchView: View {
                 shouldDisplayHint: $shouldDisplayHint,
                 hintLabel: hintLabel ?? "",
                 hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                sheetTitle: "Help"
+                sheetTitle: String(localized: "Help", comment: "Help sheet title")
             )
         }
         .navigationTitle("Fetch")

+ 7 - 7
Trio/Sources/Modules/NightscoutConfig/View/NightscoutUploadView.swift

@@ -23,14 +23,14 @@ struct NightscoutUploadView: View {
                     get: { selectedVerboseHint },
                     set: {
                         selectedVerboseHint = $0.map { AnyView($0) }
-                        hintLabel = "Allow Uploading to Nightscout"
+                        hintLabel = String(localized: "Allow Uploading to Nightscout")
                         shouldDisplayHint = true
                     }
                 ),
                 units: state.units,
                 type: .boolean,
-                label: "Allow Uploading to Nightscout",
-                miniHint: "Enable uploading of selected data sets to Nightscout.",
+                label: String(localized: "Allow Uploading to Nightscout"),
+                miniHint: String(localized: "Enable uploading of selected data sets to Nightscout."),
                 verboseHint:
                 VStack(alignment: .leading, spacing: 10) {
                     Text("Default: OFF").bold()
@@ -56,14 +56,14 @@ struct NightscoutUploadView: View {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Upload Glucose"
+                            hintLabel = String(localized: "Upload Glucose")
                             shouldDisplayHint = true
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: "Upload Glucose",
-                    miniHint: "Enable uploading of CGM readings to Nightscout.",
+                    label: String(localized: "Upload Glucose"),
+                    miniHint: String(localized: "Enable uploading of CGM readings to Nightscout."),
                     verboseHint: VStack(alignment: .leading, spacing: 10) {
                         Text("Default: OFF").bold()
                         Text("Enabling this setting allows CGM readings from Trio to be used in Nightscout.")
@@ -78,7 +78,7 @@ struct NightscoutUploadView: View {
                 shouldDisplayHint: $shouldDisplayHint,
                 hintLabel: hintLabel ?? "",
                 hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                sheetTitle: "Help"
+                sheetTitle: String(localized: "Help", comment: "Help sheet title")
             )
         }
         .navigationTitle("Upload")

+ 5 - 5
Trio/Sources/Modules/NightscoutConfig/View/ProfileImport/ReviewInsulinActionView.swift

@@ -28,13 +28,13 @@ struct ReviewInsulinActionView: BaseView {
                     get: { selectedVerboseHint },
                     set: {
                         selectedVerboseHint = $0.map { AnyView($0) }
-                        hintLabel = "Duration of Insulin Action"
+                        hintLabel = String(localized: "Duration of Insulin Action")
                     }
                 ),
                 units: state.units,
                 type: .decimal("dia"),
-                label: "Duration of Insulin Action",
-                miniHint: "Number of hours insulin is active in your body.",
+                label: String(localized: "Duration of Insulin Action"),
+                miniHint: String(localized: "Number of hours insulin is active in your body."),
                 verboseHint:
                 VStack(alignment: .leading, spacing: 10) {
                     Text("Default: 10 hours").bold()
@@ -43,7 +43,7 @@ struct ReviewInsulinActionView: BaseView {
                         "Tip: It is better to use a Custom Peak Time than to adjust Duration of Insulin Action (DIA)."
                     )
                 },
-                headerText: "Review imported DIA"
+                headerText: String(localized: "Review imported DIA")
             )
         }
         .sheet(isPresented: $shouldDisplayHint) {
@@ -52,7 +52,7 @@ struct ReviewInsulinActionView: BaseView {
                 shouldDisplayHint: $shouldDisplayHint,
                 hintLabel: hintLabel ?? "",
                 hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                sheetTitle: "Help"
+                sheetTitle: String(localized: "Help", comment: "Help sheet title")
             )
         }
         .scrollContentBackground(.hidden)

+ 1 - 1
Trio/Sources/Modules/PumpConfig/View/PumpConfigRootView.swift

@@ -119,7 +119,7 @@ extension PumpConfig {
                                 )
                             }
                         ),
-                        sheetTitle: "Help"
+                        sheetTitle: String(localized: "Help", comment: "Help sheet title")
                     )
                 }
                 .confirmationDialog("Pump Model", isPresented: $showPumpSelection) {

+ 5 - 5
Trio/Sources/Modules/RemoteControlConfig/View/RemoteControlConfig.swift

@@ -29,13 +29,13 @@ extension RemoteControlConfig {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Enable Remote Command"
+                            hintLabel = String(localized: "Enable Remote Command")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: "Enable Remote Control",
-                    miniHint: "Allow Trio to receive commands from Loop Follow remotely.",
+                    label: String(localized: "Enable Remote Control"),
+                    miniHint: String(localized: "Allow Trio to receive commands from Loop Follow remotely."),
                     verboseHint: VStack(alignment: .leading, spacing: 10) {
                         Text("Default: OFF").bold()
                         Text(
@@ -45,7 +45,7 @@ extension RemoteControlConfig {
                             "To ensure security, these commands are protected by a shared secret, which must be entered in the Loop Follow app."
                         )
                     },
-                    headerText: "Trio Remote Control"
+                    headerText: String(localized: "Trio Remote Control")
                 )
 
                 Section(
@@ -94,7 +94,7 @@ extension RemoteControlConfig {
                     shouldDisplayHint: $shouldDisplayHint,
                     hintLabel: hintLabel ?? "",
                     hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                    sheetTitle: "Help"
+                    sheetTitle: String(localized: "Help", comment: "Help sheet title")
                 )
             }
             .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))

+ 28 - 26
Trio/Sources/Modules/SMBSettings/View/SMBSettingsRootView.swift

@@ -26,12 +26,12 @@ extension SMBSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Enable SMB Always", comment: "Enable SMB Always")
+                            hintLabel = String(localized: "Enable SMB Always", comment: "Enable SMB Always")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: NSLocalizedString("Enable SMB Always", comment: "Enable SMB Always"),
+                    label: String(localized: "Enable SMB Always", comment: "Enable SMB Always"),
                     miniHint: "Allow SMBs at all times except when a high Temp Target is set.",
                     verboseHint: VStack(alignment: .leading, spacing: 10) {
                         Text("Default: OFF").bold()
@@ -42,7 +42,7 @@ extension SMBSettings {
                             "Note: If you would like to allow SMBs when a high Temp Target is set, enable the \"Allow SMBs with High Temptarget\" setting."
                         )
                     },
-                    headerText: "Super-Micro-Bolus"
+                    headerText: String(localized: "Super-Micro-Bolus")
                 )
 
                 if !state.enableSMBAlways {
@@ -54,12 +54,12 @@ extension SMBSettings {
                             get: { selectedVerboseHint },
                             set: {
                                 selectedVerboseHint = $0.map { AnyView($0) }
-                                hintLabel = NSLocalizedString("Enable SMB With COB", comment: "Enable SMB With COB")
+                                hintLabel = String(localized: "Enable SMB With COB", comment: "Enable SMB With COB")
                             }
                         ),
                         units: state.units,
                         type: .boolean,
-                        label: NSLocalizedString("Enable SMB With COB", comment: "Enable SMB With COB"),
+                        label: String(localized: "Enable SMB With COB", comment: "Enable SMB With COB"),
                         miniHint: "Allow SMB when carbs are on board.",
                         verboseHint:
                         VStack(alignment: .leading, spacing: 10) {
@@ -81,12 +81,12 @@ extension SMBSettings {
                             get: { selectedVerboseHint },
                             set: {
                                 selectedVerboseHint = $0.map { AnyView($0) }
-                                hintLabel = NSLocalizedString("Enable SMB With Temptarget", comment: "Enable SMB With Temptarget")
+                                hintLabel = String(localized: "Enable SMB With Temptarget", comment: "Enable SMB With Temptarget")
                             }
                         ),
                         units: state.units,
                         type: .boolean,
-                        label: NSLocalizedString("Enable SMB With Temptarget", comment: "Enable SMB With Temptarget"),
+                        label: String(localized: "Enable SMB With Temptarget", comment: "Enable SMB With Temptarget"),
                         miniHint: "Allow SMB when a manual Temporary Target is set under \(state.units == .mgdL ? "100" : 100.formattedAsMmolL) \(state.units.rawValue).",
                         verboseHint:
                         VStack(alignment: .leading, spacing: 10) {
@@ -108,12 +108,12 @@ extension SMBSettings {
                             get: { selectedVerboseHint },
                             set: {
                                 selectedVerboseHint = $0.map { AnyView($0) }
-                                hintLabel = NSLocalizedString("Enable SMB After Carbs", comment: "Enable SMB After Carbs")
+                                hintLabel = String(localized: "Enable SMB After Carbs", comment: "Enable SMB After Carbs")
                             }
                         ),
                         units: state.units,
                         type: .boolean,
-                        label: NSLocalizedString("Enable SMB After Carbs", comment: "Enable SMB After Carbs"),
+                        label: String(localized: "Enable SMB After Carbs", comment: "Enable SMB After Carbs"),
                         miniHint: "Allow SMB for 6 hrs after a carb entry.",
                         verboseHint:
                         VStack(alignment: .leading, spacing: 10) {
@@ -135,12 +135,12 @@ extension SMBSettings {
                             get: { selectedVerboseHint },
                             set: {
                                 selectedVerboseHint = $0.map { AnyView($0) }
-                                hintLabel = NSLocalizedString("Enable SMB With High BG", comment: "Enable SMB With High BG")
+                                hintLabel = String(localized: "Enable SMB With High BG", comment: "Enable SMB With High BG")
                             }
                         ),
                         units: state.units,
                         type: .conditionalDecimal("enableSMB_high_bg_target"),
-                        label: NSLocalizedString("Enable SMB With High BG", comment: "Enable SMB With High BG"),
+                        label: String(localized: "Enable SMB With High BG", comment: "Enable SMB With High BG"),
                         conditionalLabel: "High BG Target",
                         miniHint: "Allow SMB when glucose is above the High BG Target value.",
                         verboseHint:
@@ -164,7 +164,8 @@ extension SMBSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString(
+                            hintLabel = String(
+                                localized:
                                 "Allow SMB With High Temptarget",
                                 comment: "Allow SMB With High Temptarget"
                             )
@@ -172,7 +173,8 @@ extension SMBSettings {
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: NSLocalizedString(
+                    label: String(
+                        localized:
                         "Allow SMB With High Temptarget",
                         comment: "Allow SMB With High Temptarget"
                     ),
@@ -200,12 +202,12 @@ extension SMBSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Enable UAM", comment: "Enable UAM")
+                            hintLabel = String(localized: "Enable UAM", comment: "Enable UAM")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: NSLocalizedString("Enable UAM", comment: "Enable UAM"),
+                    label: String(localized: "Enable UAM", comment: "Enable UAM"),
                     miniHint: "Enable Unannounced Meals SMB.",
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
@@ -230,12 +232,12 @@ extension SMBSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Max SMB Basal Minutes", comment: "Max SMB Basal Minutes")
+                            hintLabel = String(localized: "Max SMB Basal Minutes", comment: "Max SMB Basal Minutes")
                         }
                     ),
                     units: state.units,
                     type: .decimal("maxSMBBasalMinutes"),
-                    label: NSLocalizedString("Max SMB Basal Minutes", comment: "Max SMB Basal Minutes"),
+                    label: String(localized: "Max SMB Basal Minutes", comment: "Max SMB Basal Minutes"),
                     miniHint: "Limits the size of a single Super Micro Bolus (SMB) dose.",
                     verboseHint: VStack(spacing: 10) {
                         VStack(alignment: .leading, spacing: 10) {
@@ -276,12 +278,12 @@ extension SMBSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Max UAM Basal Minutes", comment: "Max UAM Basal Minutes")
+                            hintLabel = String(localized: "Max UAM Basal Minutes", comment: "Max UAM Basal Minutes")
                         }
                     ),
                     units: state.units,
                     type: .decimal("maxUAMSMBBasalMinutes"),
-                    label: NSLocalizedString("Max UAM Basal Minutes", comment: "Max UAM Basal Minutes"),
+                    label: String(localized: "Max UAM Basal Minutes", comment: "Max UAM Basal Minutes"),
                     miniHint: "Limits the size of a single Unannounced Meal (UAM) SMB dose.",
                     verboseHint: VStack(spacing: 10) {
                         VStack(alignment: .leading, spacing: 10) {
@@ -321,12 +323,12 @@ extension SMBSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Max Delta-BG Threshold SMB", comment: "Max Delta-BG Threshold")
+                            hintLabel = String(localized: "Max Delta-BG Threshold SMB", comment: "Max Delta-BG Threshold")
                         }
                     ),
                     units: state.units,
                     type: .decimal("maxDeltaBGthreshold"),
-                    label: NSLocalizedString("Max Delta-BG Threshold SMB", comment: "Max Delta-BG Threshold"),
+                    label: String(localized: "Max Delta-BG Threshold SMB", comment: "Max Delta-BG Threshold"),
                     miniHint: "Disables SMBs if last two glucose values differ by more than this percent.",
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
@@ -346,12 +348,12 @@ extension SMBSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("SMB Delivery Ratio", comment: "SMB Delivery Ratio")
+                            hintLabel = String(localized: "SMB Delivery Ratio", comment: "SMB Delivery Ratio")
                         }
                     ),
                     units: state.units,
                     type: .decimal("smbDeliveryRatio"),
-                    label: NSLocalizedString("SMB Delivery Ratio", comment: "SMB Delivery Ratio"),
+                    label: String(localized: "SMB Delivery Ratio", comment: "SMB Delivery Ratio"),
                     miniHint: "Percentage of calculated insulin required that is given as SMB.",
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
@@ -374,12 +376,12 @@ extension SMBSettings {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("SMB Interval", comment: "SMB Interval")
+                            hintLabel = String(localized: "SMB Interval", comment: "SMB Interval")
                         }
                     ),
                     units: state.units,
                     type: .decimal("smbInterval"),
-                    label: NSLocalizedString("SMB Interval", comment: "SMB Interval"),
+                    label: String(localized: "SMB Interval", comment: "SMB Interval"),
                     miniHint: "Minimum minutes since the last SMB or manual bolus to allow an automated SMB.",
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
@@ -397,7 +399,7 @@ extension SMBSettings {
                     shouldDisplayHint: $shouldDisplayHint,
                     hintLabel: hintLabel ?? "",
                     hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                    sheetTitle: "Help"
+                    sheetTitle: String(localized: "Help", comment: "Help sheet title")
                 )
             }
             .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))

+ 1 - 1
Trio/Sources/Modules/Settings/SettingItems.swift

@@ -331,7 +331,7 @@ extension LocalizedStringKey {
         let mirror = Mirror(reflecting: self)
         let children = mirror.children
         if let label = children.first(where: { $0.label == "key" })?.value as? String {
-            return NSLocalizedString(label, comment: "")
+            return String(localized: "\(label)", comment: "")
         } else {
             return ""
         }

+ 7 - 7
Trio/Sources/Modules/Settings/View/SettingsRootView.swift

@@ -35,8 +35,8 @@ extension Settings {
                     Section(
                         header: Text("BRANCH: \(buildDetails.branchAndSha)").textCase(nil),
                         content: {
-                            let versionNumber = Bundle.main.releaseVersionNumber ?? "Unknown"
-                            let buildNumber = Bundle.main.buildVersionNumber ?? "Unknown"
+                            let versionNumber = Bundle.main.releaseVersionNumber ?? String(localized: "Unknown")
+                            let buildNumber = Bundle.main.buildVersionNumber ?? String(localized: "Unknown")
 
                             Group {
                                 HStack {
@@ -77,13 +77,13 @@ extension Settings {
                             get: { selectedVerboseHint },
                             set: {
                                 selectedVerboseHint = $0.map { AnyView($0) }
-                                hintLabel = "Closed Loop"
+                                hintLabel = String(localized: "Closed Loop")
                             }
                         ),
                         units: state.units,
                         type: .boolean,
-                        label: "Closed Loop",
-                        miniHint: "Enable automated insulin delivery.",
+                        label: String(localized: "Closed Loop"),
+                        miniHint: String(localized: "Enable automated insulin delivery."),
                         verboseHint: VStack(alignment: .leading, spacing: 10) {
                             Text(
                                 "Running Trio in closed loop mode requires an active CGM sensor session and a connected pump. This enables automated insulin delivery."
@@ -92,7 +92,7 @@ extension Settings {
                                 "Before enabling, dial in your settings (basal / insulin sensitivity / carb ratio), and familiarize yourself with the app."
                             )
                         },
-                        headerText: "Automated Insulin Delivery"
+                        headerText: String(localized: "Automated Insulin Delivery")
                     )
 
                     Section(
@@ -284,7 +284,7 @@ extension Settings {
                     shouldDisplayHint: $shouldDisplayHint,
                     hintLabel: hintLabel ?? "",
                     hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                    sheetTitle: "Help"
+                    sheetTitle: String(localized: "Help", comment: "Help sheet title")
                 )
             }
             .sheet(isPresented: $showShareSheet) {

+ 7 - 7
Trio/Sources/Modules/Settings/View/Subviews/NotificationsView.swift

@@ -25,7 +25,7 @@ struct NotificationsView: BaseView {
             )
         }
     )
-    @State var hintLabel: String? = "Manage iOS Preferences"
+    @State var hintLabel: String? = String(localized: "Manage iOS Preferences")
 
     @Environment(\.colorScheme) var colorScheme
     @Environment(AppState.self) var appState
@@ -50,7 +50,7 @@ struct NotificationsView: BaseView {
                         Spacer()
                         Button(
                             action: {
-                                hintLabel = "Manage iOS Preferences"
+                                hintLabel = String(localized: "Manage iOS Preferences")
                                 selectedVerboseHint = AnyView(
                                     VStack(alignment: .leading, spacing: 10) {
                                         Text(
@@ -109,7 +109,7 @@ struct NotificationsView: BaseView {
                 shouldDisplayHint: $shouldDisplayHint,
                 hintLabel: hintLabel ?? "",
                 hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                sheetTitle: "Help"
+                sheetTitle: String(localized: "Help", comment: "Help sheet title")
             )
         }
         .scrollContentBackground(.hidden)
@@ -132,11 +132,11 @@ extension NotificationsView {
 
     @ViewBuilder private func onOff(_ val: Bool) -> some View {
         if val {
-            Text(NSLocalizedString("On", comment: "Notification Setting Status is On"))
+            Text(String(localized: "On", comment: "Notification Setting Status is On"))
         } else {
             HStack {
                 Image(systemName: "exclamationmark.triangle.fill").foregroundColor(.critical)
-                Text(NSLocalizedString("Off", comment: "Notification Setting Status is Off"))
+                Text(String(localized: "Off", comment: "Notification Setting Status is Off"))
             }
         }
     }
@@ -144,7 +144,7 @@ extension NotificationsView {
     private var manageNotifications: some View {
         Button(action: { UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!) }) {
             HStack {
-                Text(NSLocalizedString("Open iOS Settings", comment: "Manage Permissions in Settings button text"))
+                Text(String(localized: "Open iOS Settings", comment: "Manage Permissions in Settings button text"))
                 Spacer()
                 Image(systemName: "chevron.right").foregroundColor(.gray).font(.footnote)
             }
@@ -154,7 +154,7 @@ extension NotificationsView {
 
     private var notificationsEnabledStatus: some View {
         HStack {
-            Text(NSLocalizedString("Notifications", comment: "Notifications Status text"))
+            Text(String(localized: "Notifications", comment: "Notifications Status text"))
             Spacer()
             onOff(!notificationsDisabled)
         }

+ 1 - 1
Trio/Sources/Modules/Settings/View/TidepoolStartView.swift

@@ -101,7 +101,7 @@ struct TidepoolStartView: BaseView {
                 hintText: Text(
                     "When connected, uploading of carbs, bolus, basal and glucose from Trio to your Tidepool account is enabled.\n\nUse your Tidepool credentials to login. If you dont already have a Tidepool account, you can sign up for one on the login page."
                 ),
-                sheetTitle: "Help"
+                sheetTitle: String(localized: "Help", comment: "Help sheet title")
             )
         }
         .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))

+ 4 - 4
Trio/Sources/Modules/ShortcutsConfig/View/ShortcutsConfigView.swift

@@ -48,13 +48,13 @@ extension ShortcutsConfig {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = "Allow Bolusing with Shortcuts"
+                            hintLabel = String(localized: "Allow Bolusing with Shortcuts")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: "Allow Bolusing with Shortcuts",
-                    miniHint: "Automate boluses using the iOS Shortcuts App.",
+                    label: String(localized: "Allow Bolusing with Shortcuts"),
+                    miniHint: String(localized: "Automate boluses using the iOS Shortcuts App."),
                     verboseHint: VStack(alignment: .leading, spacing: 10) {
                         Text("Default: OFF").bold()
                         VStack(alignment: .leading, spacing: 10) {
@@ -73,7 +73,7 @@ extension ShortcutsConfig {
                     shouldDisplayHint: $shouldDisplayHint,
                     hintLabel: hintLabel ?? "",
                     hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                    sheetTitle: "Help"
+                    sheetTitle: String(localized: "Help", comment: "Help sheet title")
                 )
             }
             .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))

+ 5 - 5
Trio/Sources/Modules/Snooze/View/SnoozeRootView.swift

@@ -62,20 +62,20 @@ extension Snooze {
 
             switch state.alarm {
             case .high:
-                celltext = NSLocalizedString("High Glucose Alarm active", comment: "High Glucose Alarm active")
+                celltext = String(localized: "High Glucose Alarm active", comment: "High Glucose Alarm active")
             case .low:
-                celltext = NSLocalizedString("Low Glucose Alarm active", comment: "Low Glucose Alarm active")
+                celltext = String(localized: "Low Glucose Alarm active", comment: "Low Glucose Alarm active")
             case .none:
-                celltext = NSLocalizedString("No Glucose Alarm active", comment: "No Glucose Alarm active")
+                celltext = String(localized: "No Glucose Alarm active", comment: "No Glucose Alarm active")
             }
 
             if state.snoozeUntilDate > Date() {
                 snoozeDescription = String(
-                    format: NSLocalizedString("snoozing until %@", comment: "snoozing until %@"),
+                    format: String(localized: "snoozing until %@", comment: "snoozing until %@"),
                     dateFormatter.string(from: state.snoozeUntilDate)
                 )
             } else {
-                snoozeDescription = NSLocalizedString("not snoozing", comment: "not snoozing")
+                snoozeDescription = String(localized: "not snoozing", comment: "not snoozing")
             }
 
             return [celltext, snoozeDescription].joined(separator: ", ")

+ 18 - 10
Trio/Sources/Modules/Stat/View/ChartsView.swift

@@ -98,15 +98,17 @@ struct ChartsView: View {
 
         let data: [ShapeModel] = [
             .init(
-                type: NSLocalizedString(
+                type: String(
+                    localized:
                     "Low",
                     comment: ""
                 ) + " (<\(low.formatted(.number.grouping(.never).rounded().precision(.fractionLength(fraction)))))",
                 percent: fetched[0].decimal
             ),
-            .init(type: NSLocalizedString("In Range", comment: ""), percent: fetched[1].decimal),
+            .init(type: String(localized: "In Range", comment: ""), percent: fetched[1].decimal),
             .init(
-                type: NSLocalizedString(
+                type: String(
+                    localized:
                     "High",
                     comment: ""
                 ) + " (>\(high.formatted(.number.grouping(.never).rounded().precision(.fractionLength(fraction)))))",
@@ -127,12 +129,14 @@ struct ChartsView: View {
             }
             .chartXAxis(.hidden)
             .chartForegroundStyleScale([
-                NSLocalizedString(
+                String(
+                    localized:
                     "Low",
                     comment: ""
                 ) + " (<\(low.formatted(.number.grouping(.never).rounded().precision(.fractionLength(fraction)))))": .red,
-                NSLocalizedString("In Range", comment: ""): .green,
-                NSLocalizedString(
+                String(localized: "In Range", comment: ""): .green,
+                String(
+                    localized:
                     "High",
                     comment: ""
                 ) + " (>\(high.formatted(.number.grouping(.never).rounded().precision(.fractionLength(fraction)))))": .orange
@@ -149,7 +153,8 @@ struct ChartsView: View {
         let fraction = units == .mmolL ? 1 : 0
         let data: [ShapeModel] = [
             .init(
-                type: NSLocalizedString(
+                type: String(
+                    localized:
                     "Low",
                     comment: ""
                 ) + " (< \(low.formatted(.number.grouping(.never).rounded().precision(.fractionLength(fraction)))))",
@@ -160,7 +165,8 @@ struct ChartsView: View {
                 percent: fetched[1].decimal
             ),
             .init(
-                type: NSLocalizedString(
+                type: String(
+                    localized:
                     "High",
                     comment: ""
                 ) + " (> \(high.formatted(.number.grouping(.never).rounded().precision(.fractionLength(fraction)))))",
@@ -184,12 +190,14 @@ struct ChartsView: View {
             )
         }
         .chartForegroundStyleScale([
-            NSLocalizedString(
+            String(
+                localized:
                 "Low",
                 comment: ""
             ) + " (< \(low.formatted(.number.grouping(.never).rounded().precision(.fractionLength(fraction)))))": .red,
             "\(low.formatted(.number.precision(.fractionLength(fraction)))) - \(high.formatted(.number.precision(.fractionLength(fraction))))": .green,
-            NSLocalizedString(
+            String(
+                localized:
                 "High",
                 comment: ""
             ) + " (> \(high.formatted(.number.grouping(.never).rounded().precision(.fractionLength(fraction)))))": .orange

+ 1 - 1
Trio/Sources/Modules/Stat/View/StatRootView.swift

@@ -122,7 +122,7 @@ extension Stat {
                 chart().padding(.top, 20)
                 Picker("Duration", selection: $state.selectedDuration) {
                     ForEach(Stat.StateModel.Duration.allCases) { duration in
-                        Text(NSLocalizedString(duration.rawValue, comment: "")).tag(Optional(duration))
+                        Text(duration.rawValue).tag(Optional(duration))
                     }
                 }.onChange(of: state.selectedDuration) { _, newValue in
                     state.setupGlucoseArray(for: newValue)

+ 16 - 12
Trio/Sources/Modules/TargetBehavoir/View/TargetBehavoirRootView.swift

@@ -26,7 +26,8 @@ extension TargetBehavoir {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString(
+                            hintLabel = String(
+                                localized:
                                 "High Temp Target Raises Sensitivity",
                                 comment: "High Temp Target Raises Sensitivity"
                             )
@@ -34,7 +35,8 @@ extension TargetBehavoir {
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: NSLocalizedString(
+                    label: String(
+                        localized:
                         "High Temp Target Raises Sensitivity",
                         comment: "High Temp Target Raises Sensitivity"
                     ),
@@ -50,7 +52,7 @@ extension TargetBehavoir {
                         )
                         Text("Note: The effect of this can be adjusted with the Half Basal Exercise Target")
                     },
-                    headerText: "Algorithmic Target Settings"
+                    headerText: String(localized: "Algorithmic Target Settings")
                 )
 
                 SettingInputSection(
@@ -61,7 +63,8 @@ extension TargetBehavoir {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString(
+                            hintLabel = String(
+                                localized:
                                 "Low Temp Target Lowers Sensitivity",
                                 comment: "Low Temp Target Lowers Sensitivity"
                             )
@@ -69,7 +72,8 @@ extension TargetBehavoir {
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: NSLocalizedString(
+                    label: String(
+                        localized:
                         "Low Temp Target Lowers Sensitivity",
                         comment: "Low Temp Target Lowers Sensitivity"
                     ),
@@ -95,12 +99,12 @@ extension TargetBehavoir {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Sensitivity Raises Target", comment: "Sensitivity Raises Target")
+                            hintLabel = String(localized: "Sensitivity Raises Target", comment: "Sensitivity Raises Target")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: NSLocalizedString("Sensitivity Raises Target", comment: "Sensitivity Raises Target"),
+                    label: String(localized: "Sensitivity Raises Target", comment: "Sensitivity Raises Target"),
                     miniHint: "Raise target glucose if when Autosens Ratio is >1.",
                     verboseHint: VStack(alignment: .leading, spacing: 10) {
                         Text("Default: OFF").bold()
@@ -118,12 +122,12 @@ extension TargetBehavoir {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Resistance Lowers Target", comment: "Resistance Lowers Target")
+                            hintLabel = String(localized: "Resistance Lowers Target", comment: "Resistance Lowers Target")
                         }
                     ),
                     units: state.units,
                     type: .boolean,
-                    label: NSLocalizedString("Resistance Lowers Target", comment: "Resistance Lowers Target"),
+                    label: String(localized: "Resistance Lowers Target", comment: "Resistance Lowers Target"),
                     miniHint: "Lower target glucose when Autosens Ratio is <1.",
                     verboseHint: VStack(alignment: .leading, spacing: 10) {
                         Text("Default: OFF").bold()
@@ -141,12 +145,12 @@ extension TargetBehavoir {
                         get: { selectedVerboseHint },
                         set: {
                             selectedVerboseHint = $0.map { AnyView($0) }
-                            hintLabel = NSLocalizedString("Half Basal Exercise Target", comment: "Half Basal Exercise Target")
+                            hintLabel = String(localized: "Half Basal Exercise Target", comment: "Half Basal Exercise Target")
                         }
                     ),
                     units: state.units,
                     type: .decimal("halfBasalExerciseTarget"),
-                    label: NSLocalizedString("Half Basal Exercise Target", comment: "Half Basal Exercise Target"),
+                    label: String(localized: "Half Basal Exercise Target", comment: "Half Basal Exercise Target"),
                     miniHint: "Scales down your basal rate to 50% at this value.",
                     verboseHint:
                     VStack(alignment: .leading, spacing: 10) {
@@ -173,7 +177,7 @@ extension TargetBehavoir {
                     shouldDisplayHint: $shouldDisplayHint,
                     hintLabel: hintLabel ?? "",
                     hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                    sheetTitle: "Help"
+                    sheetTitle: String(localized: "Help", comment: "Help sheet title")
                 )
             }
             .scrollContentBackground(.hidden).background(appState.trioBackgroundColor(for: colorScheme))

+ 2 - 3
Trio/Sources/Modules/Treatments/TreatmentsStateModel.swift

@@ -595,9 +595,8 @@ extension Treatments {
         }
 
         func addPresetToNewMeal() {
-            let test: String = selection?.dish ?? "dontAdd"
-            if test != "dontAdd" {
-                summation.append(test)
+            if let selection = selection, let dish = selection.dish {
+                summation.append(dish)
             }
         }
 

+ 3 - 3
Trio/Sources/Modules/Treatments/View/PopupView.swift

@@ -131,13 +131,13 @@ struct PopupView: View {
 
     var calcSettingsSecondRow: some View {
         GridRow {
-            Text(state.carbRatio.formatted() + " " + NSLocalizedString("g/U", comment: " grams per Unit"))
+            Text(state.carbRatio.formatted() + " " + String(localized: "g/U", comment: " grams per Unit"))
                 .gridCellAnchor(.leading)
 
             let isf = state.units == .mmolL ? state.isf.formattedAsMmolL : state.isf.description
             Text(
                 isf + " " + state.units
-                    .rawValue + NSLocalizedString("/U", comment: "/Insulin unit")
+                    .rawValue + String(localized: "/U", comment: "/Insulin unit")
             ).gridCellAnchor(.leading)
 
             let target = state.units == .mmolL ? state.target.formattedAsMmolL : state.target.description
@@ -235,7 +235,7 @@ struct PopupView: View {
                 Text(
                     state.wholeCob
                         .formatted(.number.grouping(.never).rounded().precision(.fractionLength(fractionDigits))) +
-                        NSLocalizedString(" g", comment: "grams")
+                        String(localized: " g", comment: "grams")
                 )
             }
 

+ 2 - 1
Trio/Sources/Modules/Treatments/View/TreatmentsRootView.swift

@@ -266,7 +266,8 @@ extension Treatments {
                                         )
 
                                         Text(
-                                            NSLocalizedString(
+                                            String(
+                                                localized:
                                                 " U",
                                                 comment: "Unit in number of units delivered (keep the space character!)"
                                             )

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 17 - 17
Trio/Sources/Modules/UserInterfaceSettings/View/UserInterfaceSettingsRootView.swift


+ 5 - 5
Trio/Sources/Modules/WatchConfig/View/WatchConfigAppleWatchView.swift

@@ -30,17 +30,17 @@ struct WatchConfigAppleWatchView: BaseView {
                     get: { selectedVerboseHint },
                     set: {
                         selectedVerboseHint = $0.map { AnyView($0) }
-                        hintLabel = "Confirm Bolus Faster"
+                        hintLabel = String(localized: "Confirm Bolus Faster")
                     }
                 ),
                 units: state.units,
                 type: .boolean,
-                label: "Confirm Bolus Faster",
-                miniHint: "Reduce the number of crown rotations required for bolus confirmation.",
+                label: String(localized: "Confirm Bolus Faster"),
+                miniHint: String(localized: "Reduce the number of crown rotations required for bolus confirmation."),
                 verboseHint: Text(
                     "Enabling this feature lowers the number of turns on the crown dial required when confirming a bolus."
                 ),
-                headerText: "Apple Watch Configuration"
+                headerText: String(localized: "Apple Watch Configuration")
             )
 
             Section(
@@ -63,7 +63,7 @@ struct WatchConfigAppleWatchView: BaseView {
                 shouldDisplayHint: $shouldDisplayHint,
                 hintLabel: hintLabel ?? "",
                 hintText: selectedVerboseHint ?? AnyView(EmptyView()),
-                sheetTitle: "Help"
+                sheetTitle: String(localized: "Help", comment: "Help sheet title")
             )
         }
         .navigationTitle("Apple Watch")

+ 1 - 1
Trio/Sources/Modules/WatchConfig/View/WatchConfigGarminView.swift

@@ -79,7 +79,7 @@ struct WatchConfigGarminView: View {
                 hintText: Text(
                     "Add Garmin Device to Trio. Please look at the docs to see which devices are supported."
                 ),
-                sheetTitle: "Help"
+                sheetTitle: String(localized: "Help", comment: "Help sheet title")
             )
         }
         .navigationTitle("Garmin")

+ 20 - 18
Trio/Sources/Services/UserNotifications/UserNotificationsManager.swift

@@ -166,17 +166,18 @@ final class BaseUserNotificationsManager: NSObject, UserNotificationsManager, In
         let content = UNMutableNotificationContent()
 
         if snoozeUntilDate > Date() {
-            titles.append(NSLocalizedString("(Snoozed)", comment: "(Snoozed)"))
+            titles.append(String(localized: "(Snoozed)", comment: "(Snoozed)"))
         } else {
             content.sound = .default
             playSoundIfNeeded()
         }
 
-        titles.append(String(format: NSLocalizedString("Carbs required: %d g", comment: "Carbs required"), carbs))
+        titles.append(String(format: String(localized: "Carbs required: %d g", comment: "Carbs required"), carbs))
 
         content.title = titles.joined(separator: " ")
         content.body = String(
-            format: NSLocalizedString(
+            format: String(
+                localized:
                 "To prevent LOW required %d g of carbs",
                 comment: "To prevent LOW required %d g of carbs"
             ),
@@ -186,8 +187,8 @@ final class BaseUserNotificationsManager: NSObject, UserNotificationsManager, In
     }
 
     private func scheduleMissingLoopNotifiactions(date _: Date) {
-        let title = NSLocalizedString("Trio Not Active", comment: "Trio Not Active")
-        let body = NSLocalizedString("Last loop was more than %d min ago", comment: "Last loop was more than %d min ago")
+        let title = String(localized: "Trio Not Active", comment: "Trio Not Active")
+        let body = String(localized: "Last loop was more than %d min ago", comment: "Last loop was more than %d min ago")
 
         let firstContent = UNMutableNotificationContent()
         firstContent.title = title
@@ -221,8 +222,9 @@ final class BaseUserNotificationsManager: NSObject, UserNotificationsManager, In
     }
 
     private func notifyBolusFailure() {
-        let title = NSLocalizedString("Bolus failed", comment: "Bolus failed")
-        let body = NSLocalizedString(
+        let title = String(localized: "Bolus failed", comment: "Bolus failed")
+        let body = String(
+            localized:
             "Bolus failed or inaccurate. Check pump history before repeating.",
             comment: "Bolus failed or inaccurate. Check pump history before repeating."
         )
@@ -278,13 +280,13 @@ final class BaseUserNotificationsManager: NSObject, UserNotificationsManager, In
 
             switch glucoseStorage.alarm {
             case .none:
-                titles.append(NSLocalizedString("Glucose", comment: "Glucose"))
+                titles.append(String(localized: "Glucose", comment: "Glucose"))
             case .low:
-                titles.append(NSLocalizedString("LOWALERT!", comment: "LOWALERT!"))
+                titles.append(String(localized: "LOWALERT!", comment: "LOWALERT!"))
                 messageType = MessageType.warning
                 notificationAlarm = true
             case .high:
-                titles.append(NSLocalizedString("HIGHALERT!", comment: "HIGHALERT!"))
+                titles.append(String(localized: "HIGHALERT!", comment: "HIGHALERT!"))
                 messageType = MessageType.warning
                 notificationAlarm = true
             }
@@ -297,7 +299,7 @@ final class BaseUserNotificationsManager: NSObject, UserNotificationsManager, In
             ) + infoBody()
 
             if snoozeUntilDate > Date() {
-                titles.append(NSLocalizedString("(Snoozed)", comment: "(Snoozed)"))
+                titles.append(String(localized: "(Snoozed)", comment: "(Snoozed)"))
                 notificationAlarm = false
             } else {
                 titles.append(body)
@@ -333,7 +335,7 @@ final class BaseUserNotificationsManager: NSObject, UserNotificationsManager, In
             .string(from: Double(
                 units == .mmolL ? glucoseValue
                     .asMmolL : Decimal(glucoseValue)
-            ) as NSNumber)! + " " + NSLocalizedString(units.rawValue, comment: "units")
+            ) as NSNumber)! + " " + String(localized: "\(units.rawValue)", comment: "units")
         let directionText = direction ?? "↔︎"
         let deltaText = delta
             .map {
@@ -363,7 +365,7 @@ final class BaseUserNotificationsManager: NSObject, UserNotificationsManager, In
                 body.append(
                     "\n"
                         + String(
-                            format: NSLocalizedString("Nightscout ping: %d ms", comment: "Nightscout ping"),
+                            format: String(localized: "Nightscout ping: %d ms", comment: "Nightscout ping"),
                             Int(ping * 1000)
                         )
                 )
@@ -374,7 +376,7 @@ final class BaseUserNotificationsManager: NSObject, UserNotificationsManager, In
                 body.append(
                     "\n"
                         + String(
-                            format: NSLocalizedString("Transmitter: %@%%", comment: "Transmitter: %@%%"),
+                            format: String(localized: "Transmitter: %@%%", comment: "Transmitter: %@%%"),
                             "\(transmitterBattery)"
                         )
                 )
@@ -502,11 +504,11 @@ extension BaseUserNotificationsManager: alertMessageNotificationObserver {
         if message.title == "" {
             switch message.type {
             case .info:
-                content.title = NSLocalizedString("Info", comment: "Info title")
+                content.title = String(localized: "Info", comment: "Info title")
             case .warning:
-                content.title = NSLocalizedString("Warning", comment: "Warning title")
+                content.title = String(localized: "Warning", comment: "Warning title")
             case .error:
-                content.title = NSLocalizedString("Error", comment: "Error title")
+                content.title = String(localized: "Error", comment: "Error title")
             default:
                 content.title = message.title
             }
@@ -538,7 +540,7 @@ extension BaseUserNotificationsManager: alertMessageNotificationObserver {
         default: break
         }
 
-        content.body = NSLocalizedString(message.content, comment: "Info message")
+        content.body = String(localized: "\(message.content)", comment: "Info message")
         content.sound = .default
         addRequest(
             identifier: identifier,

+ 4 - 4
Trio/Sources/Shortcuts/State/ListStateView.swift

@@ -55,7 +55,7 @@ struct ListStateView: View {
                 Text("IOB").font(.caption).foregroundColor(.secondary)
                 Text(
                     (numberFormatter.string(from: (state.iob ?? 0) as NSNumber) ?? "0") +
-                        NSLocalizedString(" U", comment: "Insulin unit")
+                        String(localized: " U", comment: "Insulin unit")
                 )
                 .font(.body).fontWeight(.bold)
             }
@@ -63,7 +63,7 @@ struct ListStateView: View {
                 Text("COB").font(.caption).foregroundColor(.secondary)
                 Text(
                     (numberFormatter.string(from: (state.cob ?? 0) as NSNumber) ?? "0") +
-                        NSLocalizedString(" g", comment: "gram of carbs")
+                        String(localized: " g", comment: "gram of carbs")
                 )
                 .font(.body).fontWeight(.bold)
             }
@@ -79,9 +79,9 @@ struct ListStateView: View {
                 let minutes = -1 * state.date.timeIntervalSinceNow / 60
                 let text = timaAgoFormatter.string(for: Double(minutes)) ?? ""
                 Text(
-                    minutes <= 1 ? "< 1 " + NSLocalizedString("min", comment: "Short form for minutes") : (
+                    minutes <= 1 ? "< 1 " + String(localized: "min", comment: "Short form for minutes") : (
                         text + " " +
-                            NSLocalizedString("min", comment: "Short form for minutes") + " "
+                            String(localized: "min", comment: "Short form for minutes") + " "
                     )
                 )
                 .font(.caption2).foregroundColor(.secondary)

+ 1 - 1
Trio/Sources/Shortcuts/State/StateIntentRequest.swift

@@ -83,7 +83,7 @@ final class StateIntentRequest: BaseIntentsRequest {
                     .asMmolL : Decimal(lastGlucose)
             ) as NSNumber)!
 
-            let directionAsString = lastValue.direction ?? "none"
+            let directionAsString = lastValue.direction ?? String(localized: "none")
 
             let deltaAsString = delta
                 .map {