ios - 在不耗尽电池电量的情况下以良好的准确性获取位置更新的最佳方法

标签 ios swift cllocationmanager energy

我一直在尝试实现一个 LocationView Controller ,它不断将用户位置更新到服务器。当我调试应用程序并在使用时,我注意到,我提供的源代码比平时更快地耗尽了我的手机电池。我是否必须解决这个问题,或者有什么方法可以在不减少 LocationRequirements 的情况下改进以下代码中的 PowerUsage?

class LocationViewController: UIViewController {
  // MARK: - Outlets
  @IBOutlet var mapView: MKMapView!

  fileprivate var locations = [MKPointAnnotation]()
  var updatesEnabled: Bool = false;

  var defaultCentre: NotificationCenter = NotificationCenter.default
  //- NSUserDefaults - LocationServicesControl_KEY to be set to TRUE when user has enabled location services.
  let UDefaults: UserDefaults = UserDefaults.standard;
  let LocationServicesControl_KEY: String = "LocationServices"


  public var lastPosition: Date?;

  public lazy var locationManager: CLLocationManager = {
    let manager = CLLocationManager()
    manager.distanceFilter = 20;
    manager.desiredAccuracy = kCLLocationAccuracyBest
    manager.delegate = self
    manager.requestAlwaysAuthorization()
    return manager
  }()

  public var routeLine: MKPolyline = MKPolyline() //your line
  public var routeLineView: MKPolylineView = MKPolylineView(); //overlay view
  // MARK: - Actions
  @available(iOS 9.0, *)
  @IBAction func enabledChanged(_ sender: UISwitch) {
    if sender.isOn {
      self.UDefaults.set(true, forKey: self.LocationServicesControl_KEY)
      locationManager.startUpdatingLocation()
      locationManager.allowsBackgroundLocationUpdates = true
      self.updatesEnabled = true;
    } else {
      self.UDefaults.set(false, forKey: self.LocationServicesControl_KEY)
      locationManager.stopUpdatingLocation()
      self.updatesEnabled = false;
      self.timer.invalidate()
      locationManager.allowsBackgroundLocationUpdates = false
    }
  }

  @IBAction func accuracyChanged(_ sender: UISegmentedControl) {
    let accuracyValues = [
      kCLLocationAccuracyBestForNavigation,
      kCLLocationAccuracyBest,
      kCLLocationAccuracyNearestTenMeters,
      kCLLocationAccuracyHundredMeters,
      kCLLocationAccuracyKilometer,
      kCLLocationAccuracyThreeKilometers]
    locationManager.desiredAccuracy = accuracyValues[sender.selectedSegmentIndex];
  }

  // MARK: - Override UIViewController
  override func viewDidLoad() {
    mapView.delegate = self;
  }
}

// MARK: - MKMapViewDelegate
extension LocationViewController: MKMapViewDelegate {
  func addRoute() {
    mapView.remove(self.routeLine);
    var pointsToUse: [CLLocationCoordinate2D] = [];
    for i in locations {
      pointsToUse += [i.coordinate];
    }
    self.routeLine = MKPolyline(coordinates: &pointsToUse, count: pointsToUse.count)
    mapView.add(self.routeLine)
  }
}

// MARK: - CLLocationManagerDelegate
extension LocationViewController: CLLocationManagerDelegate {

  func isUpdateValid (newDate: Date) -> Bool{
    var interval = TimeInterval()
    if(lastPosition==nil){lastPosition=newDate}
    interval = newDate.timeIntervalSince(lastPosition!)
    if ((interval==0)||(interval>=self.UpdatesInterval)){
      return true
    } else {
      return false
    }
  }

  func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let mostRecentLocation = locations.last else {
      return
    }
    if(isUpdateValid(newDate: mostRecentLocation.timestamp)){
      let position = MKPointAnnotation();
      position.coordinate=mostRecentLocation.coordinate;
      self.locations.append(position);
      self.addRoute();

      self.locationAPI.postLocation(location: mostRecentLocation)
      lastPosition=mostRecentLocation.timestamp
    }
  }
}

最佳答案

您需要限制 GPS 以某种方式“点亮”的时间。如果您将其设置为持续提供高精度 GPS 读数,它将使 GPS 保持通电状态,您将消耗大量电量。对此无能为力。

可能性:

您可以每 10 分钟唤醒一次 GPS,运行它直到获得良好的读数,然后再将其关闭。

当您的应用程序首次启动时,您会获得良好的读数,然后订阅重要的位置更改,当您获得更新时,开始位置更新,获得新的修复,然后再次关闭位置更新。

我不确定您会如何执行第一个选项,因为 Apple 不会让您的应用程序在后台无限期运行。您需要您的应用程序一直处于唤醒状态并在前台运行,这也比允许它进入休眠状态更快地耗尽电池电量。

关于ios - 在不耗尽电池电量的情况下以良好的准确性获取位置更新的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41885673/

相关文章:

ios - fatal error : Array index out of range when accessing an array of 10 elements in Swift

ios - 如何从 iOS 版谷歌地图获取当前缩放级别?

ios - ViewWillAppear 中的代码不起作用,为什么?

arrays - 二维数组扩展 Swift 3.1.1

swift - 具有集群和自定义 View 标记的 Google map 在放大和缩小时滞后太多

swift - 在 MKMapView 的区域成功设置为用户当前位置后,从 api 加载数据并显示注释

iphone - 这个分配语句是否适合 clocationmanager?

IOS拦截指定宽度的字符串

ios - 如何在 swift 3.3x 中从 AVURLAsset URL 访问视频/图像?

ios - 如何重新加载 UIAlertView 消息