对为什么我的AppDelegate CLLocationManager有时无法成功确定CLRegionState(CLRegionState.unknown)感到困惑,即使我确保在didStartMonitoringForRegion
之后才调用requestStateForRegion
。似乎是某种我不明白我如何处理的竞争条件。
相关,当我得到CLRegionState.unknown时,我应该怎么做?继续请求状态,直到我得到一些东西?(这似乎很糟糕)
应用代表:
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
self.locationManager = [[CLLocationManager alloc] init];
[self.locationManager setDelegate:self];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(nonnull CLRegion *)region {
NSLog(@"%@", [NSString stringWithFormat:@"didStartMonitoringFor region with ID: %@", region.identifier]);
// delay per https://stackoverflow.com/a/33288103/3380970
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
[self.locationManager requestStateForRegion:region];
});
}
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(nonnull CLRegion *)region {
NSLog(@"%@", [NSString stringWithFormat:@"didDetermineState from AppDelegate CLLocationManager: %@ (%ld)", region.identifier, (long)state ]);
NSString *baseUrl = [self fetchBaseUrl];
switch (state) {
case CLRegionStateInside:
NSLog(@"%@", @"Determined .inside state for geofence");
[HelperFunctions postGeofenceTransitionWithBaseUrl:baseUrl region:region transitionType:1];
break;
default:
break;
}
}
原始日志:
Adding geofence with ID: 5:90fd74e0-cbc7-dbe5-20fc-b870203055e1
Adding geofence with ID: 8:d408f466-ea1b-6cbb-382f-f7567db61157
Adding geofence with ID: 7:ba97dda2-39a7-9b95-8ea9-ea183d69a858
didStartMonitoringFor region with ID: 5:90fd74e0-cbc7-dbe5-20fc-b870203055e1
didStartMonitoringFor region with ID: 8:d408f466-ea1b-6cbb-382f-f7567db61157
didStartMonitoringFor region with ID: 7:ba97dda2-39a7-9b95-8ea9-ea183d69a858
didDetermineState from AppDelegate CLLocationManager: 5:90fd74e0-cbc7-dbe5-20fc-b870203055e1 (0)
didDetermineState from AppDelegate CLLocationManager: 8:d408f466-ea1b-6cbb-382f-f7567db61157 (0)
didDetermineState from AppDelegate CLLocationManager: 7:ba97dda2-39a7-9b95-8ea9-ea183d69a858 (0)
谢谢
这是因为您在块内使用条目参数region
,而没有使其成为块变量。
在- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(nonnull CLRegion *)region {
中添加:
__block CLRegion *blockRegion = region;
并在您的块中使用blockRegion
。
每当你想要使用 requestStateForRegion 时都要小心。此方法可能会生成有关设备的当前位置的错误结果。由于我在LTE上使用不同的网络进行了一些实验,因此它会错过某些地区的某些状态,并且在WIFI上,我看到它会产生重复的计数器事件,例如对于位置A,它产生了进入和退出两个。我你仔细阅读了苹果文档下此方法的评论,它说
异步检索指定区域的缓存状态。
此缓存状态不准确。