我正在尝试设置一个小型地理围栏(100米),以便在用户离开家时提醒用户.为此,我请求用户当前位置如下:
- (void)requestUsersCurrentLocation
{
if (self.locationManager == nil) self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = 100;
[self.locationManager startUpdatingLocation];
}
使用CLLocationManager的委托方法,我检查应用程序是否能够确定用户的当前位置.在我的测试中,这工作正常,应用程序继续调用我的attemptToRegisterGeofenceAlertForLocation:方法
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *location = [locations lastObject];
NSDate *eventDate = location.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (abs(howRecent) < 15.0)
{
[self.locationManager stopUpdatingLocation];
if([self attemptToRegisterGeofenceAlertForLocation:location])
{
[[NSNotificationCenter defaultCenter] postNotificationName:kGeofenceSetupSuccess object:nil];
}
else
{
[[NSNotificationCenter defaultCenter] postNotificationName:kGeofenceSetupFailure object:nil];
}
}
}
到现在为止还挺好.这是我的自定义函数,用于在用户当前位置周围注册相对较小的地理围栏:
- (BOOL)attemptToRegisterGeofenceAlertForLocation:(CLLocation *)location
{
// Do not create regions if support is unavailable or disabled
if (![CLLocationManager regionMonitoringAvailable]) return NO;
// Check the authorization status
if (([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorized) && ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusNotDetermined)) return NO;
// Clear out any old regions to prevent buildup.
if ([self.locationManager.monitoredRegions count] > 0)
{
for (id obj in self.locationManager.monitoredRegions)
{
[self.locationManager stopMonitoringForRegion:obj];
}
}
// If the overlay's radius is too large, registration fails automatically,
// so clamp the radius to the max value.
CLLocationDegrees radius = 100; // meters?
if (radius > self.locationManager.maximumRegionMonitoringDistance)
{
radius = self.locationManager.maximumRegionMonitoringDistance;
}
// Create the region to be monitored.
CLRegion *region = [[CLRegion alloc] initCircularRegionWithCenter:location.coordinate radius:radius identifier:kGeofenceIdentifier];
[self.locationManager startMonitoringForRegion:region];
return YES;
}
当用户退出地理围栏区域时,我会这样回复:
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
if([region.identifier isEqual:kGeofenceIdentifier])
{
if([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground)
{
// Fire a UILocationNotification
}
else
{
// Fire a UIAlertView
}
}
}
我已经确定该应用程序能够获取用户位置并且地理围栏已正确注册,但是我无法在实际设备(启用3G的iPhone)上触发它.我离开了地理围栏区域并且没有收到任何通知就走了几英里.我已成功设法通过大幅改变我的位置来接收模拟器中的警报.
我究竟做错了什么?
最佳答案 看起来您的半径设置为100M(好).距离过滤器也设置为100M,可能只是对你不利.在模拟器中,您可以获得非常精确的更新,因为您必须将它们传递进去.在实际测试中,您获得的Wifi逼近和细胞三角测量的坐标要小于精确坐标.
我的经验是,如果我使用kCLLocationAccuracyBest进行距离过滤,我会得到非常好的结果.由于区域监控已经从系统供电不足,因此只需将滤波器设置为最佳,就不会产生电池损坏.