locationManager.stopUpdateLocations 在应用程序 returns 从后台状态后不起作用
locationManager.stopUpdateLocations doesn't work after the app returns from the background state
我在后台使用地理定位跟踪,当应用程序在后台运行几分钟后,对 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 class:
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()
}
}
找到解决办法。您只需为我的位置服务 class 创建一个共享实例,而不是在 ViewController 中创建此 class 的实例作为变量,而是调用同一个单例。原因是我创建了“我的位置服务”的不同实例 class 并在一个实例中启动该位置并试图在另一个实例中停止它。
class var sharedInstance: MyLocationService {
struct Singleton {
static let instance = MyLocationService()
}
return Singleton.instance
}
并调用class方法:
MyLocationService.sharedInstance.start()
我在后台使用地理定位跟踪,当应用程序在后台运行几分钟后,对 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 class:
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()
}
}
找到解决办法。您只需为我的位置服务 class 创建一个共享实例,而不是在 ViewController 中创建此 class 的实例作为变量,而是调用同一个单例。原因是我创建了“我的位置服务”的不同实例 class 并在一个实例中启动该位置并试图在另一个实例中停止它。
class var sharedInstance: MyLocationService {
struct Singleton {
static let instance = MyLocationService()
}
return Singleton.instance
}
并调用class方法:
MyLocationService.sharedInstance.start()