swift - 在后台特定时间启动位置更新 - Swift (watchOS)
问题描述
我正在开发一个独立的 WatchOS 应用程序,其目的是识别用户何时离开特定区域,从而发送通知。为了做到这一点,该应用程序严重依赖后台位置更新。
到目前为止,应用程序运行良好。它根据 的distanceFilter
属性获取位置CLLocationManager
。问题是电池。我遵循的方法在执行中保持后台位置更新,即使它们仅在“覆盖”特定距离时才被获取。
我的想法是在用户离开该区域时禁用位置更新,并在夜间禁用此服务。但是,我面临着这种方法的严重问题。
我的主要问题是在后台禁用位置更新不允许我恢复它。我尝试这样做:
- 计时器。
scheduleBackgroundRefresh(withPreferredDate:userInfo:scheduledCompletion:)
startLocationUpdates()
方法,在委托中调用
似乎没有任何效果。我的问题是:
如果以前被禁用,有办法恢复后台位置更新吗? 先感谢您。
更新n.2:我尝试执行位置更新,WKApplicationRefreshBackgroundTask
但它只是忽略requestLocation()
功能(@RomuloBM 建议)
//In extension delegate handle() function
case let backgroundTask as WKApplicationRefreshBackgroundTask:
// Be sure to complete the background ta
LocMng = LocationManager() // I even tried to create a new element!
LocMng.LocMng.requestLocation()// it is just ignored
backgroundTask.setTaskCompletedWithSnapshot(false)
我在 LocationManager 中使用此功能调用后台任务:
//In didUpdateLocation
if background {
WKExtension.shared().scheduleBackgroundRefresh(withPreferredDate: Date(timeIntervalSinceNow: 30), userInfo: nil){ _ in
print("Done")
self.background = false
self.LocMng.stopUpdatingLocation()
}
}
作为参考,这是我的 LocationManager 类:
enum ScanningMode {
case Precise
case Normal
}
class LocationManager : NSObject, CLLocationManagerDelegate, UNUserNotificationCenterDelegate, ObservableObject {
let LocMng = CLLocationManager()
let NotMng = UNUserNotificationCenter.current()
var modeOfScanning: ScanningMode!
var region: CLCircularRegion!
var previousLocation: CLLocation!
// variables for position...
override init() {
super.init()
// stuff for my app...
modeOfScanning = .Precise
setupManager()
setupNotification()
startLocalization()
}
private func startLocalization(){
switch modeOfScanning!{
case ScanningMode.Precise:
LocMng.desiredAccuracy = kCLLocationAccuracyBest
LocMng.distanceFilter = 15
case ScanningMode.Normal:
LocMng.desiredAccuracy = kCLLocationAccuracyHundredMeters
LocMng.distanceFilter = 80
}
LocMng.startUpdatingLocation()
}
private func setupManager(){
LocMng.requestAlwaysAuthorization()
LocMng.delegate = self
LocMng.desiredAccuracy = kCLLocationAccuracyBest
}
private func setupNotification(){
NotMng.delegate = self
NotMng.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
if granted {
print("NotificationCenter Authorization Granted!")
}
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == CLAuthorizationStatus.authorizedAlways{
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
LocMng.allowsBackgroundLocationUpdates = true
// For the sake of clarity, I will cut out this chunk of code and
// just showing how I execute my action based on the result of location
// This is just an example
actualLocation = locations[length-1]
//find if in a forget
if previousLocation != nil{
if !region.contains(actualLocation!.coordinate) && region.contains(previousLocation!.coordinate){
//Schedule notification
LocMng.stopUpdatingLocation() // <- this does not allow me to resume
}
}
previousLocation = actualLocation
}
}
解决方案
推荐阅读
- apache-nifi - 如何在服务器上设置 nifi 注册表
- flask - 一次登录 Apache Superset 集成
- java - 如何在“数据”中获取“url”字段?
- django - 如何在 django 表单中将表单日期字段从公历更改为波斯日历?
- tesseract - 在make期间安装Tesseract问题
- ios - 当导航栏滑动隐藏时如何向上滚动 UIView
- php - MySQL Unrecognized Keyword near 选项
- c# - 在 x 数量产生/被摧毁后敌人停止产生?
- c++ - C++:`X&& goo();` 是函数声明还是变量定义?
- npm - JSDelivr URL 中的差异有和没有“最新”