diff options
| -rw-r--r-- | SolverVTests/Utilities/AppGroupManagerTests.swift | 58 | ||||
| -rw-r--r-- | Solverv/Utilities/AppGroupManager.swift | 67 |
2 files changed, 125 insertions, 0 deletions
diff --git a/SolverVTests/Utilities/AppGroupManagerTests.swift b/SolverVTests/Utilities/AppGroupManagerTests.swift new file mode 100644 index 0000000..9b5e587 --- /dev/null +++ b/SolverVTests/Utilities/AppGroupManagerTests.swift @@ -0,0 +1,58 @@ +import XCTest +@testable import Solverv + +final class AppGroupManagerTests: XCTestCase { + var manager: AppGroupManager! + + override func setUp() { + super.setUp() + manager = AppGroupManager() + manager.clearAllData() + } + + override func tearDown() { + super.tearDown() + manager.clearAllData() + } + + func testSaveAndRetrieveLocation() { + let location = AppGroupManager.UserLocation( + latitude: 59.9139, + longitude: 10.7522, + timestamp: "2026-03-23T10:00:00Z", + isDefaultLocation: false + ) + + manager.saveLocation(location) + let retrieved = manager.getLocation() + + XCTAssertNotNil(retrieved) + XCTAssertEqual(retrieved?.latitude, 59.9139) + XCTAssertEqual(retrieved?.longitude, 10.7522) + } + + func testSaveAndRetrieveSunTimes() { + let sunTimes = AppGroupManager.SunTimes( + date: "2026-03-20", + sunrise: "2026-03-20T06:42:00", + sunset: "2026-03-20T18:15:00", + timestamp: "2026-03-23T10:00:00Z" + ) + + manager.saveSunTimes(sunTimes) + let retrieved = manager.getSunTimes() + + XCTAssertNotNil(retrieved) + XCTAssertEqual(retrieved?.date, "2026-03-20") + } + + func testClearData() { + let location = AppGroupManager.UserLocation( + latitude: 0.0, longitude: 0.0, timestamp: "2026-03-23T10:00:00Z", isDefaultLocation: true + ) + manager.saveLocation(location) + manager.clearAllData() + + XCTAssertNil(manager.getLocation()) + } +} diff --git a/Solverv/Utilities/AppGroupManager.swift b/Solverv/Utilities/AppGroupManager.swift new file mode 100644 index 0000000..95ff2de --- /dev/null +++ b/Solverv/Utilities/AppGroupManager.swift @@ -0,0 +1,67 @@ +import Foundation + +class AppGroupManager { + static let shared = AppGroupManager() + static let appGroupID = "group.com.ivarlovlie.solverv" + + private lazy var userDefaults: UserDefaults? = { + UserDefaults(suiteName: Self.appGroupID) + }() + + // MARK: - Location Storage + + struct UserLocation: Codable { + let latitude: Double + let longitude: Double + let timestamp: String // ISO 8601 + let isDefaultLocation: Bool + } + + func saveLocation(_ location: UserLocation) { + guard let ud = userDefaults else { return } + if let encoded = try? JSONEncoder().encode(location) { + ud.set(encoded, forKey: "userLocation") + } + } + + func getLocation() -> UserLocation? { + guard let ud = userDefaults, + let data = ud.data(forKey: "userLocation"), + let location = try? JSONDecoder().decode(UserLocation.self, from: data) else { + return nil + } + return location + } + + // MARK: - Sunrise/Sunset Storage + + struct SunTimes: Codable { + let date: String // ISO 8601 date only (YYYY-MM-DD) + let sunrise: String // ISO 8601 datetime + let sunset: String // ISO 8601 datetime + let timestamp: String // ISO 8601 when calculated + } + + func saveSunTimes(_ sunTimes: SunTimes) { + guard let ud = userDefaults else { return } + if let encoded = try? JSONEncoder().encode(sunTimes) { + ud.set(encoded, forKey: "sunTimes") + } + } + + func getSunTimes() -> SunTimes? { + guard let ud = userDefaults, + let data = ud.data(forKey: "sunTimes"), + let sunTimes = try? JSONDecoder().decode(SunTimes.self, from: data) else { + return nil + } + return sunTimes + } + + // MARK: - Helpers + + func clearAllData() { + userDefaults?.removeObject(forKey: "userLocation") + userDefaults?.removeObject(forKey: "sunTimes") + } +} |
