我创建了多个地理围栏来监控区域进入/退出事件。
我在AppDelegate.h
文件中创建了位置管理器。
@interface AppDelegate : UIResponder <UIApplicationDelegate, CLLocationManagerDelegate>
@property (strong, nonatomic) UIWindow *window;
@property(nonatomic,retain)CLLocationManager *locationManager;
@property(nonatomic,retain)CLLocation *currentLocation;
+(AppDelegate *)sharedDelegate;
AppDelegate.m
档案
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (notification) {
NSLog(@"AppDelegate didFinishLaunchingWithOptions");
application.applicationIconBadgeNumber = 0;
}
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)])
{
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge|UIUserNotificationTypeAlert|UIUserNotificationTypeSound) categories:nil];
[application registerUserNotificationSettings:settings];
}
else // iOS 7 or earlier
{
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[application registerForRemoteNotificationTypes:myTypes];
}
if (!self.locationManager)
{
self.locationManager = [[CLLocationManager alloc] init];
}
self.locationManager.delegate = self;
//locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
self.locationManager.distanceFilter = 2.0f;
self.locationManager.activityType = CLActivityTypeAutomotiveNavigation;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
{
[self.locationManager requestAlwaysAuthorization];
}
if ([self.locationManager respondsToSelector:@selector(allowsBackgroundLocationUpdates)])
{
self.locationManager.allowsBackgroundLocationUpdates = YES;
}
if ([self.locationManager respondsToSelector:@selector(pausesLocationUpdatesAutomatically)])
{
self.locationManager.pausesLocationUpdatesAutomatically= NO;
}
[self.locationManager stopMonitoringSignificantLocationChanges];
if ([CLLocationManager locationServicesEnabled] && [CLLocationManager authorizationStatus] != kCLAuthorizationStatusDenied)
{
[self.locationManager startUpdatingLocation];
}
// Override point for customization after application launch.
return YES;
}
-(void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
{
NSLog(@"Started monitoring %@ region",region.identifier);
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
NSLog(@"%@",[locations description]);
}
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
dispatch_async(dispatch_get_main_queue(), ^{
if ([[UIApplication sharedApplication] applicationState]==UIApplicationStateBackground || [[UIApplication sharedApplication] applicationState]==UIApplicationStateInactive)
{
UILocalNotification *localnotification = [[UILocalNotification alloc]init];
localnotification.fireDate=[NSDate dateWithTimeIntervalSinceNow:1];
localnotification.alertBody=@"You are enter in region.";
localnotification.timeZone=[NSTimeZone defaultTimeZone];
localnotification.repeatInterval = 0;
localnotification.hasAction=YES;
[[UIApplication sharedApplication]scheduleLocalNotification:localnotification];
}
else
{
[[[UIAlertView alloc]initWithTitle:@"message" message:@"Enter into region." delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok ", nil] show];
}
});
}
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
dispatch_async(dispatch_get_main_queue(), ^{
if ([[UIApplication sharedApplication] applicationState]==UIApplicationStateBackground || [[UIApplication sharedApplication] applicationState]==UIApplicationStateInactive)
{
UILocalNotification *localnotificationExit = [[UILocalNotification alloc]init];
localnotificationExit.fireDate=[NSDate dateWithTimeIntervalSinceNow:1];
localnotificationExit.alertBody=@"You are exit from region.";
NSLog(@"Exit from region.");
localnotificationExit.timeZone=[NSTimeZone defaultTimeZone];
localnotificationExit.repeatInterval = 0;
localnotificationExit.hasAction=YES;
[[UIApplication sharedApplication]scheduleLocalNotification:localnotificationExit];
}
else
{
[[[UIAlertView alloc]initWithTitle:@"message" message:@"Exit from region." delegate:self cancelButtonTitle:nil otherButtonTitles:@"Ok ", nil] show];
}
});
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"didFailWithError: %@", error);
[[[UIAlertView alloc] initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
}
这是管理区域监控的事情。
现在我的视图控制器正在添加监控区域。
-(void)AddRegionsInGeoFence
{
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
//----1
CLLocationCoordinate2D centerCoordinate1 = CLLocationCoordinate2DMake(23.046518, 72.543337);
CLCircularRegion *region1 =[[CLCircularRegion alloc] initWithCenter:centerCoordinate1 radius:200 identifier:@"Location First"];
NSLog(@"%@",[region1 description]);
region1.notifyOnEntry=YES;
region1.notifyOnExit=YES;
if (![standardDefaults boolForKey:@"EnterRegion"])
{
[[AppDelegate sharedDelegate].locationManager startMonitoringForRegion:region1];
NSLog(@"Started Monitoring- %@", [region1 description]);
}
[self.mapview setShowsUserLocation:YES];
[self.mapview setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
//----2
CLLocationCoordinate2D centercoordinate2=CLLocationCoordinate2DMake(23.064381, 72.531181);
CLCircularRegion *region2=[[CLCircularRegion alloc]initWithCenter:centercoordinate2 radius:200 identifier:@"Location Second"];
NSLog(@"%@",[region2 description]);
region2.notifyOnEntry=YES;
region2.notifyOnExit=YES;
if (![standardDefaults boolForKey:@"EnterRegion"])
{
[[AppDelegate sharedDelegate].locationManager startMonitoringForRegion:region2];
NSLog(@"Started Monitoring- %@", [region2 description]);
}
//----3
CLLocationCoordinate2D centercoordinate3=CLLocationCoordinate2DMake(23.083583,72.546441);
CLCircularRegion *region3=[[CLCircularRegion alloc]initWithCenter:centercoordinate3 radius:200 identifier:@"Location Third"];
NSLog(@"%@",[region3 description]);
region3.notifyOnEntry=YES;
region3.notifyOnExit=YES;
if (![standardDefaults boolForKey:@"EnterRegion"])
{
[[AppDelegate sharedDelegate].locationManager startMonitoringForRegion:region3];
NSLog(@"Started Monitoring- %@", [region3 description]);
}
//4
CLLocationCoordinate2D centercoordinate4=CLLocationCoordinate2DMake(23.122255, 72.584499);
CLCircularRegion *region4=[[CLCircularRegion alloc]initWithCenter:centercoordinate4 radius:500 identifier:@"Location Fourth"];
NSLog(@"%@",[region4 description]);
region4.notifyOnEntry=YES;
region4.notifyOnExit=YES;
if (![standardDefaults boolForKey:@"EnterRegion"])
{
[[AppDelegate sharedDelegate].locationManager startMonitoringForRegion:region4];
NSLog(@"Started Monitoring- %@", [region4 description]);
[standardDefaults setBool:YES forKey:@"EnterRegion"];
[standardDefaults synchronize];
}
}
我的问题是区域监控方法被多次调用,即使我没有移动到区域本身。其他一切工作正常,准确性缓冲区大约是50-80 meters
,这对我来说很好。
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
此外,如果我关闭Wi-Fi,那么它会反复调用这些方法,说退出区域并进入区域。据我所知,GPS的准确性取决于Wi-Fi。
任何帮助都将受到高度赞赏。
答案 0 :(得分:0)
a Possible workaround in the interim while the apple bug gets fixed is to rate limit the callback; thereby not acting on all the callbacks but limiting the rate at which the callbacks can get processed.
Callback execution portions that happen before the time period expires get ignored.
Here is and example code that could assist, not tested: The rate is limited to 2 seconds.
-(void)methodRateLimit {
@synchronized(self) {
// rate limit begin
static NSDate *lastTimeExit = nil;
if (!lastTimeExit) {
lastTimeExit = [NSDate distantPast]; // way back in time
}
NSDate *now = [NSDate date];
if ([now timeIntervalSinceDate:lastTimeExit] > 2) {
// do work here
NSLog(@"Executing");
lastTimeExit = now;
} else {
NSLog(@"Limiting");
}
}
}