【发布时间】:2018-01-17 19:22:51
【问题描述】:
之后我有一个任务要在后台跟踪用户的位置,如果它的位置已经改变到超过 5 英里,那么我需要在服务器上更新这个数据。我知道您可以使用 startMonitoringSignificantLocationChanges 开始跟踪用户位置。我开始测试,使用startMonitoringSignificantLocationChanges 和allowsBackgroundLocationUpdates = true 启动应用程序,然后从模拟器内存中删除应用程序,进入地图并启用 Free Way 模拟。一分钟我在服务器上得到了 8 次更新,对我来说太频繁了。我认为对我来说,最好的解决方案是如果我们询问我们希望从多远的距离接收更新。我读了几篇关于这个的帖子,但没有一篇没有解决我的问题。我还认为您可以保存以前的位置并将更改与新位置进行比较,但我认为这是一个坏主意。告诉我,如何更好地解决这个问题?
class LocationManager: NSObject {
private override init() {
super.init()
}
static let shared = LocationManager()
private let locationManager = CLLocationManager()
weak var delegate: LocationManagerDelegate?
// MARK: - Flags
private var isCallDidStartGetLocation = false
// MARK: - Measuring properties
private var startTimestamp = 0.0
// MARK: - Open data
var currentLocation: CLLocation?
// MARK: - Managers
private let locationDatabaseManager = LocationDatabaseManager()
// MARK: - Values
private let metersPerMile = 1609.34
func start() {
// measuring data
startTimestamp = Date().currentTimestamp
FirebasePerformanceManager.shared.getUserLocation(true)
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.activityType = .other
locationManager.distanceFilter = 100
locationManager.delegate = self
let status = CLLocationManager.authorizationStatus()
switch status {
case .authorizedAlways:
locationManager.startUpdatingLocation()
case .authorizedWhenInUse:
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
case .restricted, .notDetermined:
locationManager.requestAlwaysAuthorization()
case .denied:
showNoPermissionsAlert()
}
}
func logOut() {
locationManager.stopUpdatingLocation()
isCallDidStartGetLocation = false
}
}
// MARK: - Alerts
extension LocationManager {
private func showNoPermissionsAlert() {
guard let topViewController = UIApplication.topViewController() else { return }
let alertController = UIAlertController(title: "No permission",
message: "In order to work, app needs your location", preferredStyle: .alert)
let openSettings = UIAlertAction(title: "Open settings", style: .default, handler: {
(action) -> Void in
guard let URL = Foundation.URL(string: UIApplicationOpenSettingsURLString) else { return }
UIApplication.shared.open(URL, options: [:], completionHandler: nil)
})
alertController.addAction(openSettings)
topViewController.present(alertController, animated: true, completion: nil)
}
}
// MARK: - CLLocationManager Delegate
extension LocationManager: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .authorizedWhenInUse, .authorizedAlways:
locationManager.startUpdatingLocation()
default: break
}
delegate?.didChangeAuthorization?(manager: manager, didChangeAuthorization: status)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let lastLocation = locations.last else { return }
let timeInterval = abs(lastLocation.timestamp.timeIntervalSinceNow)
guard timeInterval < 60 else { return }
currentLocation = lastLocation
locationDatabaseManager.updateUserLocation(lastLocation)
measureGetLocationTime()
if !isCallDidStartGetLocation {
isCallDidStartGetLocation = true
delegate?.didStartGetLocation?()
}
}
}
// MARK: - Calculation
extension LocationManager {
func calculateDistanceFromCurrentLocation(_ venueLocation: CLLocation) -> Double {
guard let userLocation = locationManager.location else {
return 0.0
}
let distance = userLocation.distance(from: venueLocation)
let distanceMiles = distance / DistanceConvertor.metersPerMile //1609
return distanceMiles.roundToPlaces(places: 1)
}
}
// MARK: - Measuring functions
extension LocationManager {
private func measureGetLocationTime() {
FirebasePerformanceManager.shared.getUserLocation(false)
let endTimestamp = Date().currentTimestamp
let resultTimestamp = endTimestamp - startTimestamp
BugfenderManager.getFirstUserLocation(resultTimestamp)
}
}
【问题讨论】:
-
"我还以为你可以保存以前的位置并将更改与新位置进行比较,但我认为这是个坏主意。"是什么让您认为这是一个坏主意..?
-
@viz 例如,一个用户在 Free Way 上旅行,我们的应用程序在一分钟内运行约 8 次,我认为这些计算将使我们的应用程序成为最耗能的应用程序之一用户的设备。
-
通过网络发送数据消耗的能量最多。比较两个值不会占用太多能量。或者你可以简单地忽略一些运行,少做比较。
标签: ios swift core-location cllocationmanager