diff --git a/.gitignore b/.gitignore index 075fb31..6fc83a5 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ DerivedData/ ## Xcode user state *.xcuserstate *.xcscmblueprint +*.xcresult ## Obj-C/Swift specific *.hmap diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9c30113..9b0de6d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -83,6 +83,6 @@ Include the iOS version, device or simulator, and steps to reproduce. For weathe - Migrate one `ObservableObject` view model to `@Observable` - Replace `UIImpactFeedbackGenerator` / `UINotificationFeedbackGenerator` call sites with `.sensoryFeedback` -- Extract user-facing strings into a String Catalog (none exists yet, all copy is inline English) +- Add a new locale to the String Catalog (English and Spanish ship today) - Split one of the remaining 600+ line views into focused subviews - VoiceOver labels for weather cards, forecast charts, and trigger indicators diff --git a/README.md b/README.md index f941875..ec5c252 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ Captured on iOS 26 (iPhone). SunHat is iPhone-first. iPad, widget, and watch sur |---|---| | Xcode | 26+ | | Swift | 6.2 | -| Minimum iOS | 26.0 | +| Minimum iOS | 26.5 | | Dependencies | Google Mobile Ads + User Messaging Platform (SPM), for the ad-supported free tier. Everything else is Apple frameworks. | No CocoaPods, no Carthage. The only SPM packages are Google Mobile Ads and its @@ -161,7 +161,7 @@ Version 1.0, iPhone-first, preparing for App Store submission. ### Toolchain note -The project targets Xcode 26 and Swift 6.2, but it currently builds against the Xcode 27 beta, which is stricter about actor isolation for protocol conformances and introduced a `LinearGradient` `.opacity` ambiguity. Both are handled in-tree with comments. If you're on the released Xcode, the code still compiles. +The project builds with Xcode 26 and Swift 6.2. It also compiles against the Xcode 27 beta, which is stricter about actor isolation for protocol conformances and introduced a `LinearGradient` `.opacity` ambiguity; both are handled in-tree with comments. CI runs on `macos-latest` via GitHub Actions. The build-for-testing step uses the `SunHatUnitTests` scheme. diff --git a/SunHat/AppIntents/SunHatShortcuts.swift b/SunHat/AppIntents/SunHatShortcuts.swift index 2e70a7e..2b82590 100644 --- a/SunHat/AppIntents/SunHatShortcuts.swift +++ b/SunHat/AppIntents/SunHatShortcuts.swift @@ -2,7 +2,7 @@ // SunHatShortcuts.swift // SunHat // -// Created by Codex on 6/27/26. +// Created by Wesley Keetch on 6/27/26. // import AppIntents diff --git a/SunHat/Models/WeatherCondition+Display.swift b/SunHat/Models/WeatherCondition+Display.swift index 37ff600..d9a9f27 100644 --- a/SunHat/Models/WeatherCondition+Display.swift +++ b/SunHat/Models/WeatherCondition+Display.swift @@ -2,7 +2,7 @@ // WeatherCondition+Display.swift // SunHat // -// Created by Codex on 6/2/26. +// Created by Wesley Keetch on 6/2/26. // import SwiftUI diff --git a/SunHat/Services/Engagement/AppLifecyclePromptCoordinator.swift b/SunHat/Services/Engagement/AppLifecyclePromptCoordinator.swift index ca133ab..8f2ed3e 100644 --- a/SunHat/Services/Engagement/AppLifecyclePromptCoordinator.swift +++ b/SunHat/Services/Engagement/AppLifecyclePromptCoordinator.swift @@ -2,7 +2,7 @@ // AppLifecyclePromptCoordinator.swift // SunHat // -// Created by Codex on 7/3/26. +// Created by Wesley Keetch on 7/3/26. // import Foundation diff --git a/SunHat/Services/Location/LocationDisplayFormatter.swift b/SunHat/Services/Location/LocationDisplayFormatter.swift index f63c86f..9b5f5a3 100644 --- a/SunHat/Services/Location/LocationDisplayFormatter.swift +++ b/SunHat/Services/Location/LocationDisplayFormatter.swift @@ -2,7 +2,7 @@ // LocationDisplayFormatter.swift // SunHat // -// Created by Codex on 6/3/26. +// Created by Wesley Keetch on 6/3/26. // import CoreLocation diff --git a/SunHat/Services/Location/LocationManaging.swift b/SunHat/Services/Location/LocationManaging.swift index faea5fe..2109b77 100644 --- a/SunHat/Services/Location/LocationManaging.swift +++ b/SunHat/Services/Location/LocationManaging.swift @@ -2,7 +2,7 @@ // LocationManaging.swift // SunHat // -// Created by Codex on 6/2/26. +// Created by Wesley Keetch on 6/2/26. // import CoreLocation diff --git a/SunHat/Services/Notifications/SunHatNotificationCategoryRegistry.swift b/SunHat/Services/Notifications/SunHatNotificationCategoryRegistry.swift index 601ba44..c947be1 100644 --- a/SunHat/Services/Notifications/SunHatNotificationCategoryRegistry.swift +++ b/SunHat/Services/Notifications/SunHatNotificationCategoryRegistry.swift @@ -2,7 +2,7 @@ // SunHatNotificationCategoryRegistry.swift // SunHat // -// Created by Codex on 6/27/26. +// Created by Wesley Keetch on 6/27/26. // import Foundation diff --git a/SunHat/Services/Routing/SunHatIntentHandoff.swift b/SunHat/Services/Routing/SunHatIntentHandoff.swift index 4fbe32e..d71e61a 100644 --- a/SunHat/Services/Routing/SunHatIntentHandoff.swift +++ b/SunHat/Services/Routing/SunHatIntentHandoff.swift @@ -2,7 +2,7 @@ // SunHatIntentHandoff.swift // SunHat // -// Created by Codex on 6/27/26. +// Created by Wesley Keetch on 6/27/26. // import Foundation diff --git a/SunHat/Services/Search/SunHatSearchIndexer.swift b/SunHat/Services/Search/SunHatSearchIndexer.swift index 97302cc..32182ef 100644 --- a/SunHat/Services/Search/SunHatSearchIndexer.swift +++ b/SunHat/Services/Search/SunHatSearchIndexer.swift @@ -2,7 +2,7 @@ // SunHatSearchIndexer.swift // SunHat // -// Created by Codex on 6/27/26. +// Created by Wesley Keetch on 6/27/26. // import CoreSpotlight diff --git a/SunHat/Services/Settings/NotificationPermissionProviding.swift b/SunHat/Services/Settings/NotificationPermissionProviding.swift index 54b5088..ec3a99a 100644 --- a/SunHat/Services/Settings/NotificationPermissionProviding.swift +++ b/SunHat/Services/Settings/NotificationPermissionProviding.swift @@ -2,7 +2,7 @@ // NotificationPermissionProviding.swift // SunHat // -// Created by Claude on 6/12/26. +// Created by Wesley Keetch on 6/12/26. // import Foundation diff --git a/SunHat/Services/Settings/SettingsOpening.swift b/SunHat/Services/Settings/SettingsOpening.swift index 015bb08..0292fb4 100644 --- a/SunHat/Services/Settings/SettingsOpening.swift +++ b/SunHat/Services/Settings/SettingsOpening.swift @@ -2,7 +2,7 @@ // SettingsOpening.swift // SunHat // -// Created by Codex on 6/2/26. +// Created by Wesley Keetch on 6/2/26. // import Foundation diff --git a/SunHat/Services/Weather/WeatherProviding.swift b/SunHat/Services/Weather/WeatherProviding.swift index cd444d9..576841e 100644 --- a/SunHat/Services/Weather/WeatherProviding.swift +++ b/SunHat/Services/Weather/WeatherProviding.swift @@ -2,7 +2,7 @@ // WeatherProviding.swift // SunHat // -// Created by Codex on 6/2/26. +// Created by Wesley Keetch on 6/2/26. // import Combine diff --git a/SunHat/Utilities/Motion/SunHatMotion.swift b/SunHat/Utilities/Motion/SunHatMotion.swift index df9568f..df87449 100644 --- a/SunHat/Utilities/Motion/SunHatMotion.swift +++ b/SunHat/Utilities/Motion/SunHatMotion.swift @@ -2,7 +2,7 @@ // SunHatMotion.swift // SunHat // -// Created by Codex on 6/27/26. +// Created by Wesley Keetch on 6/27/26. // import SwiftUI diff --git a/SunHat/Utilities/Theme/SunHatAtmospherePalette.swift b/SunHat/Utilities/Theme/SunHatAtmospherePalette.swift index 33c988d..a530c3c 100644 --- a/SunHat/Utilities/Theme/SunHatAtmospherePalette.swift +++ b/SunHat/Utilities/Theme/SunHatAtmospherePalette.swift @@ -2,7 +2,7 @@ // SunHatAtmospherePalette.swift // SunHat // -// Created by Codex on 7/3/26. +// Created by Wesley Keetch on 7/3/26. // import SwiftUI diff --git a/SunHat/Utilities/Theme/SunHatSurfaceModifier.swift b/SunHat/Utilities/Theme/SunHatSurfaceModifier.swift index 9560d4e..dbebd5d 100644 --- a/SunHat/Utilities/Theme/SunHatSurfaceModifier.swift +++ b/SunHat/Utilities/Theme/SunHatSurfaceModifier.swift @@ -2,7 +2,7 @@ // SunHatSurfaceModifier.swift // SunHat // -// Created by Codex on 7/2/26. +// Created by Wesley Keetch on 7/2/26. // import SwiftUI diff --git a/SunHat/Utilities/Theme/WeatherBackdropPalette.swift b/SunHat/Utilities/Theme/WeatherBackdropPalette.swift index ec3ebc2..9067f8c 100644 --- a/SunHat/Utilities/Theme/WeatherBackdropPalette.swift +++ b/SunHat/Utilities/Theme/WeatherBackdropPalette.swift @@ -2,7 +2,7 @@ // WeatherBackdropPalette.swift // SunHat // -// Created by Codex on 7/3/26. +// Created by Wesley Keetch on 7/3/26. // import Foundation diff --git a/SunHat/Views/Components/LiquidGlassFieldBackground.swift b/SunHat/Views/Components/LiquidGlassFieldBackground.swift index 35a8046..3f3e08e 100644 --- a/SunHat/Views/Components/LiquidGlassFieldBackground.swift +++ b/SunHat/Views/Components/LiquidGlassFieldBackground.swift @@ -2,7 +2,7 @@ // LiquidGlassFieldBackground.swift // SunHat // -// Created by Claude on 6/12/26. +// Created by Wesley Keetch on 6/12/26. // import SwiftUI diff --git a/SunHat/Views/Components/SelectableTileLabel.swift b/SunHat/Views/Components/SelectableTileLabel.swift index 647ff5c..2fe269e 100644 --- a/SunHat/Views/Components/SelectableTileLabel.swift +++ b/SunHat/Views/Components/SelectableTileLabel.swift @@ -2,7 +2,7 @@ // SelectableTileLabel.swift // SunHat // -// Created by Claude on 6/12/26. +// Created by Wesley Keetch on 6/12/26. // import SwiftUI diff --git a/SunHat/Views/Components/SettingsIconLabel.swift b/SunHat/Views/Components/SettingsIconLabel.swift index e6e6859..0d66962 100644 --- a/SunHat/Views/Components/SettingsIconLabel.swift +++ b/SunHat/Views/Components/SettingsIconLabel.swift @@ -2,7 +2,7 @@ // SettingsIconLabel.swift // SunHat // -// Created by Claude on 6/12/26. +// Created by Wesley Keetch on 6/12/26. // import SwiftUI diff --git a/SunHat/Views/Components/SunHatProductComponents.swift b/SunHat/Views/Components/SunHatProductComponents.swift index de22a0c..cb296f0 100644 --- a/SunHat/Views/Components/SunHatProductComponents.swift +++ b/SunHat/Views/Components/SunHatProductComponents.swift @@ -2,7 +2,7 @@ // SunHatProductComponents.swift // SunHat // -// Created by Codex on 6/28/26. +// Created by Wesley Keetch on 6/28/26. // import SwiftUI diff --git a/SunHat/Views/Dashboard/DashboardComponents.swift b/SunHat/Views/Dashboard/DashboardComponents.swift index 65780fd..9a1d5df 100644 --- a/SunHat/Views/Dashboard/DashboardComponents.swift +++ b/SunHat/Views/Dashboard/DashboardComponents.swift @@ -2,7 +2,7 @@ // DashboardComponents.swift // SunHat // -// Created by Codex on 6/2/26. +// Created by Wesley Keetch on 6/2/26. // import SwiftUI diff --git a/SunHat/Views/Dashboard/SunHatForecastRibbon.swift b/SunHat/Views/Dashboard/SunHatForecastRibbon.swift index 3b9d521..c1eaac7 100644 --- a/SunHat/Views/Dashboard/SunHatForecastRibbon.swift +++ b/SunHat/Views/Dashboard/SunHatForecastRibbon.swift @@ -2,7 +2,7 @@ // SunHatForecastRibbon.swift // SunHat // -// Created by Codex on 7/3/26. +// Created by Wesley Keetch on 7/3/26. // import SwiftUI diff --git a/SunHat/Views/Dashboard/SunHatWeatherDial.swift b/SunHat/Views/Dashboard/SunHatWeatherDial.swift index bc4f5c3..3d099d2 100644 --- a/SunHat/Views/Dashboard/SunHatWeatherDial.swift +++ b/SunHat/Views/Dashboard/SunHatWeatherDial.swift @@ -2,7 +2,7 @@ // SunHatWeatherDial.swift // SunHat // -// Created by Codex on 7/3/26. +// Created by Wesley Keetch on 7/3/26. // import SwiftUI diff --git a/SunHat/Views/Dashboard/WeatherHeroMetricPill.swift b/SunHat/Views/Dashboard/WeatherHeroMetricPill.swift index e88590d..64e883d 100644 --- a/SunHat/Views/Dashboard/WeatherHeroMetricPill.swift +++ b/SunHat/Views/Dashboard/WeatherHeroMetricPill.swift @@ -2,7 +2,7 @@ // WeatherHeroMetricPill.swift // SunHat // -// Created by Codex on 7/3/26. +// Created by Wesley Keetch on 7/3/26. // import SwiftUI diff --git a/SunHat/Views/Engagement/AppFeedbackFormView.swift b/SunHat/Views/Engagement/AppFeedbackFormView.swift index 35c51a1..50222eb 100644 --- a/SunHat/Views/Engagement/AppFeedbackFormView.swift +++ b/SunHat/Views/Engagement/AppFeedbackFormView.swift @@ -2,7 +2,7 @@ // AppFeedbackFormView.swift // SunHat // -// Created by Codex on 7/3/26. +// Created by Wesley Keetch on 7/3/26. // import SwiftUI diff --git a/SunHat/Views/Location/LocationPickerCurrentLocationCard.swift b/SunHat/Views/Location/LocationPickerCurrentLocationCard.swift index 4e9cb88..bd407ba 100644 --- a/SunHat/Views/Location/LocationPickerCurrentLocationCard.swift +++ b/SunHat/Views/Location/LocationPickerCurrentLocationCard.swift @@ -2,7 +2,7 @@ // LocationPickerCurrentLocationCard.swift // SunHat // -// Created by Codex on 7/3/26. +// Created by Wesley Keetch on 7/3/26. // import SwiftUI diff --git a/SunHat/Views/Location/LocationPickerEmptyGuidance.swift b/SunHat/Views/Location/LocationPickerEmptyGuidance.swift index 8695218..af06767 100644 --- a/SunHat/Views/Location/LocationPickerEmptyGuidance.swift +++ b/SunHat/Views/Location/LocationPickerEmptyGuidance.swift @@ -2,7 +2,7 @@ // LocationPickerEmptyGuidance.swift // SunHat // -// Created by Codex on 7/3/26. +// Created by Wesley Keetch on 7/3/26. // import SwiftUI diff --git a/SunHat/Views/Location/LocationPickerSearchField.swift b/SunHat/Views/Location/LocationPickerSearchField.swift index 6f212dd..1448e12 100644 --- a/SunHat/Views/Location/LocationPickerSearchField.swift +++ b/SunHat/Views/Location/LocationPickerSearchField.swift @@ -2,7 +2,7 @@ // LocationPickerSearchField.swift // SunHat // -// Created by Codex on 7/3/26. +// Created by Wesley Keetch on 7/3/26. // import SwiftUI diff --git a/SunHat/Views/Reminders/FilterChip.swift b/SunHat/Views/Reminders/FilterChip.swift index 202397d..460e350 100644 --- a/SunHat/Views/Reminders/FilterChip.swift +++ b/SunHat/Views/Reminders/FilterChip.swift @@ -2,7 +2,7 @@ // FilterChip.swift // SunHat // -// Created by Codex on 7/3/26. +// Created by Wesley Keetch on 7/3/26. // import SwiftUI diff --git a/SunHat/Views/Reminders/ReminderGlassCard.swift b/SunHat/Views/Reminders/ReminderGlassCard.swift index 8d118db..cc0b4d6 100644 --- a/SunHat/Views/Reminders/ReminderGlassCard.swift +++ b/SunHat/Views/Reminders/ReminderGlassCard.swift @@ -2,7 +2,7 @@ // ReminderGlassCard.swift // SunHat // -// Created by Codex on 7/3/26. +// Created by Wesley Keetch on 7/3/26. // import SwiftUI diff --git a/SunHat/Views/Reminders/StreamlinedCurrentWeatherSection.swift b/SunHat/Views/Reminders/StreamlinedCurrentWeatherSection.swift index c2c4f8a..ffbef60 100644 --- a/SunHat/Views/Reminders/StreamlinedCurrentWeatherSection.swift +++ b/SunHat/Views/Reminders/StreamlinedCurrentWeatherSection.swift @@ -2,7 +2,7 @@ // StreamlinedCurrentWeatherSection.swift // SunHat // -// Created by Claude on 6/12/26. +// Created by Wesley Keetch on 6/12/26. // import SwiftUI diff --git a/SunHat/Views/Reminders/StreamlinedTimePreferencesSection.swift b/SunHat/Views/Reminders/StreamlinedTimePreferencesSection.swift index 35e85d0..e3eae31 100644 --- a/SunHat/Views/Reminders/StreamlinedTimePreferencesSection.swift +++ b/SunHat/Views/Reminders/StreamlinedTimePreferencesSection.swift @@ -2,7 +2,7 @@ // StreamlinedTimePreferencesSection.swift // SunHat // -// Created by Claude on 6/12/26. +// Created by Wesley Keetch on 6/12/26. // import SwiftUI diff --git a/SunHat/Views/Reminders/StreamlinedWeatherConditionsSection.swift b/SunHat/Views/Reminders/StreamlinedWeatherConditionsSection.swift index e3cb6c2..aa6498e 100644 --- a/SunHat/Views/Reminders/StreamlinedWeatherConditionsSection.swift +++ b/SunHat/Views/Reminders/StreamlinedWeatherConditionsSection.swift @@ -2,7 +2,7 @@ // StreamlinedWeatherConditionsSection.swift // SunHat // -// Created by Claude on 6/12/26. +// Created by Wesley Keetch on 6/12/26. // import SwiftUI diff --git a/SunHat/Views/Settings/QuietHoursTimeRow.swift b/SunHat/Views/Settings/QuietHoursTimeRow.swift index 49f7387..0794f32 100644 --- a/SunHat/Views/Settings/QuietHoursTimeRow.swift +++ b/SunHat/Views/Settings/QuietHoursTimeRow.swift @@ -2,7 +2,7 @@ // QuietHoursTimeRow.swift // SunHat // -// Created by Codex on 7/3/26. +// Created by Wesley Keetch on 7/3/26. // import SwiftUI diff --git a/SunHat/Views/Settings/QuietHoursWindowPicker.swift b/SunHat/Views/Settings/QuietHoursWindowPicker.swift index 02e0be4..2dd3017 100644 --- a/SunHat/Views/Settings/QuietHoursWindowPicker.swift +++ b/SunHat/Views/Settings/QuietHoursWindowPicker.swift @@ -2,7 +2,7 @@ // QuietHoursWindowPicker.swift // SunHat // -// Created by Codex on 7/3/26. +// Created by Wesley Keetch on 7/3/26. // import SwiftUI diff --git a/SunHatTests/AppLifecyclePromptCoordinatorTests.swift b/SunHatTests/AppLifecyclePromptCoordinatorTests.swift index 2d11cfe..07e5c36 100644 --- a/SunHatTests/AppLifecyclePromptCoordinatorTests.swift +++ b/SunHatTests/AppLifecyclePromptCoordinatorTests.swift @@ -2,7 +2,7 @@ // AppLifecyclePromptCoordinatorTests.swift // SunHatTests // -// Created by Codex on 7/3/26. +// Created by Wesley Keetch on 7/3/26. // import Foundation diff --git a/SunHatTests/LocationDisplayFormatterTests.swift b/SunHatTests/LocationDisplayFormatterTests.swift index 810ebf6..b2c8335 100644 --- a/SunHatTests/LocationDisplayFormatterTests.swift +++ b/SunHatTests/LocationDisplayFormatterTests.swift @@ -2,7 +2,7 @@ // LocationDisplayFormatterTests.swift // SunHatTests // -// Created by Codex on 6/3/26. +// Created by Wesley Keetch on 6/3/26. // import Foundation