【问题标题】:locationManager.stopUpdateLocations doesn't work after the app returns from the background state应用从后台状态返回后 locationManager.stopUpdateLocations 不起作用
【发布时间】:2020-12-03 11:09:42
【问题描述】:

我在后台使用地理定位跟踪,当应用程序在后台运行几分钟后,对 locationManager.stopUpdateLocations () 的调用停止工作 - 顶部的蓝条没​​有被移除,应用程序继续使用地理定位服务.如果您调用 locationManager.stopUpdateLocations() 而不将应用程序最小化到后台,则服务将关闭并且顶部的蓝条消失。任何遇到过这种情况的人,请帮忙,已经花了几天时间 - 都无济于事。禁用所有逻辑,剩下的就是:启动地理定位服务(locationManager.startUpdateLocations)并尝试停止(locationManager.stopUpdateLocations)。根本没有计时器或任何其他逻辑。

import CoreLocation

final class MyLocationService: NSObject, CLLocationManagerDelegate {

    private let locationManager = CLLocationManager()
    

    func sendCoord() {
        print("Send you coordinates")
    }
    
    func requestPermission() {
        locationManager.requestWhenInUseAuthorization()
    }
    
    func start() {
        locationManager.delegate = self
        locationManager.pausesLocationUpdatesAutomatically = false
        locationManager.allowsBackgroundLocationUpdates = true
        locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
        locationManager.distanceFilter = 300
        locationManager.startUpdatingLocation()
        
        sendCoord()
        
    }
    
    func stop() {

        locationManager.pausesLocationUpdatesAutomatically = true
        locationManager.stopUpdatingLocation()
        locationManager.allowsBackgroundLocationUpdates = false
        locationManager.delegate = nil 
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    
        sendCoord()
    }
}

这是我的 ViewController 类:

import UIKit
import Foundation
import CoreLocation

class ViewController: UIViewController {
        
    // *** Internal variables *** //
    private let locationService = MyLocationService()
    var needPermissionForLocationServices = false

    @IBOutlet weak var toolBar: UIToolbar!
    
    @IBOutlet weak var startLocationToolBarButton: UIBarButtonItem!
    
    @IBAction func startLocationToolBarButtonAction(_ sender: UIBarButtonItem) {
        
    if CLLocationManager.locationServicesEnabled() {

            switch(CLLocationManager.authorizationStatus()) {

                case .notDetermined, .restricted, .denied:
           
                    DispatchQueue.main.async(execute: {

                        let alert = UIAlertController(title: "Error!", message: "Location services is off", preferredStyle: UIAlertController.Style.alert)
                alert.addAction(UIAlertAction(title: "Go to settings?", style: UIAlertAction.Style.default, handler: { (alert: UIAlertAction!) in
                print("")
                            UIApplication.shared.open(NSURL(string:UIApplication.openSettingsURLString)! as URL)
                        }))
                        self.present(alert, animated: true, completion: nil)
                    })
                    
                case .authorizedAlways, .authorizedWhenInUse:

                    locationService.start()
                }
            } else {
                DispatchQueue.main.async(execute: {
                   let alert = UIAlertController(title: "Error!", message: "Location services is off", preferredStyle: UIAlertController.Style.alert)
                alert.addAction(UIAlertAction(title: "Go to settings?", style: UIAlertAction.Style.default, handler: { (alert: UIAlertAction!) in
                print("")
                    UIApplication.shared.open(NSURL(string:UIApplication.openSettingsURLString)! as URL)
                    }))
                    self.present(alert, animated: true, completion: nil)
                })
                locationService.requestPermission()
            }
         
    }

    @IBOutlet weak var stopLocationToolBarButton: UIBarButtonItem!
    
    @IBAction func stopLocationToolBarButtonAction(_ sender: UIBarButtonItem) {
        
        locationService.stop()
         
    }
    
    // *** View Controller Functions *** //
    
    deinit {
        print("Deinit: VC NO MEMORY LEAKS")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        locationService.requestPermission()
        
    }
    
    override func viewDidDisappear(_ animated: Bool) {

    }
    
    override func viewWillAppear(_ animated: Bool) {
       
        view.backgroundColor = UIColor.white
    }
    
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    
    }
}

【问题讨论】:

  • 请在上下文中显示代码。您的目标应该是制作一个我们可以用来重现问题的实际工作项目。我们不仅需要一些代码摘录;我们需要查看代码在视图控制器中的确切位置,以及应该触发它的内容。
  • 好的,修改文本
  • 什么时候打电话给stop?当您的应用在后台时,调用stop 函数的代码似乎没有执行。
  • 我通过点击 viewController 内的按钮来调用 stop,所以应用程序此时肯定处于活动状态并且处于前台

标签: ios swift swift4


【解决方案1】:

找到解决方案。您只需为 My Location Service 类创建一个共享实例,而不是在 ViewController 中将此类的实例创建为变量,而是调用相同的单例。原因是我创建了 My Location Service 类的不同实例,并在一个实例中启动了位置,并试图在另一个实例中停止它。

class var sharedInstance: MyLocationService {
    struct Singleton {
        static let instance = MyLocationService()
    }

    return Singleton.instance
}

并调用类方法:

MyLocationService.sharedInstance.start()

【讨论】:

  • “原因是我创建了我的位置服务类的不同实例,并在一个实例中启动了位置,并试图在另一个实例中停止它。”是的,这也是我的猜测。但这并不能使 Singleton 成为一个好的解决方案。另请注意,您的问题没有提示您如何最终获得多个实例。
  • 这很明显,因为我每次启动 ViewController 时都创建了一个类的实例
猜你喜欢
  • 2023-02-08
  • 2011-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多