Fixes for receiving location

This commit is contained in:
Selim Mustafaev 2021-04-04 20:53:52 +03:00
parent a099d60b8f
commit 0a1f9d4363
5 changed files with 106 additions and 167 deletions

View File

@ -33,8 +33,8 @@
"repositoryURL": "https://github.com/onevcat/Kingfisher",
"state": {
"branch": null,
"revision": "2a10bf41da75599a9f8e872dbd44fe0155a2e00c",
"version": "5.15.8"
"revision": "2a6d1135af3915547c4b08c3b154a05e6f1075a3",
"version": "5.15.5"
}
},
{
@ -51,8 +51,8 @@
"repositoryURL": "https://github.com/realm/realm-cocoa",
"state": {
"branch": null,
"revision": "7ec5df0a700ef76ad930dcedb9c63c1b354979e1",
"version": "5.5.1"
"revision": "2dc2d259095051b997b76a07e859822661105303",
"version": "5.4.7"
}
},
{
@ -60,8 +60,8 @@
"repositoryURL": "https://github.com/realm/realm-core",
"state": {
"branch": null,
"revision": "66d79b3c5213fb14d491c1b22193077b488d49a6",
"version": "6.2.4"
"revision": "2df510904ad04287926b287b4e89b786de2808c8",
"version": "6.1.3"
}
},
{
@ -78,8 +78,8 @@
"repositoryURL": "https://github.com/ReactiveX/RxSwift.git",
"state": {
"branch": null,
"revision": "254617dd7fae0c45319ba5fbea435bf4d0e15b5d",
"version": "5.1.2"
"revision": "002d325b0bdee94e7882e1114af5ff4fe1e96afa",
"version": "5.1.1"
}
},
{
@ -87,8 +87,8 @@
"repositoryURL": "https://github.com/malcommac/SwiftDate.git",
"state": {
"branch": null,
"revision": "6190d0cefff3013e77ed567e6b074f324e5c5bf5",
"version": "6.3.1"
"revision": "a25913b19833860b61fac161a706e44834f03c47",
"version": "6.2.0"
}
}
]

View File

@ -63,149 +63,5 @@
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "27C2C8D7-42E9-4B34-AB1D-A2A00B31DBA3"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "AutoCat/Controllers/CheckController.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "390"
endingLineNumber = "390"
landmarkName = "check(number:action:force:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "507A1EC9-C1AB-4D60-82C0-3C73D3556F79"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "AutoCat/Controllers/CheckController.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "386"
endingLineNumber = "386"
landmarkName = "check(number:action:force:)"
landmarkType = "7">
<Locations>
<Location
uuid = "507A1EC9-C1AB-4D60-82C0-3C73D3556F79 - c652eeb3d8934ef5"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "closure #3 (Swift.Array&lt;AutoCat.VehicleEvent&gt;) throws -&gt; () in closure #2 (Swift.Error) throws -&gt; () in AutoCat.CheckController.check(number: Swift.String, action: AutoCat.EventAction, force: Swift.Bool) -&gt; RxSwift.PrimitiveSequence&lt;RxSwift.SingleTrait, AutoCat.Vehicle&gt;"
moduleName = "AutoCat"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/selim/Documents/dev/autocat/AutoCat/Controllers/CheckController.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "329"
endingLineNumber = "329"
offsetFromSymbolStart = "109">
</Location>
<Location
uuid = "507A1EC9-C1AB-4D60-82C0-3C73D3556F79 - a8cb23139c126154"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "closure #1 () -&gt; () in closure #3 (Swift.Array&lt;AutoCat.VehicleEvent&gt;) throws -&gt; () in closure #2 (Swift.Error) throws -&gt; () in AutoCat.CheckController.check(number: Swift.String, action: AutoCat.EventAction, force: Swift.Bool) -&gt; RxSwift.PrimitiveSequence&lt;RxSwift.SingleTrait, AutoCat.Vehicle&gt;"
moduleName = "AutoCat"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/selim/Documents/dev/autocat/AutoCat/Controllers/CheckController.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "329"
endingLineNumber = "329"
offsetFromSymbolStart = "34">
</Location>
</Locations>
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "159FCAA9-1442-4DBC-964C-64C42A54C925"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "AutoCat/Controllers/CheckController.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "354"
endingLineNumber = "354"
landmarkName = "getEvent(for:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "EE577186-7806-4EC3-A2CB-42B9A77AF142"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "AutoCat/Controllers/CheckController.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "349"
endingLineNumber = "349"
landmarkName = "getEvent(for:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "FBE8EF96-3DD2-4BDA-8FBB-431343BBDB68"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "AutoCat/Controllers/CheckController.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "381"
endingLineNumber = "381"
landmarkName = "check(number:action:force:)"
landmarkType = "7">
<Locations>
<Location
uuid = "FBE8EF96-3DD2-4BDA-8FBB-431343BBDB68 - ae2694a5a3b56690"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "closure #2 (AutoCat.VehicleEvent) -&gt; RxSwift.PrimitiveSequence&lt;RxSwift.SingleTrait, Swift.Array&lt;AutoCat.VehicleEvent&gt;&gt; in closure #2 (Swift.Error) throws -&gt; () in AutoCat.CheckController.check(number: Swift.String, action: AutoCat.EventAction, force: Swift.Bool) -&gt; RxSwift.PrimitiveSequence&lt;RxSwift.SingleTrait, AutoCat.Vehicle&gt;"
moduleName = "AutoCat"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/selim/Documents/dev/autocat/AutoCat/Controllers/CheckController.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "324"
endingLineNumber = "324"
offsetFromSymbolStart = "25">
</Location>
<Location
uuid = "FBE8EF96-3DD2-4BDA-8FBB-431343BBDB68 - 64aa8bf9bc307c10"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "closure #1 () -&gt; Swift.Array&lt;AutoCat.VehicleEvent&gt; in closure #2 (AutoCat.VehicleEvent) -&gt; RxSwift.PrimitiveSequence&lt;RxSwift.SingleTrait, Swift.Array&lt;AutoCat.VehicleEvent&gt;&gt; in closure #2 (Swift.Error) throws -&gt; () in AutoCat.CheckController.check(number: Swift.String, action: AutoCat.EventAction, force: Swift.Bool) -&gt; RxSwift.PrimitiveSequence&lt;RxSwift.SingleTrait, AutoCat.Vehicle&gt;"
moduleName = "AutoCat"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/selim/Documents/dev/autocat/AutoCat/Controllers/CheckController.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "324"
endingLineNumber = "324"
offsetFromSymbolStart = "28">
</Location>
</Locations>
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>

View File

@ -4,6 +4,7 @@ import RxSwift
import SwiftDate
import RxRealm
import PKHUD
import CoreLocation
enum EventAction {
case doNotSend
@ -17,6 +18,16 @@ enum HistoryFilter {
case outdated
}
extension String.StringInterpolation {
mutating func appendInterpolation(_ value: EventAction) {
switch value {
case .doNotSend: appendLiteral("do not send"); break
case .receiveAndSend: appendLiteral("receive and send"); break
case .sendSpecific(let event): appendLiteral("send specific (\(event.latitude), \(event.longitude)"); break
}
}
}
class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegate, PNKeyboardDelegate {
@IBOutlet weak var number: SwiftMaskTextfield!
@ -204,8 +215,13 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat
HUD.hide()
} 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)
//HUD.show(error: error)
}
}
.disposed(by: self.bag)
@ -235,6 +251,7 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat
// MARK: - UITextFieldDelegate
@IBAction func textFieldDidBeginEditing(_ textField: UITextField) {
print("+++ textFieldDidBeginEditing, requesting new location")
LocationManager.requestCurrentLocation().subscribe().disposed(by: self.bag)
}
@ -344,18 +361,22 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat
return Single.just(event)
}
if let event = LocationManager.lastEvent, (Date().timeIntervalSince1970 - event.date) < 15 {
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)")
let checkSingle = Api.checkVehicle(by: number, force: force)
.observeOn(MainScheduler.instance)
.map { (vehicle: Vehicle) -> Vehicle in
try self.save(vehicle: vehicle)
print("+++ Vehicle saved")
return vehicle
}
.do (onError: { err in
@ -365,11 +386,17 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat
try realm.write { realm.add(vehicle, update: .all) }
self.getEvent(for: action)
.flatMap { event in event.findAddress().map{ [event] }.catchErrorJustReturn([event]) }
//.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 { events in
try realm.write { vehicle.events.append(objectsIn: events) }
//.catchErrorJustReturn([])
.map { event in
try realm.write { vehicle.events.append(event) }
print("+++ event added")
}
.subscribe()
.disposed(by: self.bag)
@ -392,13 +419,20 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat
.map{ event }
.catchErrorJustReturn(event)
.flatMap { Api.add(event: $0, to: vehicle.freeze().getNumber()) }
.do(onDispose: {
print("+++ Dispose 2")
})
.observeOn(MainScheduler.instance)
.map {
try self.save(vehicle: $0)
return $0
}
.catchErrorJustReturn(vehicle)
//.catchErrorJustReturn(vehicle)
}
.catchErrorJustReturn(vehicle)
//.catchErrorJustReturn(vehicle)
}
deinit {
print("+++ CheckController deinit")
}
}

View File

@ -1,5 +1,6 @@
import UIKit
import PKHUD
import CoreLocation
extension NSError {
var displayMessage: (title: String, body: String) {
@ -57,3 +58,29 @@ extension HUD {
self.flash(.labeledError(title: msg.title, subtitle: msg.body), delay: 2.0)
}
}
extension CLError.Code: CustomStringConvertible {
public var description: String {
switch self {
case .locationUnknown: return "Location unknown"
case .denied: return "Access denied"
case .network: return "general, network-related error"
case .headingFailure: return "heading could not be determined"
case .regionMonitoringDenied: return "Location region monitoring has been denied"
case .regionMonitoringSetupDelayed: return "CL could not immediately initialize region monitoring"
case .regionMonitoringResponseDelayed: return "While events for this fence will be delivered, delivery will not occur immediately"
case .geocodeFoundNoResult: return "A geocode request yielded no result"
case .geocodeFoundPartialResult: return "A geocode request yielded a partial result"
case .geocodeCanceled: return "A geocode request was cancelled"
case .deferredFailed: return "Deferred mode failed"
case .deferredNotUpdatingLocation: return "Deferred mode failed because location updates disabled or paused"
case .deferredAccuracyTooLow: return "Deferred mode not supported for the requested accuracy"
case .deferredDistanceFiltered: return "Deferred mode does not support distance filters"
case .deferredCanceled: return "Deferred mode request canceled a previous request"
case .rangingUnavailable: return "Ranging cannot be performed"
case .rangingFailure: return "General ranging failure"
case .promptDeclined: return "Authorization request not presented to user"
default: return "Unknown location error (\(self.rawValue)"
}
}
}

View File

@ -36,11 +36,13 @@ 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)
}
}
@ -48,8 +50,10 @@ 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) {
@ -58,6 +62,11 @@ class RxLocationManagerDelegateProxy: DelegateProxy<CLLocationManager, CLLocatio
print("Unexpected CoreLocation error: \(error)")
}
}
func getNewLocationSubject() -> PublishSubject<CLLocation> {
self.locationSubject = PublishSubject<CLLocation>()
return self.locationSubject
}
}
class LocationManager {
@ -67,6 +76,7 @@ class LocationManager {
return mgr
}()
private static let bag = DisposeBag()
private static var eventObservable: Single<VehicleEvent>?
private(set) static var lastEvent: VehicleEvent?
private static func checkPermissions() -> Single<Void> {
@ -96,7 +106,8 @@ class LocationManager {
private static func requestLocation() -> Single<VehicleEvent> {
let proxy = RxLocationManagerDelegateProxy.proxy(for: self.manager)
let single = proxy.locationSubject.take(1).asSingle().map { location -> VehicleEvent in
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
@ -106,9 +117,20 @@ class LocationManager {
}
static func requestCurrentLocation() -> Single<VehicleEvent> {
return self.checkPermissions().flatMap(self.requestLocation).do(onDispose: {
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()
})
return self.eventObservable!
}
}
static func getAddressForLocation(latitude: Double, longitude: Double) -> Single<String> {