未调用CoreLocation区域委托

时间:2012-02-16 22:36:15

标签: ios delegates core-location

我在iOS 5中遇到了CoreLocation区域委托方法的问题,无论是在模拟器还是在设备上。我正在尝试添加一个区域进行监控,然后等待didStartMonitoring委托回调。很少,它工作正常。但是,通常不会调用didStartMonitoringmonitoringDidFail。该区域确实已添加到monitoredRegions。委托对象设置正确,通常会调用didEnterRegiondidExitRegion。位置管理器永远不会发布。这是main thread。我已经检查了我能想到的所有条件。

-(id) init
{
   self = [super init];
   if( self ) {
      NSLog( @"initializing location manager" );
      self.locationManager = [[CLLocationManager alloc] init];
      locationManager.delegate = self;
      [locationManager startUpdatingLocation];
   }
   return self;
}

-(void) startMonitoringRegion
{
   BOOL monitoring = NO;    
   if ( [CLLocationManager regionMonitoringAvailable] ) {
      if ( [CLLocationManager regionMonitoringEnabled] ) {
         if( [CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized ) {
            monitoring = YES;
         } else {
            NSLog( @"app is not authorized for location monitoring" );
         }
      } else {
         NSLog( @"region monitoring is not enabled" );
      }
   } else {
      NSLog( @"region monitoring is not available" );
   }
   if( !monitoring ) return;

   CLRegion *region = [[CLRegion alloc] initCircularRegionWithCenter:locationManager.location.coordinate 
                                                          radius:50
                                                      identifier:@"majorRegion"];
   NSLog( @"trying to start monitoring for region %@", region );
   [locationManager startMonitoringForRegion:region desiredAccuracy:kCLLocationAccuracyBest];
}

-(void)     locationManager:(CLLocationManager*)manager 
didStartMonitoringForRegion:(CLRegion*)region
{
   NSLog( @"region monitoring started" );
}

- (void)   locationManager:(CLLocationManager *)manager
monitoringDidFailForRegion:(CLRegion *)region 
                 withError:(NSError *)error
{
   NSLog( @"region monitoring failed" );
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
   NSLog( @"location manager failed" );
}

有人有什么想法吗?我可以处理这个,但似乎didEnterRegiondidExitRegion委托方法有时也不一致,这对我来说是个大问题。

编辑:我可以在单个应用委托中复制此功能 - 没有自定义对象或任何内容。见下面的实施。区域被添加(打印时看到),但didStartMonitoringRegion永远不会被调用。

@implementation AppDelegate

@synthesize window = _window;
@synthesize locationManager;

-(void) startMonitoringRegion
{
   BOOL monitoring = NO;    
   if ( [CLLocationManager regionMonitoringAvailable] ) {
      if ( [CLLocationManager regionMonitoringEnabled] ) {
         if( [CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized )  {
            monitoring = YES;
         } else {
            NSLog( @"app is not authorized for location monitoring" );
         }
      } else {
         NSLog( @"region monitoring is not enabled" );
      }
   } else {
      NSLog( @"region monitoring is not available" );
   }
   if( !monitoring ) return;

   CLRegion *region = [[CLRegion alloc] initCircularRegionWithCenter:locationManager.location.coordinate 
                                                              radius:50.
                                                          identifier:@"majorRegion"];
   NSLog( @"trying to start monitoring for region %@", region );
   [locationManager startMonitoringForRegion:region desiredAccuracy:kCLLocationAccuracyBest];
}

-(void) printMonitoredRegions
{
   NSLog( @"printing regions:" );
   for( CLRegion* region in locationManager.monitoredRegions )
      NSLog( @"%@", region );
}


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
   NSLog( @"initializing location manager" );
   self.locationManager = [[CLLocationManager alloc] init];
   locationManager.delegate = self;
   [locationManager startUpdatingLocation];

   [self startMonitoringRegion];
   [self performSelector:@selector(printMonitoredRegions) withObject:nil afterDelay:2.];

   return YES;
}


- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
           fromLocation:(CLLocation *)oldLocation
{
   //NSLog( @"location updated" );
}

-(void)     locationManager:(CLLocationManager*)manager 
didStartMonitoringForRegion:(CLRegion*)region
{
   NSLog( @"region monitoring started" );
}

-(void) locationManager:(CLLocationManager*)manager didEnterRegion:(CLRegion*)region
{
   NSLog( @"did enter region" );
}

-(void) locationManager:(CLLocationManager*)manager didExitRegion:(CLRegion*)region
{
   NSLog( @"did exit region" );
}

- (void)   locationManager:(CLLocationManager *)manager
monitoringDidFailForRegion:(CLRegion *)region 
                 withError:(NSError *)error
{
   NSLog( @"region monitoring failed" );
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
   NSLog( @"location manager failed" );
}

@end

日志:

2012-02-21 10:53:50.397 locationtest[64440:f803] initializing location manager
2012-02-21 10:53:50.412 locationtest[64440:f803] trying to start monitoring for region (identifier majorRegion) <LAT,LONG> radius 50.00m
2012-02-21 10:53:52.414 locationtest[64440:f803] printing regions:
2012-02-21 10:53:52.416 locationtest[64440:f803] (identifier majorRegion <LAT,LONG> radius 50.00m

编辑2:我刚注意到CLLocationManagerDelegate协议的iOS implementationMac implementation略有不同 - 值得注意的是,Mac没有didStartMonitoringRegion。有没有办法让我不小心使用Mac库而不是iOS库?

3 个答案:

答案 0 :(得分:3)

看看Apple说的话:

http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html

测试您应用的区域监控支持

在iOS模拟器或设备上测试区域监控代码时,请注意区域事件可能不会在跨越区域边界后立即发生。为防止虚假通知,iOS在满足某些阈值条件之前不会发送区域通知。具体而言,用户的位置必须越过区域边界并远离该边界移动最小距离,并在报告通知之前保持最小距离至少20秒。

特定阈值距离由当前可用的硬件和位置技术决定。例如,如果禁用Wi-Fi,则区域监控的准确性要低得多。但是,出于测试目的,您可以假设最小距离约为200米。

答案 1 :(得分:0)

您的区域半径非常小,您无法获得准确的拾取。尝试将它从半米扩展到10或20,然后在那里工作。

您也可以尝试设置精度,但半径是您几乎可以肯定的主要问题。

更新

我刚刚注意到你正在调用-startUpdatingLocatuon而不是-startMonitoringRegion。尝试将代码包含在构建CLRegion的位置并添加它以进行监视。

答案 2 :(得分:0)

对于寻找答案的其他人:监控区域必须明确停止。在应用程序终止之前或手动(使其显而易见)(这是因为它实际上在后台运行)

如果你看到didStartMonitoringFor被调用但是你不再看到它了,因为你已经在监视(即使你关闭了应用程序)