Revorking number checking code

This commit is contained in:
Selim Mustafaev 2021-04-11 13:40:31 +03:00
parent 0a1f9d4363
commit ed0e2a444b
6 changed files with 122 additions and 94 deletions

View File

@ -327,20 +327,20 @@
7A11471423FDEAF800B424AF /* Controllers */ = {
isa = PBXGroup;
children = (
7A0420AF2561A0C100034941 /* Osago */,
7A813DC7250B5C6E00CC93B9 /* Location */,
7A11471523FDEB2A00B424AF /* MainSplitController.swift */,
7A11471723FDEBFA00B424AF /* ReportController.swift */,
7A0420AF2561A0C100034941 /* Osago */,
7A2DE69A25869ABD00A113FC /* AdsController.swift */,
7A11471923FE839000B424AF /* AuthController.swift */,
7A530B7924001D3300CBFE6E /* CheckController.swift */,
7AEFE727240455E200910EB7 /* SettingsController.swift */,
7A3F07AC2436350B00E59687 /* SearchController.swift */,
7A96AE2C246B2B7400297C33 /* GoogleSignInController.swift */,
7A6E03272485951700DB22ED /* OwnersController.swift */,
7A33381024990DAE00D878F1 /* FiltersController.swift */,
7A27ADC6249D43210035F39E /* RegionsController.swift */,
7A96AE2C246B2B7400297C33 /* GoogleSignInController.swift */,
7A11471523FDEB2A00B424AF /* MainSplitController.swift */,
7A6E03272485951700DB22ED /* OwnersController.swift */,
7A27ADF2249F8B650035F39E /* RecordsController.swift */,
7A2DE69A25869ABD00A113FC /* AdsController.swift */,
7A27ADC6249D43210035F39E /* RegionsController.swift */,
7A11471723FDEBFA00B424AF /* ReportController.swift */,
7A3F07AC2436350B00E59687 /* SearchController.swift */,
7AEFE727240455E200910EB7 /* SettingsController.swift */,
);
path = Controllers;
sourceTree = "<group>";

View File

@ -63,5 +63,21 @@
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "A2917113-DA52-4374-ADE1-6BB476EC9BD9"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "AutoCat/Controllers/CheckController.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "401"
endingLineNumber = "401"
landmarkName = "check(number:action:force:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>

View File

@ -855,7 +855,6 @@
<tabBarItem key="tabBarItem" title="Check" image="check" landscapeImage="check-compact" id="QJd-35-4OB"/>
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="AAc-4d-GNh">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
@ -874,7 +873,6 @@
<tabBarItem key="tabBarItem" title="Search" image="search" landscapeImage="search-compact" id="gDG-z8-R0t"/>
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="vdY-9n-hjX">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
@ -892,7 +890,6 @@
<navigationController storyboardIdentifier="ReportNavController" automaticallyAdjustsScrollViewInsets="NO" id="Km4-b6-SGW" sceneMemberID="viewController">
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="JaO-tp-k6N">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
@ -911,7 +908,6 @@
<tabBarItem key="tabBarItem" title="Records" image="record" landscapeImage="record-compact" id="lxF-EY-z8V"/>
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="8YG-pw-LE7">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
@ -929,7 +925,6 @@
<navigationController storyboardIdentifier="GlobalEventsNavigation" automaticallyAdjustsScrollViewInsets="NO" id="HWa-Ea-ZKD" sceneMemberID="viewController">
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="REm-5j-xeL">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>

View File

@ -6,7 +6,7 @@ import RxRealm
import PKHUD
import CoreLocation
enum EventAction {
enum EventAction: Equatable {
case doNotSend
case receiveAndSend
case sendSpecific(VehicleEvent)
@ -94,9 +94,12 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat
action = .sendSpecific(event)
}
HUD.show(.progress)
self.check(number: number, action: action).subscribe { vehicle in
self.check(number: number, action: action).subscribe { (vehicle, errors) in
if !vehicle.unrecognized {
self.updateDetailController(with: vehicle)
}
HUD.hide()
self.showErrors(errors)
} onError: { error in
HUD.hide()
self.show(error: error)
@ -210,19 +213,16 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat
self.check.isEnabled = false
HUD.show(.progress)
self.check(number: numberNormalized, action: .receiveAndSend).subscribe { vehicle in
self.check(number: numberNormalized, action: .receiveAndSend).subscribe { (vehicle, errors) in
if !vehicle.unrecognized {
self.updateDetailController(with: vehicle)
}
HUD.hide()
self.showErrors(errors)
} onError: { error in
HUD.hide()
if let clerror = error as? CLError {
if clerror.code != .denied {
self.showAlert(title: NSLocalizedString("Location error", comment: ""), message: clerror.code.description)
}
} else {
self.show(error: error)
}
}
.disposed(by: self.bag)
}
@ -251,7 +251,6 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat
// MARK: - UITextFieldDelegate
@IBAction func textFieldDidBeginEditing(_ textField: UITextField) {
print("+++ textFieldDidBeginEditing, requesting new location")
LocationManager.requestCurrentLocation().subscribe().disposed(by: self.bag)
}
@ -323,13 +322,15 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat
eventAction = .sendSpecific(savedEvent)
}
self.check(number: vehicle.getNumber(), action: eventAction, force: true).subscribe { vehicle in
self.check(number: vehicle.getNumber(), action: eventAction, force: true).subscribe { (vehicle, errors) in
if !vehicle.unrecognized {
self.updateDetailController(with: vehicle)
}
HUD.hide()
self.showErrors(errors)
} onError: { error in
HUD.hide()
self.show(error: error)
//HUD.show(error: error)
}
.disposed(by: self.bag)
}
@ -362,77 +363,88 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat
}
if let event = LocationManager.lastEvent, (Date().timeIntervalSince1970 - event.date) < 100 {
print("+++ getEvent, using last event")
return Single<VehicleEvent>.just(event)
} else {
print("+++ getEvent, requesting new location")
return LocationManager.requestCurrentLocation()
}
}
func check(number: String, action: EventAction, force: Bool = false) -> Single<Vehicle> {
print("+++ Checking numnber, event: \(action)")
func check(number: String, action: EventAction, force: Bool = false) -> Single<(vehicle: Vehicle, errors: [Error])> {
var eventSingle: Single<(event: VehicleEvent?, error: Error?)> = .just((event: nil, error: nil))
if action != .doNotSend {
eventSingle = self.getEvent(for: action)
.flatMap { event in event.findAddress().map{ event }.catchErrorJustReturn(event) }
.map { event -> (event: VehicleEvent?, error: Error?) in (event: event, error: nil) }
.observeOn(MainScheduler.instance)
.catchError { .just((event: nil, error: $0)) }
}
let checkSingle = Api.checkVehicle(by: number, force: force)
.observeOn(MainScheduler.instance)
.map { (vehicle: Vehicle) -> Vehicle in
.map { (vehicle: Vehicle) -> (vehicle: Vehicle, error: Error?) in
try self.save(vehicle: vehicle)
print("+++ Vehicle saved")
return vehicle
return (vehicle: vehicle, error: nil)
}
.do (onError: { err in
.catchError { error in
let realm = try Realm()
if realm.object(ofType: Vehicle.self, forPrimaryKey: number) == nil {
if let existingVehicle = realm.object(ofType: Vehicle.self, forPrimaryKey: number) {
return .just((vehicle: existingVehicle, error: error))
} else {
let vehicle = Vehicle(number)
try realm.write { realm.add(vehicle, update: .all) }
self.getEvent(for: action)
//.flatMap { event in event.findAddress().map{ [event] }.catchErrorJustReturn([event]) }
.do(onError: { error in
print("+++ error getting event: \(error)")
}, onDispose: {
print("+++ Dispose")
})
.observeOn(MainScheduler.instance)
//.catchErrorJustReturn([])
.map { event in
try realm.write { vehicle.events.append(event) }
print("+++ event added")
return .just((vehicle: vehicle, error: error))
}
.subscribe()
.disposed(by: self.bag)
}
})
if case .doNotSend = action {
return checkSingle
return Single.zip(eventSingle, checkSingle).flatMap { eventResult, vehicleResult in
let errors = [eventResult.error, vehicleResult.error].map { error -> Error? in
if let clerror = error as? CLError {
if clerror.code != .denied {
return CocoaError.error(NSLocalizedString("Location error", comment: ""), reason: clerror.code.description)
} else {
return checkSingle
.flatMap { self.addEvent(to: $0, action: action) }
return nil
}
} else {
return error
}
}
.compactMap { $0 }
func addEvent(to vehicle: Vehicle, action: EventAction) -> Single<Vehicle> {
return self.getEvent(for: action).flatMap { event in
return event
.findAddress()
.map{ event }
.catchErrorJustReturn(event)
.flatMap { Api.add(event: $0, to: vehicle.freeze().getNumber()) }
.do(onDispose: {
print("+++ Dispose 2")
})
LocationManager.resetLastEvent()
if vehicleResult.vehicle.unrecognized {
let realm = try Realm()
if let event = eventResult.event {
try realm.write { vehicleResult.vehicle.events.append(event) }
}
return .just((vehicle: vehicleResult.vehicle, errors: errors))
} else {
if let event = eventResult.event {
return Api.add(event: event, to: vehicleResult.vehicle.getNumber())
.observeOn(MainScheduler.instance)
.map {
try self.save(vehicle: $0)
return $0
return (vehicle: $0, errors: errors)
}
} else {
return .just((vehicle: vehicleResult.vehicle, errors: errors))
}
}
//.catchErrorJustReturn(vehicle)
}
//.catchErrorJustReturn(vehicle)
}
deinit {
print("+++ CheckController deinit")
func showErrors(_ errors: [Error]) {
let observables = errors.map(rxShowError)
Observable.from(observables).concat().subscribe().disposed(by: self.bag)
}
func rxShowError(_ error: Error) -> Observable<Void> {
return Observable<Void>.create { observer in
self.show(error: error, animated: true) {
observer.on(.next(()))
observer.on(.completed)
}
return Disposables.create()
}
}
}

View File

@ -38,11 +38,13 @@ extension CocoaError {
}
extension UIViewController {
func show(error: Error) {
func show(error: Error, animated: Bool = true, completion: (() -> Void)? = nil) {
let msg = (error as NSError).displayMessage
let alert = UIAlertController(title: msg.title, message: msg.body, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
self.present(alert, animated: true)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { _ in
completion?()
}))
self.present(alert, animated: animated)
}
func showAlert(title: String, message: String) {

View File

@ -36,13 +36,11 @@ class RxLocationManagerDelegateProxy: DelegateProxy<CLLocationManager, CLLocatio
// MARK: - CLLocationManagerDelegate
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
print("+++ >>> locationManager didChangeAuthorization")
self.authSubject.onNext(status)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.first {
print("+++ >>> locationManager didUpdateLocations")
self.locationSubject.onNext(location)
}
}
@ -50,10 +48,8 @@ class RxLocationManagerDelegateProxy: DelegateProxy<CLLocationManager, CLLocatio
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
guard let err = error as? CLError else { return }
print("+++ >>> locationManager didFailWithError: \(error)")
if self.generalErrors.contains(err.code) {
// Pass general errors to all existing subjects
print("+++ >>> passing error to subjects, code: \(err.code)")
self.authSubject.onError(error)
self.locationSubject.onError(error)
} else if self.geocodingErrors.contains(err.code) {
@ -95,6 +91,9 @@ class LocationManager {
observer(.error(NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "Location permission error"])))
}
}, onError: { observer(.error($0)) })
case .denied:
observer(.error(CLError(.denied)))
break
default:
observer(.error(NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "Location permission error"])))
break
@ -107,7 +106,6 @@ class LocationManager {
private static func requestLocation() -> Single<VehicleEvent> {
let proxy = RxLocationManagerDelegateProxy.proxy(for: self.manager)
let single = proxy.getNewLocationSubject().take(1).asSingle().map { location -> VehicleEvent in
print("+++ >>> Initializing new event")
let event = VehicleEvent(lat: location.coordinate.latitude, lon: location.coordinate.longitude, speed: location.speed, dir: location.course)
self.lastEvent = event
return event
@ -118,14 +116,11 @@ class LocationManager {
static func requestCurrentLocation() -> Single<VehicleEvent> {
if let result = self.eventObservable {
print("+++ >>> requestCurrentLocation existing")
return result
} else {
print("+++ >>> requestCurrentLocation new")
self.eventObservable = self.checkPermissions().flatMap(self.requestLocation).do(onError: { _ in
self.eventObservable = nil
}, onDispose: {
print("+++ >>> stopUpdatingLocation")
self.eventObservable = nil
self.manager.stopUpdatingLocation()
})
@ -133,6 +128,10 @@ class LocationManager {
}
}
static func locationRequestInProgress() -> Bool {
return self.eventObservable != nil
}
static func getAddressForLocation(latitude: Double, longitude: Double) -> Single<String> {
return Single.create { observer in
let geocoder = CLGeocoder()
@ -152,4 +151,8 @@ class LocationManager {
}
}
}
static func resetLastEvent() {
self.lastEvent = nil
}
}