Some steps towards Swift 6 in AutoCatCore framework
This commit is contained in:
parent
2dae05fa97
commit
cb02fe6746
@ -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 = "<group>"; };
|
||||
7A11474623FF2AA500B424AF /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = "<group>"; };
|
||||
7A11474823FF2B2D00B424AF /* Response.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Response.swift; sourceTree = "<group>"; };
|
||||
7A11474A23FF368B00B424AF /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = "<group>"; };
|
||||
7A11474D23FFEE8800B424AF /* SVProgressHUD.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SVProgressHUD.framework; path = Carthage/Build/iOS/SVProgressHUD.framework; sourceTree = "<group>"; };
|
||||
7A1441652C297EDE00E79018 /* NotesScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesScreen.swift; sourceTree = "<group>"; };
|
||||
7A1441672C297EFD00E79018 /* NotesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotesViewModel.swift; sourceTree = "<group>"; };
|
||||
@ -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 */,
|
||||
|
||||
@ -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"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@ -49,5 +49,21 @@
|
||||
landmarkType = "0">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "88924AF0-7C20-4DBB-A9C1-7F575E0CE5C2"
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "AutoCat/AppDelegate.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "115"
|
||||
endingLineNumber = "115"
|
||||
landmarkName = "application(_:configurationForConnecting:options:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
</Breakpoints>
|
||||
</Bucket>
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="pme-aR-UNJ">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait" appearance="dark"/>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
|
||||
@ -21,17 +21,17 @@
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="EventCell" id="QIb-Hv-tvk" customClass="EventCell" customModule="AutoCat" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="50" width="375" height="437"/>
|
||||
<rect key="frame" x="0.0" y="50" width="375" height="437.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="QIb-Hv-tvk" id="Ypt-ch-fGT">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="437"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="437.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="HP8-oO-yhP">
|
||||
<rect key="frame" x="16" y="8" width="343" height="421"/>
|
||||
<rect key="frame" x="16" y="8" width="343" height="421.5"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="k4Z-KM-byE">
|
||||
<rect key="frame" x="0.0" y="0.0" width="335" height="421"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="335" height="421.5"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xcQ-Wz-gJ0">
|
||||
<rect key="frame" x="0.0" y="0.0" width="335" height="201"/>
|
||||
@ -40,7 +40,7 @@
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1tQ-zM-6T9">
|
||||
<rect key="frame" x="0.0" y="209" width="335" height="212"/>
|
||||
<rect key="frame" x="0.0" y="209" width="335" height="212.5"/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@ -48,7 +48,7 @@
|
||||
</subviews>
|
||||
</stackView>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="750" verticalHuggingPriority="251" image="person" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="CFI-xa-eLs">
|
||||
<rect key="frame" x="343" y="1" width="0.0" height="418.5"/>
|
||||
<rect key="frame" x="343" y="1" width="0.0" height="419"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
</stackView>
|
||||
@ -790,22 +790,22 @@
|
||||
<image name="square.and.arrow.up" catalog="system" width="110" height="128"/>
|
||||
<image name="text.bubble" catalog="system" width="128" height="110"/>
|
||||
<systemColor name="secondaryLabelColor">
|
||||
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemBackgroundColor">
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemBlueColor">
|
||||
<color red="0.0" green="0.47843137254901963" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemOrangeColor">
|
||||
<color red="1" green="0.58431372549019611" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="1" green="0.58431372550000005" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemTealColor">
|
||||
<color red="0.18823529411764706" green="0.69019607843137254" blue="0.7803921568627451" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.18823529410000001" green="0.69019607839999997" blue="0.78039215689999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
<systemColor name="tertiaryLabelColor">
|
||||
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.29803921568627451" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.29803921570000003" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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")
|
||||
}
|
||||
|
||||
@ -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())
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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? {
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
@ -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<FirebasePayload>(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
|
||||
}
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@ public final class LocationService {
|
||||
|
||||
@Service var geocoder: GeocoderProtocol
|
||||
@Service var locationManager: SwiftLocationProtocol
|
||||
@Service var settingsService: SettingsServiceProtocol
|
||||
|
||||
private var eventTask: Task<VehicleEventDto,Error>?
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
import Mockable
|
||||
|
||||
@Mockable
|
||||
public protocol SettingsServiceProtocol {
|
||||
public protocol SettingsServiceProtocol: Sendable {
|
||||
|
||||
var user: User { get set }
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user