2015-11-11 6 views
1

Я заметил, что всякий раз, когда я снова запустил приложение и посмотрю на следующий метод, я получаю, что возвращенный beaconRegion не является нулем. Как это работает?Жизненный цикл CLLocationManager для приложения мониторинга зоны маяка

beaconRegion = [self.locationManager.monitoredRegions member:beaconRegion]; 
// for more context on how I use this please look at the code below 

Другими словами, как же IOS обрабатывать распределение CLLocationManager? Разделяет ли он десериализацию каждый раз, когда приложение пробуждается и таким образом извлекает информацию о регионе?


Это выход консоли Xcode отладчика при выполнении кода ниже:

2015-11-11 09:44:13.718 RegionMonitoringTest[239:15121] AppDelegate: creating new location manager object 
2015-11-11 09:44:13.722 RegionMonitoringTest[239:15121] BeaconMonitoring class: in startRangingForBeacons, startupdatinglocation, range for my beacon 
2015-11-11 09:44:13.724 RegionMonitoringTest[239:15121] Region already in list 
2015-11-11 09:44:13.732 RegionMonitoringTest[239:15121] AppDelegate: Application did became active. 
2015-11-11 09:44:13.762 RegionMonitoringTest[239:15121] BeaconMonitoring -> LocationManager: didFailWithError | Error: Error Domain=kCLErrorDomain Code=0 "(null)" 
2015-11-11 09:44:13.762 RegionMonitoringTest[239:15121] Requesting to start ranging for beacons again. 
2015-11-11 09:44:13.762 RegionMonitoringTest[239:15121] BeaconMonitoring class: in startRangingForBeacons, startupdatinglocation, range for my beacon 
2015-11-11 09:44:13.767 RegionMonitoringTest[239:15121] Region already in list 

Ниже я вставить исходный код, что я использую, чтобы проверить это, это может быть полезно (оно основано на примере AirLocate, предоставленном Apple):

#import "AppDelegate.h" 
#define BEACON_REGION @"01020102-0102-0102-0102-010201020102" 

@interface AppDelegate() 

@property (strong, nonatomic) CLLocationManager *locationManager; 
@property (strong, nonatomic) NSMutableArray * monitoredRegions; 

@end 

@implementation AppDelegate 


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    // Override point for customization after application launch. 

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) { 
     NSLog(@"AppDelegate: being woken up after entering region"); 
    } 
    else{ 
     NSLog(@"AppDelegate: creating new location manager object"); 
     self.locationManager = [[CLLocationManager alloc] init]; 
     self.locationManager.pausesLocationUpdatesAutomatically = false; 
     self.locationManager.allowsBackgroundLocationUpdates = true; 
     self.locationManager.delegate = self; 

     if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) { 
      [self.locationManager requestAlwaysAuthorization]; 
     } 

     self.monitoredRegions = [[NSMutableArray alloc] initWithCapacity:10]; 

     [self startRangingForBeacons]; 
    } 

    return YES; 
} 

- (void)applicationWillResignActive:(UIApplication *)application { 
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 
    NSLog(@"AppDelegate: will resign active"); 

} 

- (void)applicationDidEnterBackground:(UIApplication *)application { 
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 

    NSLog(@"AppDelegate: did enter background"); 
} 

- (void)applicationWillEnterForeground:(UIApplication *)application { 
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 
    //[self.bluetoothDataSync stopScanning]; 

    NSLog(@"AppDelegate: did enter foreground"); 
} 

- (void)applicationDidBecomeActive:(UIApplication *)application { 
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 
    NSLog(@"AppDelegate: Application did became active."); 
} 

- (void)applicationWillTerminate:(UIApplication *)application { 
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 
    //[[UIApplication sharedApplication] cancelAllLocalNotifications]; 
    NSLog(@"AppDelegate: App will terminate"); 
} 

////////////////////////////////////////////////// 

- (void) startRangingForBeacons{ 
    NSLog(@"BeaconMonitoring class: in startRangingForBeacons, startupdatinglocation, range for my beacon"); 
    [self startMonitoringForRegion:[[NSUUID alloc] initWithUUIDString:BEACON_REGION] :@"my-beaconregion"]; 
} 


- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error { 
    NSString * message = [NSString stringWithFormat:@"BeaconMonitoring -> LocationManager: monitoringDidFailForRegion | Error: %@, Region identifier: %@", error, region.identifier]; 

    NSLog(@"%@", message); 
    NSLog(@"Requesting to start ranging for beacons again."); 
    [self startRangingForBeacons]; 
} 

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { 
    NSString * message = [NSString stringWithFormat:@"BeaconMonitoring -> LocationManager: didFailWithError | Error: %@", error]; 
    NSLog(@"%@", message); 
    NSLog(@"Requesting to start ranging for beacons again."); 
    [self startRangingForBeacons]; 
} 

- (void) startMonitoringForRegion:(NSUUID*)beaconUUID :(NSString*)regionIdentifier{ 
    CLBeaconRegion *beaconRegion = nil; 

    beaconRegion = [self.locationManager.monitoredRegions member:beaconRegion]; 

    if(beaconRegion) 
    { 
     NSLog(@"Region already in list"); 
    } 
    else{ 
     beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:beaconUUID identifier:regionIdentifier]; 

     beaconRegion.notifyEntryStateOnDisplay = YES; 
     beaconRegion.notifyOnEntry = YES; 
     beaconRegion.notifyOnExit = YES; 

     [self.locationManager startMonitoringForRegion:beaconRegion]; 
    } 

    [self.locationManager startRangingBeaconsInRegion:beaconRegion]; 
    [self.locationManager startUpdatingLocation]; 
    [self.monitoredRegions addObject:beaconRegion]; 
} 

- (void) stopRangingForbeacons{ 
    NSLog(@"BeaconMonitoring: stopRangingForbeacons - Stops updating location"); 
    [self.locationManager stopUpdatingLocation]; 

    for (int i=0; i < [self.monitoredRegions count]; i++) { 
     NSObject * object = [self.monitoredRegions objectAtIndex:i]; 

     if ([object isKindOfClass:[CLBeaconRegion class]]) { 
      CLBeaconRegion * region = (CLBeaconRegion*)object; 
      [self.locationManager stopMonitoringForRegion:region]; 
      [self.locationManager stopRangingBeaconsInRegion:region]; 
     } 
     else{ 
     NSLog(@"BeaconMonitoring: unrecongized object in beacon region list"); 
     } 
    } 
} 

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status 
{ 
    if (![CLLocationManager locationServicesEnabled]) { 
     NSLog(@"Couldn't turn on ranging: Location services are not enabled."); 
    } 

    if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorized) { 
     NSLog(@"Couldn't turn on monitoring: Location services not authorised."); 
    } 
} 


#pragma CLLocationManagerDelegate 

-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region { 

    NSLog(@"BeaconMonitoring: did enter region, will now start ranging beacons in this region"); 
    [manager startRangingBeaconsInRegion:(CLBeaconRegion*)region]; 
    [self.locationManager startUpdatingLocation]; 
} 


-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region { 
    NSLog(@"BeaconMonitoring: did exit region, will now: stop ranging beacons in this region; stop updating locations; stop scanning for BLE"); 

    [manager stopRangingBeaconsInRegion:(CLBeaconRegion*)region]; 
    [self.locationManager stopUpdatingLocation]; 

    NSDictionary * notificationData = @{ @"value" : @"exitedRegion"}; 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"dataUpdate" object:nil userInfo:notificationData]; 
} 

- (void) locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region 
{ 
    NSString * message = @"CLRegionState: "; 

    switch (state) { 
     case CLRegionStateInside: 
      message = @"CLRegionState: state inside"; 
      break; 
     case CLRegionStateOutside: 
      message = @"CLRegionState: state outside"; 
      break; 
     case CLRegionStateUnknown: 
      message = @"CLRegionState: state unknown"; 
      break; 
     default: 
      message = @"CLRegionState: default case"; 
      break; 
    } 

    NSLog(@"%@", message); 
} 

-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region { 

    bool rangedBeacons = false; 

    if ([beacons count]>0) { 
     for (int i=0; i<[beacons count]; i++) { 
      CLBeacon *beacon = [beacons objectAtIndex:i]; 
      if((beacon.major.intValue == 4) && (beacon.major.intValue == 8)){ 
       rangedBeacons = true; 
      } 
     } 
    } 

    if (rangedBeacons) { 
     NSLog(@"Region identifier: %@", region.identifier); 

     NSString * message = [NSString stringWithFormat:@"BeaconMonitoring: ranged a total of %lu, hence request scan start", (unsigned long)[beacons count]]; 
     NSLog(@"%@", message); 
    } 
} 

ответ

1

Поскольку мониторинг диспетчера местоположения работает даже в том случае, когда приложение не работает, например, было прекращено из-за давления памяти или убито пользователем в коммутаторе приложений, iOS необходимо сохранить список регионов приложений для мониторинга где-то вне приложения , и вы можете думать о monitoredRegions как отражение этого списка, а не свойство экземпляра, которое исчезает, когда объект освобождается.

Обратите внимание, например, что если вы создаете экземпляр нескольких менеджеров местоположения, все они имеют один и тот же список мониторинга - прямой результат списка, который хранится для каждого приложения на уровне ОС. Если вы начнете/прекратите мониторинг для региона в одном менеджере местоположений, это затронет всех остальных.

Все это относится к CLBeaconRegion, но также к «обычным» CLCircularRegion, потому что это функция мониторинга, а не специфическая для маяка.

 Смежные вопросы

  • Нет связанных вопросов^_^