IOS13:CoreLocation:CLVisit 稍后停止调用委托
IOS 13: CoreLocation: CLVisit stop calling delegate after a while
将我的 iPhone 升级到 IOS 13.* DidVisit CoreLocation 委托 的回调是不再可靠了。
我没有更改这方面的任何代码。自 IOS 9(应用程序开发开始)以来一切正常。
它像往常一样启动,但过了一会儿它停止调用回调 "didVisit" 然后没有任何东西让它恢复生机(有时重新启动正在恢复,有时是新的应用程序版本),但我没有看到任何模式...
有人看到同样的问题吗?
编辑:
正如 Nevan King 告诉我的那样,它甚至可以与 IOS 13 一起工作,我现在将提供相关的代码块和今天早上 运行 的日志。也许有人可以告诉我代码有什么问题...
位置管理器正在工作,委托回调(didUpdateLocations、didEnterRegion 等)都被调用,除了回调 "didVisit"。
真是奇怪!
首先:这是设置位置管理器的方法
// --------------------------------------------------------------------
// startRunLoop()
// --------------------------------------------------------------------
func startRunLoop(preferMain: Bool) {
// before we start the location manager we wait for the user accepted the privacy explanation
checkAndWaitForStartViewController(from: "WTSRunLoop startRunLoop(preferMain: \(preferMain)")
// explicit call on main thread
DispatchQueue.main.async(execute: {
#if DEBUG_NSLOG_CUR
NSLog("WTSRunLoop: set WTS_LocationManager, his delegate, WTS_MotionActivityManager and WTS_MotionActivityQueue")
#endif
// ---------------------------------------
// first step, just cean up left overs, just to be on the save side
if self.WTS_LocationManager != nil {
if self.WTS_LocationManager!.delegate != nil {
self.WTS_LocationManager!.delegate = nil
#if DEBUG_NSLOG_CUR
NSLog("WTSRunLoop: just set WTS_LocationManager!.delegate = nil, as it was not nil")
#endif
}
self.WTS_LocationManager = nil
#if DEBUG_NSLOG_CUR
NSLog("WTSRunLoop: just set WTS_LocationManager = nil, as it was not nil")
#endif
}
// get the location manager and set the delegate
self.WTS_LocationManager = CLLocationManager()
self.WTS_LocationManager!.delegate = self
// set the semaphore, that we did create the location manager
#if DEBUG_NSLOG_CUR
NSLog("WTSRunLoop: call WTS_LocationManagerDispatchGroup.leave()")
#endif
WTS_LocationManagerDispatchGroup.leave()
...
})
}
二:开启访问监控的方法
/**
-----------------------------------------------------------------------------------------------
WTS_StartVisitMonitoring()
-----------------------------------------------------------------------------------------------
*/
var WTS_StartVisitMonitoringDone : Bool = false
func WTS_StartVisitMonitoring(checkRegion: Bool) {
#if DEBUG_NSLOG_CUR
NSLog("WTS_StartVisitMonitoring(): just started")
#endif
// just a test if we still run on the same locationManager
if self.WTS_LocationManager != nil {
if self.WTS_OldLocationManager != self.WTS_LocationManager {
#if DEBUG_NSLOG_CUR
NSLog("WTS_StartVisitMonitoring(): WTS_OldLocationManager (\(self.WTS_OldLocationManager.debugDescription)) != WTS_LocationManager (\(self.WTS_LocationManager.debugDescription)), set WTS_StartVisitMonitoringDone = false")
#endif
WTS_StartVisitMonitoringDone = false
self.WTS_OldLocationManager = self.WTS_LocationManager
}
}
// make sure we do this only once
if self.WTS_StartVisitMonitoringDone == false {
// set the flag
self.WTS_StartVisitMonitoringDone = true
// if we didn't have a valif location manager so far, wait for it
if self.WTS_LocationManager == nil {
#if DEBUG_NSLOG_CUR
NSLog("WTS_StartVisitMonitoring(): WTS_LocationManager == nil, call WTS_LocationManagerDispatchGroup.wait()")
#endif
WTS_LocationManagerDispatchGroup.wait()
}
#if DEBUG_NSLOG_CUR
NSLog("WTS_StartVisitMonitoring(): will try to call WTS_LocationManager!.startMonitoringVisits() on main thread")
#endif
DispatchQueue.main.async(execute: {
#if DEBUG_NSLOG_CUR
NSLog("WTS_StartVisitMonitoring().main: call WTS_LocationManager!.startMonitoringVisits() on main thread")
#endif
self.WTS_LocationManager!.startMonitoringVisits()
})
// check if we should do a check to adjust the visits Region
if checkRegion == true {
#if DEBUG_NSLOG_CUR
NSLog("WTS_StartVisitMonitoring(): checkRegion == true, will call WTS_CheckForVisitRegion()")
#endif
self.WTS_CheckForVisitRegion()
}
} else {
#if DEBUG_NSLOG_CUR
NSLog("WTS_StartVisitMonitoring(): WTS_StartVisitMonitoringDone == \(self.WTS_StartVisitMonitoringDone), do nothing")
#endif
}
}
三:运行今早的日志相关部分
2019-11-08 06:10:13.647 App[2156:734589] WTSRunLoop init(), <<< IOS 13 >>> now call startRunLoop(true)
2019-11-08 06:10:13.647 App[2156:734589] checkAndWaitForStartViewController(from: WTSRunLoop startRunLoop(preferMain: true): just started, will call now myStartupDispatchGroup.wait()
...
2019-11-08 06:10:13.726 App[2156:734589] checkAndWaitForStartViewController(from: WTSRunLoop startRunLoop(preferMain: true): after myStartupDispatchGroup.wait(), return
2019-11-08 06:10:13.727 App[2156:734584] WTSRunLoop: set WTS_LocationManager, his delegate, WTS_MotionActivityManager and WTS_MotionActivityQueue
2019-11-08 06:10:13.728 App[2156:734589] WTS_StartTrackSystem(): just started, wait for StartViewController
2019-11-08 06:10:13.728 App[2156:734584] WTSRunLoop: call WTS_LocationManagerDispatchGroup.leave()
2019-11-08 06:10:13.728 App[2156:734584] WTSRunLoop: WTS_MotionActivityManager != nil, all OK
2019-11-08 06:10:13.728 App[2156:734584] WTSRunLoop: WTS_MotionActivityQueue != nil, all OK
...
2019-11-08 06:10:14.435 App[2156:734584] locationManager(didChangeAuthorization:): just started, call checkAndHandleAuthorizationStatus()
2019-11-08 06:10:14.436 App[2156:734584] checkAndHandleAuthorisationStatus(): User gave permission to use Localisation also when not in use, now we can work
2019-11-08 06:10:14.436 App[2156:734584] checkAndHandleAuthorisationStatus(): user decided about authorization, call myAuthorizationDispatchGroup.leave()
2019-11-08 06:10:14.436 App[2156:734584] locationManager(didChangeAuthorization:): new authorizationStatus = .authorizedAlways
....
2019-11-08 06:10:14.438 App[2156:734589] WTS_SetYellowRed(): will call WTS_StartVisitMonitoring()
2019-11-08 06:10:14.438 App[2156:734589] WTS_StartVisitMonitoring(): just started
2019-11-08 06:10:14.439 App[2156:734589] WTS_StartVisitMonitoring(): WTS_OldLocationManager (nil) != WTS_LocationManager (Optional(<CLLocationManager: 0x2816b5120>)), set WTS_StartVisitMonitoringDone = false
2019-11-08 06:10:14.439 App[2156:734589] WTS_StartVisitMonitoring(): will try to call WTS_LocationManager!.startMonitoringVisits() on myRunLoop
2019-11-08 06:10:14.439 App[2156:734589] WTS_StartVisitMonitoring(): checkRegion == true, will call WTS_CheckForVisitRegion()
...
2019-11-08 06:10:14.497 App[2156:734584] WTS_StartVisitMonitoring().main: call WTS_LocationManager!.startMonitoringVisits() on main thread
...
编辑 2:
信不信由你,在我重新启动 iPhone 后,应用程序收到了几个 didVisit 事件(见下文)...
但这都是昨天早上和之前发生的事情。昨天和晚上什么都没有...
有人对这种行为有解释吗?
2019-11-08 08:16:55.700 App[283:5235] didVisit: New VisitEvent: <Lat, Lon>, Arrival: 06.11.2019, 20:21:41, Depart: 01.01.4001, 01:00:00), accuracy: 40.45339263770871
2019-11-08 08:17:00.568 App[283:5235] didVisit: New VisitEvent: <Lat, Lon>, Arrival: 06.11.2019, 20:21:41, Depart: 07.11.2019, 00:47:57), accuracy: 24.207239944549148
2019-11-08 08:17:00.663 App[283:5235] didVisit: New VisitEvent: <Lat, Lon>, Arrival: 07.11.2019, 00:54:20, Depart: 01.01.4001, 01:00:00), accuracy: 85.76831155108509
2019-11-08 08:17:03.698 App[283:5235] didVisit: New VisitEvent: <Lat, Lon>, Arrival: 07.11.2019, 00:54:20, Depart: 07.11.2019, 07:08:39), accuracy: 64.95511399529799
2019-11-08 08:17:03.778 App[283:5235] didVisit: New VisitEvent: <Lat, Lon>, Arrival: 07.11.2019, 07:16:14, Depart: 01.01.4001, 01:00:00), accuracy: 46.553598849932335
2019-11-08 08:17:12.808 App[283:5235] didVisit: New VisitEvent: <Lat, Lon>, Arrival: 07.11.2019, 07:16:14, Depart: 07.11.2019, 07:42:07), accuracy: 105.4615461367936
2019-11-08 08:17:12.909 App[283:5235] didVisit: New VisitEvent: <Lat, Lon>, Arrival: 07.11.2019, 07:50:36, Depart: 01.01.4001, 01:00:00), accuracy: 58.591188713846954
。
编辑 3:
又发生了...出乎意料的是,"didVisit" 回调不再被调用...
我启动了应用程序并监控了设备日志。我在日志中找到了这个,对我来说看起来不错,还是我错过了什么?
定位守护进程确认开始访问记录
com.apple.locationd.Core {"msg":"CLLocationManager", "event":"activity", "_cmd":"startMonitoringVisits", "self":"0x282655120"}
后来在状态消息中我发现:
locationd com.apple.locationd.Core {"msg":"Incoming message", "event":"activity", "name":"kCLConnectionMessageSignificantLocationVisit", "this":"0x10a0476d0", "registrationReceived":1}
locationd com.apple.locationd.Core {"msg":"#slv Client subscribe", "client":"myApp", "subscribe":1}
后来我发现了这个(好像访问记录开始了"VisitTimeStarted = ...")
locationd com.apple.locationd.Core {"msg":"#usesync Enqueued usage update message", "client":"myApp", "usage":"{\n BackgroundLocationTimeStarted = \"595586042.0572129\";\n FenceTimeStarted = \"595458288.958685\";\n LocationTimeStarted = \"595586039.822194\";\n NonPersistentSignificantTimeStopped = \"586698620.031068\";\n ReceivingLocationInformationTimeStarted = \"595586039.836334\";\n SignificantTimeStopped = \"594494158.865963\";\n VisitTimeStarted = \"595458288.95714\";\n}"}
CLVisit
仍在工作,委托方法仍在 iOS 13 中被调用。后台位置的权限系统在 iOS 13 中发生了变化,因此后台位置 API 将只几天后开始工作,并且只有在用户授予后台权限的情况下。
如果您想立即进行访问,请尝试转到您的应用设置,将位置权限切换为 "Always"。它可能在 "When In Use"。有关更多信息,请观看 WWDC 2019 What's New in Core Location
将我的 iPhone 升级到 IOS 13.* DidVisit CoreLocation 委托 的回调是不再可靠了。
我没有更改这方面的任何代码。自 IOS 9(应用程序开发开始)以来一切正常。
它像往常一样启动,但过了一会儿它停止调用回调 "didVisit" 然后没有任何东西让它恢复生机(有时重新启动正在恢复,有时是新的应用程序版本),但我没有看到任何模式...
有人看到同样的问题吗?
编辑:
正如 Nevan King 告诉我的那样,它甚至可以与 IOS 13 一起工作,我现在将提供相关的代码块和今天早上 运行 的日志。也许有人可以告诉我代码有什么问题...
位置管理器正在工作,委托回调(didUpdateLocations、didEnterRegion 等)都被调用,除了回调 "didVisit"。
真是奇怪!
首先:这是设置位置管理器的方法
// --------------------------------------------------------------------
// startRunLoop()
// --------------------------------------------------------------------
func startRunLoop(preferMain: Bool) {
// before we start the location manager we wait for the user accepted the privacy explanation
checkAndWaitForStartViewController(from: "WTSRunLoop startRunLoop(preferMain: \(preferMain)")
// explicit call on main thread
DispatchQueue.main.async(execute: {
#if DEBUG_NSLOG_CUR
NSLog("WTSRunLoop: set WTS_LocationManager, his delegate, WTS_MotionActivityManager and WTS_MotionActivityQueue")
#endif
// ---------------------------------------
// first step, just cean up left overs, just to be on the save side
if self.WTS_LocationManager != nil {
if self.WTS_LocationManager!.delegate != nil {
self.WTS_LocationManager!.delegate = nil
#if DEBUG_NSLOG_CUR
NSLog("WTSRunLoop: just set WTS_LocationManager!.delegate = nil, as it was not nil")
#endif
}
self.WTS_LocationManager = nil
#if DEBUG_NSLOG_CUR
NSLog("WTSRunLoop: just set WTS_LocationManager = nil, as it was not nil")
#endif
}
// get the location manager and set the delegate
self.WTS_LocationManager = CLLocationManager()
self.WTS_LocationManager!.delegate = self
// set the semaphore, that we did create the location manager
#if DEBUG_NSLOG_CUR
NSLog("WTSRunLoop: call WTS_LocationManagerDispatchGroup.leave()")
#endif
WTS_LocationManagerDispatchGroup.leave()
...
})
}
二:开启访问监控的方法
/**
-----------------------------------------------------------------------------------------------
WTS_StartVisitMonitoring()
-----------------------------------------------------------------------------------------------
*/
var WTS_StartVisitMonitoringDone : Bool = false
func WTS_StartVisitMonitoring(checkRegion: Bool) {
#if DEBUG_NSLOG_CUR
NSLog("WTS_StartVisitMonitoring(): just started")
#endif
// just a test if we still run on the same locationManager
if self.WTS_LocationManager != nil {
if self.WTS_OldLocationManager != self.WTS_LocationManager {
#if DEBUG_NSLOG_CUR
NSLog("WTS_StartVisitMonitoring(): WTS_OldLocationManager (\(self.WTS_OldLocationManager.debugDescription)) != WTS_LocationManager (\(self.WTS_LocationManager.debugDescription)), set WTS_StartVisitMonitoringDone = false")
#endif
WTS_StartVisitMonitoringDone = false
self.WTS_OldLocationManager = self.WTS_LocationManager
}
}
// make sure we do this only once
if self.WTS_StartVisitMonitoringDone == false {
// set the flag
self.WTS_StartVisitMonitoringDone = true
// if we didn't have a valif location manager so far, wait for it
if self.WTS_LocationManager == nil {
#if DEBUG_NSLOG_CUR
NSLog("WTS_StartVisitMonitoring(): WTS_LocationManager == nil, call WTS_LocationManagerDispatchGroup.wait()")
#endif
WTS_LocationManagerDispatchGroup.wait()
}
#if DEBUG_NSLOG_CUR
NSLog("WTS_StartVisitMonitoring(): will try to call WTS_LocationManager!.startMonitoringVisits() on main thread")
#endif
DispatchQueue.main.async(execute: {
#if DEBUG_NSLOG_CUR
NSLog("WTS_StartVisitMonitoring().main: call WTS_LocationManager!.startMonitoringVisits() on main thread")
#endif
self.WTS_LocationManager!.startMonitoringVisits()
})
// check if we should do a check to adjust the visits Region
if checkRegion == true {
#if DEBUG_NSLOG_CUR
NSLog("WTS_StartVisitMonitoring(): checkRegion == true, will call WTS_CheckForVisitRegion()")
#endif
self.WTS_CheckForVisitRegion()
}
} else {
#if DEBUG_NSLOG_CUR
NSLog("WTS_StartVisitMonitoring(): WTS_StartVisitMonitoringDone == \(self.WTS_StartVisitMonitoringDone), do nothing")
#endif
}
}
三:运行今早的日志相关部分
2019-11-08 06:10:13.647 App[2156:734589] WTSRunLoop init(), <<< IOS 13 >>> now call startRunLoop(true)
2019-11-08 06:10:13.647 App[2156:734589] checkAndWaitForStartViewController(from: WTSRunLoop startRunLoop(preferMain: true): just started, will call now myStartupDispatchGroup.wait()
...
2019-11-08 06:10:13.726 App[2156:734589] checkAndWaitForStartViewController(from: WTSRunLoop startRunLoop(preferMain: true): after myStartupDispatchGroup.wait(), return
2019-11-08 06:10:13.727 App[2156:734584] WTSRunLoop: set WTS_LocationManager, his delegate, WTS_MotionActivityManager and WTS_MotionActivityQueue
2019-11-08 06:10:13.728 App[2156:734589] WTS_StartTrackSystem(): just started, wait for StartViewController
2019-11-08 06:10:13.728 App[2156:734584] WTSRunLoop: call WTS_LocationManagerDispatchGroup.leave()
2019-11-08 06:10:13.728 App[2156:734584] WTSRunLoop: WTS_MotionActivityManager != nil, all OK
2019-11-08 06:10:13.728 App[2156:734584] WTSRunLoop: WTS_MotionActivityQueue != nil, all OK
...
2019-11-08 06:10:14.435 App[2156:734584] locationManager(didChangeAuthorization:): just started, call checkAndHandleAuthorizationStatus()
2019-11-08 06:10:14.436 App[2156:734584] checkAndHandleAuthorisationStatus(): User gave permission to use Localisation also when not in use, now we can work
2019-11-08 06:10:14.436 App[2156:734584] checkAndHandleAuthorisationStatus(): user decided about authorization, call myAuthorizationDispatchGroup.leave()
2019-11-08 06:10:14.436 App[2156:734584] locationManager(didChangeAuthorization:): new authorizationStatus = .authorizedAlways
....
2019-11-08 06:10:14.438 App[2156:734589] WTS_SetYellowRed(): will call WTS_StartVisitMonitoring()
2019-11-08 06:10:14.438 App[2156:734589] WTS_StartVisitMonitoring(): just started
2019-11-08 06:10:14.439 App[2156:734589] WTS_StartVisitMonitoring(): WTS_OldLocationManager (nil) != WTS_LocationManager (Optional(<CLLocationManager: 0x2816b5120>)), set WTS_StartVisitMonitoringDone = false
2019-11-08 06:10:14.439 App[2156:734589] WTS_StartVisitMonitoring(): will try to call WTS_LocationManager!.startMonitoringVisits() on myRunLoop
2019-11-08 06:10:14.439 App[2156:734589] WTS_StartVisitMonitoring(): checkRegion == true, will call WTS_CheckForVisitRegion()
...
2019-11-08 06:10:14.497 App[2156:734584] WTS_StartVisitMonitoring().main: call WTS_LocationManager!.startMonitoringVisits() on main thread
...
编辑 2:
信不信由你,在我重新启动 iPhone 后,应用程序收到了几个 didVisit 事件(见下文)...
但这都是昨天早上和之前发生的事情。昨天和晚上什么都没有...
有人对这种行为有解释吗?
2019-11-08 08:16:55.700 App[283:5235] didVisit: New VisitEvent: <Lat, Lon>, Arrival: 06.11.2019, 20:21:41, Depart: 01.01.4001, 01:00:00), accuracy: 40.45339263770871
2019-11-08 08:17:00.568 App[283:5235] didVisit: New VisitEvent: <Lat, Lon>, Arrival: 06.11.2019, 20:21:41, Depart: 07.11.2019, 00:47:57), accuracy: 24.207239944549148
2019-11-08 08:17:00.663 App[283:5235] didVisit: New VisitEvent: <Lat, Lon>, Arrival: 07.11.2019, 00:54:20, Depart: 01.01.4001, 01:00:00), accuracy: 85.76831155108509
2019-11-08 08:17:03.698 App[283:5235] didVisit: New VisitEvent: <Lat, Lon>, Arrival: 07.11.2019, 00:54:20, Depart: 07.11.2019, 07:08:39), accuracy: 64.95511399529799
2019-11-08 08:17:03.778 App[283:5235] didVisit: New VisitEvent: <Lat, Lon>, Arrival: 07.11.2019, 07:16:14, Depart: 01.01.4001, 01:00:00), accuracy: 46.553598849932335
2019-11-08 08:17:12.808 App[283:5235] didVisit: New VisitEvent: <Lat, Lon>, Arrival: 07.11.2019, 07:16:14, Depart: 07.11.2019, 07:42:07), accuracy: 105.4615461367936
2019-11-08 08:17:12.909 App[283:5235] didVisit: New VisitEvent: <Lat, Lon>, Arrival: 07.11.2019, 07:50:36, Depart: 01.01.4001, 01:00:00), accuracy: 58.591188713846954
。
编辑 3:
又发生了...出乎意料的是,"didVisit" 回调不再被调用...
我启动了应用程序并监控了设备日志。我在日志中找到了这个,对我来说看起来不错,还是我错过了什么?
定位守护进程确认开始访问记录
com.apple.locationd.Core {"msg":"CLLocationManager", "event":"activity", "_cmd":"startMonitoringVisits", "self":"0x282655120"}
后来在状态消息中我发现:
locationd com.apple.locationd.Core {"msg":"Incoming message", "event":"activity", "name":"kCLConnectionMessageSignificantLocationVisit", "this":"0x10a0476d0", "registrationReceived":1}
locationd com.apple.locationd.Core {"msg":"#slv Client subscribe", "client":"myApp", "subscribe":1}
后来我发现了这个(好像访问记录开始了"VisitTimeStarted = ...")
locationd com.apple.locationd.Core {"msg":"#usesync Enqueued usage update message", "client":"myApp", "usage":"{\n BackgroundLocationTimeStarted = \"595586042.0572129\";\n FenceTimeStarted = \"595458288.958685\";\n LocationTimeStarted = \"595586039.822194\";\n NonPersistentSignificantTimeStopped = \"586698620.031068\";\n ReceivingLocationInformationTimeStarted = \"595586039.836334\";\n SignificantTimeStopped = \"594494158.865963\";\n VisitTimeStarted = \"595458288.95714\";\n}"}
CLVisit
仍在工作,委托方法仍在 iOS 13 中被调用。后台位置的权限系统在 iOS 13 中发生了变化,因此后台位置 API 将只几天后开始工作,并且只有在用户授予后台权限的情况下。
如果您想立即进行访问,请尝试转到您的应用设置,将位置权限切换为 "Always"。它可能在 "When In Use"。有关更多信息,请观看 WWDC 2019 What's New in Core Location