diff --git a/AutoCat.xcodeproj/project.pbxproj b/AutoCat.xcodeproj/project.pbxproj index aa067c1..cc153ee 100644 --- a/AutoCat.xcodeproj/project.pbxproj +++ b/AutoCat.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 7A000AA224C2EEDE001F5B00 /* Location.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A000AA124C2EEDE001F5B00 /* Location.swift */; }; 7A051611241412CA00FC55AC /* SwiftDate in Frameworks */ = {isa = PBXBuildFile; productRef = 7A051610241412CA00FC55AC /* SwiftDate */; }; 7A0516162414EC1200FC55AC /* Differentiator in Frameworks */ = {isa = PBXBuildFile; productRef = 7A0516152414EC1200FC55AC /* Differentiator */; }; 7A0516182414EC1200FC55AC /* RxDataSources in Frameworks */ = {isa = PBXBuildFile; productRef = 7A0516172414EC1200FC55AC /* RxDataSources */; }; @@ -90,6 +91,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 7A000AA124C2EEDE001F5B00 /* Location.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Location.swift; sourceTree = ""; }; 7A0516192414FF0900FC55AC /* DateSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateSection.swift; sourceTree = ""; }; 7A1090E724A394F100B4F0B2 /* AudioRecordCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioRecordCell.swift; sourceTree = ""; }; 7A1090E924A3A26300B4F0B2 /* AudioPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlayer.swift; sourceTree = ""; }; @@ -266,6 +268,7 @@ 7A11474323FF06CA00B424AF /* Api.swift */, 7A27ADF6249FEF690035F39E /* Recorder.swift */, 7A1090E924A3A26300B4F0B2 /* AudioPlayer.swift */, + 7A000AA124C2EEDE001F5B00 /* Location.swift */, ); path = Utils; sourceTree = ""; @@ -537,6 +540,7 @@ 7A64AE752469DFB600ABE48E /* MediaBrowserViewController.swift in Sources */, 7A64AE732469DFB600ABE48E /* DismissAnimationController.swift in Sources */, 7A64AE812469E16100ABE48E /* ProgressAnimatedView.swift in Sources */, + 7A000AA224C2EEDE001F5B00 /* Location.swift in Sources */, 7A7547E024032CB6004E8406 /* VehiclePhotoCell.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -683,7 +687,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 20; + CURRENT_PROJECT_VERSION = 21; DEVELOPMENT_TEAM = 46DTTB8X4S; INFOPLIST_FILE = AutoCat/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 13.0; @@ -705,7 +709,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 20; + CURRENT_PROJECT_VERSION = 21; DEVELOPMENT_TEAM = 46DTTB8X4S; INFOPLIST_FILE = AutoCat/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 13.0; diff --git a/AutoCat/Controllers/RecordsController.swift b/AutoCat/Controllers/RecordsController.swift index 7a7004c..8445235 100644 --- a/AutoCat/Controllers/RecordsController.swift +++ b/AutoCat/Controllers/RecordsController.swift @@ -59,6 +59,8 @@ class RecordsController: UIViewController, UITableViewDelegate { } self.tableView.rx.setDelegate(self).disposed(by: self.bag) + + LocationManager.requestCurrentLocation().subscribe().disposed(by: self.bag) } override func viewDidAppear(_ animated: Bool) { diff --git a/AutoCat/Info.plist b/AutoCat/Info.plist index 5c5318f..84a1b81 100644 --- a/AutoCat/Info.plist +++ b/AutoCat/Info.plist @@ -2,6 +2,8 @@ + NSLocationWhenInUseUsageDescription + Access is needed for storing locations of vehicles CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable diff --git a/AutoCat/Utils/Location.swift b/AutoCat/Utils/Location.swift new file mode 100644 index 0000000..b71352f --- /dev/null +++ b/AutoCat/Utils/Location.swift @@ -0,0 +1,82 @@ +import Foundation +import RxSwift +import RxCocoa +import CoreLocation + +struct VehicleEvent { + var date: Date + var latitude: Double + var longitude: Double + var speed: Double + var direction: Double +} + +class RxLocationManagerDelegateProxy: DelegateProxy, DelegateProxyType, CLLocationManagerDelegate { + + init(locationManager: ParentObject) { + super.init(parentObject: locationManager, delegateProxy: RxLocationManagerDelegateProxy.self) + } + + // MARK: - DelegateProxyType + + static func registerKnownImplementations() { + self.register { RxLocationManagerDelegateProxy(locationManager: $0) } + } + + static func currentDelegate(for object: CLLocationManager) -> CLLocationManagerDelegate? { + return object.delegate + } + + static func setCurrentDelegate(_ delegate: CLLocationManagerDelegate?, to object: CLLocationManager) { + object.delegate = delegate + } +} + +extension Reactive where Base: CLLocationManager { + var delegate: DelegateProxy { + return RxLocationManagerDelegateProxy.proxy(for: base) + } + + var didChangeAuthorization: ControlEvent { + let sel = #selector((CLLocationManagerDelegate.locationManager(_:didChangeAuthorization:)! as (CLLocationManagerDelegate) -> (CLLocationManager, CLAuthorizationStatus) -> Void)) + let source: Observable = delegate.methodInvoked(sel) + .map { arg in + let status = arg[1] as! CLAuthorizationStatus + return status + } + return ControlEvent(events: source) + } +} + +class LocationManager: { + static let shared = LocationManager() + + private let manager = CLLocationManager() + private let bag = DisposeBag() + + private func checkPermissions() -> Single { + return Single.create { observer in + switch CLLocationManager.authorizationStatus() { + case .authorizedWhenInUse: + observer(.success(())) + break + case .notDetermined: + self.manager.requestWhenInUseAuthorization() + _ = self.manager.rx.didChangeAuthorization.first().subscribe(onSuccess: { status in + + }, onError: { observer(.error($0)) }) + default: + observer(.error(NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "Location permission error"]))) + break + } + + return Disposables.create { } + } + } + + func requestCurrentLocation() -> Single { + return self.checkPermissions().map { + return VehicleEvent() + } + } +}