Created
October 30, 2017 17:52
-
-
Save soxjke/eeab169d980e152c64e7dda05d2d7d11 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import CoreLocation | |
import ReactiveSwift | |
class LocationService: NSObject { | |
static let shared: LocationService = LocationService() | |
fileprivate lazy var locationManager: CLLocationManager = self.setupLocationManager() | |
fileprivate let appStore: AppStore = AppStore.shared | |
private override init() { | |
super.init() | |
setupObserving() | |
} | |
private func setupObserving() { | |
let locationProducer = self.appStore.producer | |
.map { $0.location.locationState } | |
.skipRepeats() | |
.observe(on: QueueScheduler.main) | |
locationProducer | |
.filter { $0 == .notYetRequested } | |
.startWithValues { [weak self] _ in self?.locationManager.requestWhenInUseAuthorization() } | |
locationProducer | |
.filter { $0 == .available } | |
.startWithValues { [weak self] _ in self?.appStore.consume(event: .locationRequest) } | |
let locationRequestProducer = self.appStore.producer | |
.map { $0.location.locationRequestState } | |
.skipRepeats() // To use skipRepeats we have to implement equatable for LocationRequestState | |
.observe(on: QueueScheduler.main) | |
locationRequestProducer | |
.filter { $0 == .updating} | |
.startWithValues { [weak self] _ in self?.locationManager.startUpdatingLocation() } | |
locationRequestProducer | |
.filter { $0 != .updating && $0 != .none } // get only success or error | |
.startWithValues { [weak self] _ in self?.locationManager.stopUpdatingLocation() } | |
} | |
private func setupLocationManager() -> CLLocationManager { | |
let result = CLLocationManager() | |
result.delegate = self | |
result.desiredAccuracy = kCLLocationAccuracyKilometer | |
return result | |
} | |
} | |
extension LocationService: CLLocationManagerDelegate { | |
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { | |
appStore.consume(event: status.appEvent) | |
} | |
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { | |
appStore.consume(event: .locationResult(latitude: 0, longitude: 0, timestamp: 0, error: error)) | |
} | |
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { | |
guard let location = locations.first else { return } | |
appStore.consume(event: .locationResult(latitude: location.coordinate.latitude, | |
longitude: location.coordinate.longitude, | |
timestamp: location.timestamp.timeIntervalSince1970, | |
error: nil)) | |
} | |
} | |
private extension CLAuthorizationStatus { | |
var appEvent: AppEvent { | |
switch self { | |
case .notDetermined, .restricted, .denied: return .locationPermissionResult(success: false) | |
case .authorizedWhenInUse, .authorizedAlways: return .locationPermissionResult(success: true) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment