Last active
January 5, 2017 22:41
-
-
Save nebiros/9c928e98e0115382ad38f4dd6c0f3639 to your computer and use it in GitHub Desktop.
BaseGeolocable example
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
// | |
// BaseGeolocable.swift | |
// | |
// Created by Juan Felipe Alvarez Saldarriaga on 11/11/16. | |
// | |
import Foundation | |
import CoreLocation | |
protocol BaseGeolocable: class, CLLocationManagerDelegate { | |
var currentLocation: CLLocation? { get set } | |
} | |
// MARK: - CLLocationManagerDelegate | |
extension BaseGeolocable { | |
func defaultLocationManager() -> CLLocationManager { | |
let manager = CLLocationManager() | |
manager.distanceFilter = kCLDistanceFilterNone | |
manager.desiredAccuracy = kCLLocationAccuracyThreeKilometers | |
manager.delegate = self | |
manager.requestWhenInUseAuthorization() | |
return manager | |
} | |
func setCurrentLocationWith(manager: CLLocationManager, locations: [CLLocation], completion: (() -> Void)? = nil) { | |
guard let newLocation = locations.last else { | |
return | |
} | |
// see: http://stackoverflow.com/a/12848776/255463 | |
// | |
// test the age of the location measurement to determine if the measurement is cached | |
// in most cases you will not want to rely on cached measurements | |
let locationAge = -newLocation.timestamp.timeIntervalSinceNow | |
if locationAge > 5.0 { | |
return | |
} | |
// test that the horizontal accuracy does not indicate an invalid measurement | |
if newLocation.horizontalAccuracy < 0 { | |
return | |
} | |
// test the measurement to see if it is more accurate than the previous measurement | |
if currentLocation == nil || (currentLocation?.horizontalAccuracy)! > newLocation.horizontalAccuracy { | |
// store the location as the "best effort" | |
currentLocation = newLocation | |
// test the measurement to see if it meets the desired accuracy | |
// | |
// IMPORTANT!!! kCLLocationAccuracyBest should not be used for comparison with location coordinate or altitidue | |
// accuracy because it is a negative value. Instead, compare against some predetermined "real" measure of | |
// acceptable accuracy, or depend on the timeout to stop updating. This sample depends on the timeout. | |
// | |
if newLocation.horizontalAccuracy <= manager.desiredAccuracy { | |
// we have a measurement that meets our requirements, so we can stop updating the location | |
// | |
// IMPORTANT!!! Minimize power usage by stopping the location manager as soon as possible. | |
// | |
manager.stopUpdatingLocation() | |
} | |
} | |
if let completion = completion { | |
completion() | |
} | |
} | |
} |
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
// | |
// ServiceLocationViewController.swift | |
// | |
// Created by Juan Felipe Alvarez Saldarriaga on 10/27/16. | |
// | |
import UIKit | |
import CoreLocation | |
final class ServiceLocationViewController: UIViewController { | |
lazy var locationManager: CLLocationManager = self.defaultLocationManager() | |
var viewModel: ServiceLocationViewModelProtocol? { | |
willSet { | |
viewModel?.viewDelegate = nil | |
} | |
didSet { | |
viewModel?.viewDelegate = self | |
} | |
} | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
locationManager.startUpdatingLocation() | |
} | |
} | |
// MARK: - Load | |
extension ServiceLocationViewController { | |
func loadGeolocation() { | |
guard let currentLocation = currentLocation else { | |
return | |
} | |
viewModel?.currentLocation = currentLocation | |
viewModel?.geolocationParentType = .service | |
viewModel?.geolocation() | |
} | |
} | |
// MARK: - BaseGeolocable | |
extension ServiceLocationViewController: BaseGeolocable { | |
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { | |
// FIXME: implement geolocable error (jf) | |
} | |
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { | |
self.setCurrentLocationWith(manager: manager, locations: locations, completion: { [unowned self] in | |
self.loadGeolocation() | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment