diff --git a/AutoCat.xcodeproj/project.pbxproj b/AutoCat.xcodeproj/project.pbxproj index 07107fa..4218b8e 100644 --- a/AutoCat.xcodeproj/project.pbxproj +++ b/AutoCat.xcodeproj/project.pbxproj @@ -187,7 +187,6 @@ 7AF6D2122677C12E0086EA64 /* Location.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A000AA124C2EEDE001F5B00 /* Location.swift */; }; 7AF6D2132677C15A0086EA64 /* AudioRecord.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A659B5824A2B1BA0043A0F2 /* AudioRecord.swift */; }; 7AF6D2142677C1680086EA64 /* VehicleEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AAE6AD224CDDF950023860B /* VehicleEvent.swift */; }; - 7AF6D2152677C1680086EA64 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A11474A23FF368B00B424AF /* Settings.swift */; }; 7AF6D2172677C1680086EA64 /* VehicleRegion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB562B9249C9E9B00473D53 /* VehicleRegion.swift */; }; 7AF6D2182677C1680086EA64 /* VehicleAd.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A2DE69725868AC800A113FC /* VehicleAd.swift */; }; 7AF6D2192677C1680086EA64 /* DateSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A0516192414FF0900FC55AC /* DateSection.swift */; }; @@ -292,7 +291,6 @@ 7A11474323FF06CA00B424AF /* ApiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiService.swift; sourceTree = ""; }; 7A11474623FF2AA500B424AF /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = ""; }; 7A11474823FF2B2D00B424AF /* Response.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Response.swift; sourceTree = ""; }; - 7A11474A23FF368B00B424AF /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = ""; }; 7A11474D23FFEE8800B424AF /* SVProgressHUD.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SVProgressHUD.framework; path = Carthage/Build/iOS/SVProgressHUD.framework; sourceTree = ""; }; 7A1441652C297EDE00E79018 /* NotesScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesScreen.swift; sourceTree = ""; }; 7A1441672C297EFD00E79018 /* NotesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesViewModel.swift; sourceTree = ""; }; @@ -661,7 +659,6 @@ 6841A913FABBB0AB20DEF4FC /* PagedResponse.swift */, 7A6DD90D24337930009DE740 /* PlateNumber.swift */, 7A11474823FF2B2D00B424AF /* Response.swift */, - 7A11474A23FF368B00B424AF /* Settings.swift */, 7A11474623FF2AA500B424AF /* User.swift */, 7AB562B9249C9E9B00473D53 /* VehicleRegion.swift */, ); @@ -1502,7 +1499,6 @@ 7A60D2512C5A9E4200D13F7B /* GeocoderProtocol.swift in Sources */, 7A64A21C2C19E87B00284124 /* OsagoDto.swift in Sources */, 7AF6D21D2677C1680086EA64 /* Osago.swift in Sources */, - 7AF6D2152677C1680086EA64 /* Settings.swift in Sources */, 7A1CF81629A42117007962DA /* Realm.swift in Sources */, 7A64A2142C19E3B700284124 /* VehicleEngineDto.swift in Sources */, 7A761C052677F1BC0005F28F /* CocoaError.swift in Sources */, diff --git a/AutoCat.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/AutoCat.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 8f2148b..81045db 100644 --- a/AutoCat.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/AutoCat.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -42,8 +42,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/realm/realm-core.git", "state" : { - "revision" : "e474a8d2270a8b12ac63ac9504e4757e39814b99", - "version" : "14.13.0" + "revision" : "85eeca41654cc9070ad81a21a4b1d153ad467c33", + "version" : "14.13.1" } }, { @@ -51,8 +51,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/realm/realm-swift.git", "state" : { - "revision" : "863498d37a9f0e72caa65963da9641d8cdfc8228", - "version" : "10.54.0" + "revision" : "5553cfd1c789efdb3d6daf7f0cc0733cfe601846", + "version" : "10.54.1" } }, { diff --git a/AutoCat.xcodeproj/xcuserdata/selim.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/AutoCat.xcodeproj/xcuserdata/selim.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 1e00cef..a0b0c58 100644 --- a/AutoCat.xcodeproj/xcuserdata/selim.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/AutoCat.xcodeproj/xcuserdata/selim.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -49,5 +49,21 @@ landmarkType = "0"> + + + + diff --git a/AutoCat/AppDelegate.swift b/AutoCat/AppDelegate.swift index 95502f4..c2dba56 100644 --- a/AutoCat/AppDelegate.swift +++ b/AutoCat/AppDelegate.swift @@ -72,25 +72,26 @@ class AppDelegate: UIResponder, UIApplicationDelegate { HUD.dimsBackground = true HUD.allowsInteraction = false - Task { - try! await registerServices() - } + registerServices() //Logging.URLRequests = { _ in false }; return true } - func registerServices() async throws { + func registerServices() { let container = ServiceContainer.shared container.register(SettingsServiceProtocol.self, instance: SettingsService(defaults: .standard)) - container.register(StorageServiceProtocol.self, instance: try await StorageService()) container.register(ApiServiceProtocol.self, instance: ApiService()) container.register(GeocoderProtocol.self, instance: CLGeocoder()) container.register(SwiftLocationProtocol.self, instance: Location()) container.register(LocationServiceProtocol.self, instance: LocationService()) + + Task { + container.register(StorageServiceProtocol.self, instance: try await StorageService()) + } } // MARK: UISceneSession Lifecycle diff --git a/AutoCat/Base.lproj/Main.storyboard b/AutoCat/Base.lproj/Main.storyboard index 8936fbd..e829875 100644 --- a/AutoCat/Base.lproj/Main.storyboard +++ b/AutoCat/Base.lproj/Main.storyboard @@ -1,5 +1,5 @@ - + @@ -21,17 +21,17 @@ - + - + - + - + - + @@ -790,22 +790,22 @@ - + - + - + - + - + diff --git a/AutoCat/Cells/EventCell.swift b/AutoCat/Cells/EventCell.swift index db221fb..9c19e8f 100644 --- a/AutoCat/Cells/EventCell.swift +++ b/AutoCat/Cells/EventCell.swift @@ -6,6 +6,8 @@ class EventCell: UITableViewCell { @IBOutlet weak var date: UILabel! @IBOutlet weak var userImageView: UIImageView! + @Service var settingsService: SettingsServiceProtocol + let dateFormatter = DateFormatter() override func awakeFromNib() { @@ -26,7 +28,7 @@ class EventCell: UITableViewCell { self.date.text = self.dateFormatter.string(from: date) if let addedBy = event.addedBy { - let isMe = addedBy == Settings.shared.user.email + let isMe = addedBy == settingsService.user.email userImageView.image = UIImage(systemName: isMe ? "person.fill" : "person") userImageView.tintColor = isMe ? self.tintColor : .secondaryLabel userImageView.isHidden = false diff --git a/AutoCat/Controllers/AuthController.swift b/AutoCat/Controllers/AuthController.swift index 314532c..2498704 100644 --- a/AutoCat/Controllers/AuthController.swift +++ b/AutoCat/Controllers/AuthController.swift @@ -10,6 +10,8 @@ class AuthController: UIViewController { @IBOutlet weak var password: UITextField! @IBOutlet weak var login: UIButton! @IBOutlet weak var signup: UIButton! + + @Service var settingsService: SettingsServiceProtocol override func viewDidLoad() { super.viewDidLoad() @@ -23,8 +25,8 @@ class AuthController: UIViewController { // authValid.bind(to: self.login.rx.isEnabled).disposed(by: self.bag) // authValid.bind(to: self.signup.rx.isEnabled).disposed(by: self.bag) - if Settings.shared.user.email.count > 0 { - self.username.text = Settings.shared.user.email + if settingsService.user.email.count > 0 { + self.username.text = settingsService.user.email } } @@ -64,13 +66,13 @@ class AuthController: UIViewController { HUD.hide() - if user.email != Settings.shared.user.email { + if user.email != settingsService.user.email { try? realm.write { realm.deleteAll() } } - Settings.shared.user = user + settingsService.user = user let storyboard = UIStoryboard(name: "Main", bundle: nil) self.view.window?.rootViewController = storyboard.instantiateViewController(identifier: "MainSplitController") } diff --git a/AutoCat/Controllers/Location/EventsController.swift b/AutoCat/Controllers/Location/EventsController.swift index 3c360d0..6f976f3 100644 --- a/AutoCat/Controllers/Location/EventsController.swift +++ b/AutoCat/Controllers/Location/EventsController.swift @@ -46,6 +46,8 @@ class EventsController: UIViewController, UITableViewDataSource, UITableViewDele @IBOutlet weak var map: MKMapView! @IBOutlet weak var tableView: UITableView! + @Service var settingsService: SettingsServiceProtocol + var modeButton: UIBarButtonItem! var addButton: UIBarButtonItem! var pasteButton: UIBarButtonItem! @@ -257,10 +259,9 @@ class EventsController: UIViewController, UITableViewDataSource, UITableViewDele func editEvent(event: VehicleEventDto) { if let navigationController { - let coordinator = LocationEditCoordinator(navController: navigationController, - event: event) + let coordinator = LocationEditCoordinator(navController: navigationController) Task { - if let event = try await coordinator.start() { + if let event = await coordinator.start(event: event) { do { HUD.show(.progress) let vehicle = try await ApiService.shared.edit(event: event) @@ -328,7 +329,8 @@ class EventsController: UIViewController, UITableViewDataSource, UITableViewDele let coordinator = LocationEditCoordinator(navController: navigationController) Task { - if let event = try await coordinator.start() { + let newEvent = VehicleEventDto(lat: 0, lon: 0, addedBy: settingsService.user.email) + if let event = await coordinator.start(event: newEvent) { do { HUD.show(.progress) let vehicle = try await ApiService.shared.add(event: event, to: vehicle.getNumber()) diff --git a/AutoCat/Controllers/RecordsController.swift b/AutoCat/Controllers/RecordsController.swift index ee2660d..d8e495d 100644 --- a/AutoCat/Controllers/RecordsController.swift +++ b/AutoCat/Controllers/RecordsController.swift @@ -12,6 +12,8 @@ class RecordsController: UIViewController, UITableViewDelegate { @IBOutlet weak var tableView: UITableView! + @Service var settingsService: SettingsServiceProtocol + var recorder: Recorder? var addButton: UIBarButtonItem! var audioSessionObserver: NSObjectProtocol? @@ -173,14 +175,14 @@ class RecordsController: UIViewController, UITableViewDelegate { var result = "" if let range = trimmed.range(of: #"\S\d\d\d\S\S\d\d\d?"#, options: .regularExpression) { result = String(trimmed[range]) - } else if let range = trimmed.range(of: #"\S\S\S\d\d\d\d\d\d?"#, options: .regularExpression), Settings.shared.recognizeAlternativeOrder { + } else if let range = trimmed.range(of: #"\S\S\S\d\d\d\d\d\d?"#, options: .regularExpression), settingsService.recognizeAlternativeOrder { let n = String(trimmed[range]) result = String(n.prefix(1)) + n.substring(with: 3..<6) + n.substring(with: 1..<3) + n.substring(from: 6) - } else if let range = trimmed.range(of: #"\S\d\d\d\S\S"#, options: .regularExpression), Settings.shared.recognizeShortenedNumbers { - result = String(trimmed[range]) + Settings.shared.defaultRegion - } else if let range = trimmed.range(of: #"\S\S\S\d\d\d"#, options: .regularExpression), Settings.shared.recognizeAlternativeOrder && Settings.shared.recognizeShortenedNumbers { + } else if let range = trimmed.range(of: #"\S\d\d\d\S\S"#, options: .regularExpression), settingsService.recognizeShortenedNumbers { + result = String(trimmed[range]) + settingsService.defaultRegion + } else if let range = trimmed.range(of: #"\S\S\S\d\d\d"#, options: .regularExpression), settingsService.recognizeAlternativeOrder && settingsService.recognizeShortenedNumbers { let n = String(trimmed[range]) - result = String(n.prefix(1)) + n.substring(with: 3..<6) + n.substring(with: 1..<3) + Settings.shared.defaultRegion + result = String(n.prefix(1)) + n.substring(with: 3..<6) + n.substring(with: 1..<3) + settingsService.defaultRegion } if !result.isEmpty && valid(number: result) { @@ -208,7 +210,7 @@ class RecordsController: UIViewController, UITableViewDelegate { } func makeStartSoundIfNeeded() async { - guard Settings.shared.recordBeep else { + guard settingsService.recordBeep else { return } diff --git a/AutoCat/SceneDelegate.swift b/AutoCat/SceneDelegate.swift index 022456a..2ddf75a 100644 --- a/AutoCat/SceneDelegate.swift +++ b/AutoCat/SceneDelegate.swift @@ -5,6 +5,8 @@ import PKHUD import AutoCatCore class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + @Service var settingsService: SettingsServiceProtocol var window: UIWindow? @@ -32,7 +34,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { self.window = UIWindow(windowScene: windowScene) let storyboard = UIStoryboard(name: "Main", bundle: nil) - if Settings.shared.user.token.isEmpty { + if settingsService.user.token.isEmpty { self.window?.rootViewController = storyboard.instantiateViewController(identifier: "AuthController") } else { self.window?.rootViewController = storyboard.instantiateViewController(identifier: "MainSplitController") diff --git a/AutoCat/Screens/EventsScreen/EventsCoordinator.swift b/AutoCat/Screens/EventsScreen/EventsCoordinator.swift index 65c6b37..b8eb12e 100644 --- a/AutoCat/Screens/EventsScreen/EventsCoordinator.swift +++ b/AutoCat/Screens/EventsScreen/EventsCoordinator.swift @@ -29,15 +29,9 @@ class EventsCoordinator { return viewModel.vehicle } - func addNewEvent() async -> VehicleEventDto? { - - let coordinator = LocationEditCoordinator(navController: navController) - return await coordinator.start() - } - func editEvent(event: VehicleEventDto) async -> VehicleEventDto? { - let coordinator = LocationEditCoordinator(navController: navController, event: event) - return await coordinator.start() + let coordinator = LocationEditCoordinator(navController: navController) + return await coordinator.start(event: event) } } diff --git a/AutoCat/Screens/EventsScreen/EventsViewModel.swift b/AutoCat/Screens/EventsScreen/EventsViewModel.swift index cf5300c..d329274 100644 --- a/AutoCat/Screens/EventsScreen/EventsViewModel.swift +++ b/AutoCat/Screens/EventsScreen/EventsViewModel.swift @@ -53,7 +53,10 @@ class EventsViewModel: ACHudContainer { } func addNewEvent() async { - if let event = await coordinator?.addNewEvent() { + + let newEvent = VehicleEventDto(lat: 0, lon: 0, addedBy: settingsService.user.email) + + if let event = await coordinator?.editEvent(event: newEvent) { await eventOperation { try await self.storageService.add(event: event, to: self.vehicle.getNumber()) } apiOperation: { diff --git a/AutoCat/Screens/LocationEditScreen/LocationEditCoordinator.swift b/AutoCat/Screens/LocationEditScreen/LocationEditCoordinator.swift index 9966069..ee122d4 100644 --- a/AutoCat/Screens/LocationEditScreen/LocationEditCoordinator.swift +++ b/AutoCat/Screens/LocationEditScreen/LocationEditCoordinator.swift @@ -13,22 +13,20 @@ import AutoCatCore @MainActor final class LocationEditCoordinator { - let viewController: UINavigationController? - let event: VehicleEventDto + let viewController: UINavigationController - init(navController: UINavigationController?, event: VehicleEventDto? = nil) { + init(navController: UINavigationController) { self.viewController = navController - self.event = event ?? VehicleEventDto(lat: 0, lon: 0) } - func start() async -> VehicleEventDto? { + func start(event: VehicleEventDto) async -> VehicleEventDto? { let viewModel = LocationEditViewModel(event: event) viewModel.coordinator = self let screen = LocationEditScreen(viewModel: viewModel) let controller = CustomHostingController(rootView: screen) - viewController?.pushViewController(controller, animated: true) + viewController.pushViewController(controller, animated: true) await controller.waitForDisappear() return viewModel.result } diff --git a/AutoCat/Screens/LocationEditScreen/LocationEditScreen.swift b/AutoCat/Screens/LocationEditScreen/LocationEditScreen.swift index 0db8607..e30d0e2 100644 --- a/AutoCat/Screens/LocationEditScreen/LocationEditScreen.swift +++ b/AutoCat/Screens/LocationEditScreen/LocationEditScreen.swift @@ -38,7 +38,7 @@ struct LocationEditScreen: View { #Preview { - var event = VehicleEventDto(lat: 25.54984, lon: 36.34857) + var event = VehicleEventDto(lat: 25.54984, lon: 36.34857, addedBy: "") event.address = "Ул. Ленина, 123" return LocationEditScreen(viewModel: .init(event: event)) diff --git a/AutoCat/Screens/LocationPickerScreen/LocationPickerScreen.swift b/AutoCat/Screens/LocationPickerScreen/LocationPickerScreen.swift index 8865a70..da27f5c 100644 --- a/AutoCat/Screens/LocationPickerScreen/LocationPickerScreen.swift +++ b/AutoCat/Screens/LocationPickerScreen/LocationPickerScreen.swift @@ -48,7 +48,7 @@ struct LocationPickerScreen: View { #Preview { - var event = VehicleEventDto(lat: 47.250049, lon: 39.711821) + var event = VehicleEventDto(lat: 47.250049, lon: 39.711821, addedBy: nil) event.address = "Ул. Ленина, 123" let viewModel = LocationPickerViewModel(event: event) diff --git a/AutoCat/Screens/NotesScreen/NotesScreen.swift b/AutoCat/Screens/NotesScreen/NotesScreen.swift index 0726b32..9dd270c 100644 --- a/AutoCat/Screens/NotesScreen/NotesScreen.swift +++ b/AutoCat/Screens/NotesScreen/NotesScreen.swift @@ -90,9 +90,9 @@ struct NotesScreen: View { var vehicle = VehicleDto() vehicle.notes = [ - .init(text: "qwe"), - .init(text: "asdf"), - .init(text: "zxcv") + .init(text: "qwe", user: ""), + .init(text: "asdf", user: ""), + .init(text: "zxcv", user: "") ] let vm = NotesViewModel(vehicle: vehicle) diff --git a/AutoCat/Screens/NotesScreen/NotesViewModel.swift b/AutoCat/Screens/NotesScreen/NotesViewModel.swift index 5a28f21..d308c24 100644 --- a/AutoCat/Screens/NotesScreen/NotesViewModel.swift +++ b/AutoCat/Screens/NotesScreen/NotesViewModel.swift @@ -31,7 +31,7 @@ class NotesViewModel: ACHudContainer { await noteOperation { try await self.storageService.addNote(text: text, to: self.vehicle.getNumber()) } apiOp: { - let note = VehicleNoteDto(text: text) + let note = VehicleNoteDto(text: text, user: "") return try await self.apiService.add(notes: [note], to: self.vehicle.getNumber()) } } @@ -50,7 +50,7 @@ class NotesViewModel: ACHudContainer { await noteOperation { try await self.storageService.editNote(id: id, text: text, for: self.vehicle.getNumber()) } apiOp: { - var note = VehicleNoteDto(text: text) + var note = VehicleNoteDto(text: text, user: "") note.id = id return try await self.apiService.edit(note: note) } diff --git a/AutoCatCore/Models/DTO/VehicleEventDto.swift b/AutoCatCore/Models/DTO/VehicleEventDto.swift index b7467b8..fe924e7 100644 --- a/AutoCatCore/Models/DTO/VehicleEventDto.swift +++ b/AutoCatCore/Models/DTO/VehicleEventDto.swift @@ -18,10 +18,10 @@ public struct VehicleEventDto: Codable, Sendable, Equatable { public var addedBy: String? = nil public var number: String? - public init(lat: Double, lon: Double) { + public init(lat: Double, lon: Double, addedBy: String?) { self.latitude = lat self.longitude = lon - self.addedBy = Settings.shared.user.email + self.addedBy = addedBy } public func getMapLink() -> URL? { diff --git a/AutoCatCore/Models/DTO/VehicleNoteDto.swift b/AutoCatCore/Models/DTO/VehicleNoteDto.swift index ca8619a..c3e5ac6 100644 --- a/AutoCatCore/Models/DTO/VehicleNoteDto.swift +++ b/AutoCatCore/Models/DTO/VehicleNoteDto.swift @@ -15,8 +15,8 @@ public struct VehicleNoteDto: Codable, Sendable, Identifiable, Equatable { public var date: TimeInterval = Date().timeIntervalSince1970 public var text: String = "" - public init(text: String) { + public init(text: String, user: String) { self.text = text - self.user = Settings.shared.user.email + self.user = user } } diff --git a/AutoCatCore/Models/Realm/VehicleEvent.swift b/AutoCatCore/Models/Realm/VehicleEvent.swift index 7a7c371..d320e01 100644 --- a/AutoCatCore/Models/Realm/VehicleEvent.swift +++ b/AutoCatCore/Models/Realm/VehicleEvent.swift @@ -29,11 +29,10 @@ extension VehicleEvent: DtoConvertible { public var dto: VehicleEventDto { - var dto = VehicleEventDto(lat: latitude, lon: longitude) + var dto = VehicleEventDto(lat: latitude, lon: longitude, addedBy: addedBy) dto.id = id dto.date = date dto.address = address - dto.addedBy = addedBy return dto } diff --git a/AutoCatCore/Models/Realm/VehicleNote.swift b/AutoCatCore/Models/Realm/VehicleNote.swift index e9e5655..b694c26 100644 --- a/AutoCatCore/Models/Realm/VehicleNote.swift +++ b/AutoCatCore/Models/Realm/VehicleNote.swift @@ -8,10 +8,10 @@ public final class VehicleNote: Object { @Persisted public var date: TimeInterval = Date().timeIntervalSince1970 @Persisted public var text: String = "" - public convenience init(text: String) { + public convenience init(text: String, user: String) { self.init() self.text = text - self.user = Settings.shared.user.email + self.user = user } public override static func primaryKey() -> String? { @@ -22,16 +22,15 @@ public final class VehicleNote: Object { extension VehicleNote: DtoConvertible { public var dto: VehicleNoteDto { - var dto = VehicleNoteDto(text: text) + var dto = VehicleNoteDto(text: text, user: user) dto.id = id - dto.user = user dto.date = date return dto } public convenience init(dto: VehicleNoteDto) { - self.init(text: dto.text) + self.init(text: dto.text, user: dto.user) self.id = dto.id self.user = dto.user diff --git a/AutoCatCore/Models/Settings.swift b/AutoCatCore/Models/Settings.swift deleted file mode 100644 index 23f8b07..0000000 --- a/AutoCatCore/Models/Settings.swift +++ /dev/null @@ -1,72 +0,0 @@ -import Foundation - -final public class Settings: Sendable { - private static let defaults = UserDefaults.standard - public static let shared = Settings() - - public var user: User { - didSet { - if let json = try? JSONEncoder().encode(self.user) { - Settings.defaults.set(json, forKey: "user") - Settings.defaults.synchronize() - } - } - } - - public var recognizeAlternativeOrder: Bool = false { - didSet { - Settings.defaults.set(self.recognizeAlternativeOrder, forKey: "recognizeAlternativeOrder") - Settings.defaults.synchronize() - } - } - - public var recognizeShortenedNumbers: Bool = false { - didSet { - Settings.defaults.set(self.recognizeShortenedNumbers, forKey: "recognizeShortenedNumbers") - Settings.defaults.synchronize() - } - } - - public var defaultRegion: String = "" { - didSet { - Settings.defaults.set(self.defaultRegion, forKey: "defaultRegion") - Settings.defaults.synchronize() - } - } - - public var recordBeep: Bool = false { - didSet { - Settings.defaults.set(self.recordBeep, forKey: "recordBeep") - Settings.defaults.synchronize() - } - } - - public var showDebugInfo: Bool = false { - didSet { - Settings.defaults.set(self.showDebugInfo, forKey: "showDebugInfo") - Settings.defaults.synchronize() - } - } - - init() { - UserDefaults.standard.register(defaults: [ - "recognizeAlternativeOrder": false, - "recognizeShortenedNumbers": false, - "defaultRegion": "161", - "recordBeep": false, - "showDebugInfo": false - ]) - - self.user = Settings.getUser() - self.recognizeAlternativeOrder = Settings.defaults.bool(forKey: "recognizeAlternativeOrder") - self.recognizeShortenedNumbers = Settings.defaults.bool(forKey: "recognizeShortenedNumbers") - self.defaultRegion = Settings.defaults.string(forKey: "defaultRegion") ?? "161" - self.recordBeep = Settings.defaults.bool(forKey: "recordBeep") - self.showDebugInfo = Settings.defaults.bool(forKey: "showDebugInfo") - } - - private static func getUser() -> User { - guard let data = Settings.defaults.data(forKey: "user") else { return User() } - return (try? JSONDecoder().decode(User.self, from: data)) ?? User() - } -} diff --git a/AutoCatCore/Services/ApiService/ApiService.swift b/AutoCatCore/Services/ApiService/ApiService.swift index 75de870..144c8b7 100644 --- a/AutoCatCore/Services/ApiService/ApiService.swift +++ b/AutoCatCore/Services/ApiService/ApiService.swift @@ -32,7 +32,7 @@ public actor ApiService: ApiServiceProtocol { request.httpMethod = method request.addValue("application/json", forHTTPHeaderField: "Content-Type") request.addValue("application/json", forHTTPHeaderField: "Accept") - request.addValue("Bearer " + Settings.shared.user.token, forHTTPHeaderField: "Authorization") + await request.addValue("Bearer " + settingsService.user.token, forHTTPHeaderField: "Authorization") if let body = body, method.uppercased() != "GET" { let encoder = JSONEncoder() @@ -109,8 +109,8 @@ public actor ApiService: ApiServiceProtocol { // MARK: - Firebase API public func refreshFbToken() async throws { - guard let token = Settings.shared.user.firebaseIdToken, - let refreshToken = Settings.shared.user.firebaseRefreshToken, + guard let token = await settingsService.user.firebaseIdToken, + let refreshToken = await settingsService.user.firebaseRefreshToken, let jwt = JWT(string: token), jwt.expired else { return } @@ -138,11 +138,11 @@ public actor ApiService: ApiServiceProtocol { let model = try JSONDecoder().decode(FbRefreshTokenModel.self, from: data) if let idToken = model.id_token { - Settings.shared.user.firebaseIdToken = idToken + await settingsService.user.firebaseIdToken = idToken } if let refreshToken = model.refresh_token { - Settings.shared.user.firebaseRefreshToken = refreshToken + await settingsService.user.firebaseRefreshToken = refreshToken } } @@ -181,11 +181,11 @@ public actor ApiService: ApiServiceProtocol { let model = try JSONDecoder().decode(FbVerifyTokenModel.self, from: data) if let idToken = model.idToken { - Settings.shared.user.firebaseIdToken = idToken + await settingsService.user.firebaseIdToken = idToken } if let refreshToken = model.refreshToken { - Settings.shared.user.firebaseRefreshToken = refreshToken + await settingsService.user.firebaseRefreshToken = refreshToken } } catch { @@ -237,7 +237,7 @@ public actor ApiService: ApiServiceProtocol { "forceUpdate": AnyEncodable(force) ] - if let token = Settings.shared.user.firebaseIdToken { + if let token = await settingsService.user.firebaseIdToken { body["googleIdToken"] = AnyEncodable(token) } @@ -324,7 +324,7 @@ public actor ApiService: ApiServiceProtocol { var body = ["number": number] - if let token = Settings.shared.user.firebaseIdToken { + if let token = await settingsService.user.firebaseIdToken { body["token"] = token } diff --git a/AutoCatCore/Services/LocationService/LocationService.swift b/AutoCatCore/Services/LocationService/LocationService.swift index 5f9cc45..dade295 100644 --- a/AutoCatCore/Services/LocationService/LocationService.swift +++ b/AutoCatCore/Services/LocationService/LocationService.swift @@ -14,6 +14,7 @@ public final class LocationService { @Service var geocoder: GeocoderProtocol @Service var locationManager: SwiftLocationProtocol + @Service var settingsService: SettingsServiceProtocol private var eventTask: Task? @@ -44,7 +45,7 @@ public final class LocationService { throw LocationError.generic } - return VehicleEventDto(lat: coordinate.latitude, lon: coordinate.longitude) + return VehicleEventDto(lat: coordinate.latitude, lon: coordinate.longitude, addedBy: settingsService.user.email) } } diff --git a/AutoCatCore/Services/SettingsService/SettingsServiceProtocol.swift b/AutoCatCore/Services/SettingsService/SettingsServiceProtocol.swift index 84933cc..af2d3de 100644 --- a/AutoCatCore/Services/SettingsService/SettingsServiceProtocol.swift +++ b/AutoCatCore/Services/SettingsService/SettingsServiceProtocol.swift @@ -9,7 +9,7 @@ import Mockable @Mockable -public protocol SettingsServiceProtocol { +public protocol SettingsServiceProtocol: Sendable { var user: User { get set } diff --git a/AutoCatCore/Services/StorageService/StorageService+Notes.swift b/AutoCatCore/Services/StorageService/StorageService+Notes.swift index 8f8bdbc..f956be1 100644 --- a/AutoCatCore/Services/StorageService/StorageService+Notes.swift +++ b/AutoCatCore/Services/StorageService/StorageService+Notes.swift @@ -16,7 +16,7 @@ extension StorageService { throw StorageError.vehicleNotFound } - let note = VehicleNote(text: text) + let note = VehicleNote(text: text, user: await settingsService.user.email) try await realm.asyncWrite { vehicle.notes.append(note) diff --git a/AutoCatCore/Services/StorageService/StorageService.swift b/AutoCatCore/Services/StorageService/StorageService.swift index 7d0d508..e05f454 100644 --- a/AutoCatCore/Services/StorageService/StorageService.swift +++ b/AutoCatCore/Services/StorageService/StorageService.swift @@ -26,6 +26,8 @@ public enum StorageError: LocalizedError { public actor StorageService: StorageServiceProtocol { + @Service var settingsService: SettingsServiceProtocol + var realm: Realm! public init(config: Realm.Configuration = .defaultConfiguration) async throws { diff --git a/AutoCatCore/Utils/Location.swift b/AutoCatCore/Utils/Location.swift index 28fc5cf..1b73b20 100644 --- a/AutoCatCore/Utils/Location.swift +++ b/AutoCatCore/Utils/Location.swift @@ -58,7 +58,9 @@ public class RxLocationManager { throw LocationError.generic } - let event = VehicleEventDto(lat: coordinate.latitude, lon: coordinate.longitude) + let settingsService = try ServiceContainer.shared.resolve(SettingsServiceProtocol.self) + + let event = VehicleEventDto(lat: coordinate.latitude, lon: coordinate.longitude, addedBy: settingsService.user.email) self.lastEvent = event return event }