2013-12-13 51 views
0

我正在使用locationManager:didStartMonitoringForRegion:進行區域監控。有時回調包含錯誤的區域,即使在CLLocationManager.monitoredRegions中顯示的右側區域也是如此。locationManager:didStartMonitoringForRegion:錯誤區域回調

locationManager:didStartMonitoringForRegion:消息:

- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region { 
    NSLog(@"Started monitoring %@ region", region.identifier); 
    NSLog(@"Monitored regions: %@", self.locationManager.monitoredRegions); 
} 

這裏一個示例輸出(具有改變經度/ latidue保存地方)

2013-12-13 20:01:34.047 N[] Started monitoring Hamburg region 
2013-12-13 20:01:34.048 N[] Monitored regions: {(
    CLCircularRegion (identifier:'Hamburg', center:<+47.0,+8.1>, radius:1000.00m), 
    CLCircularRegion (identifier:'Zürich', center:<+47.0,+8.0>, radius:500.00m), 
    CLCircularRegion (identifier:'St.Gallen', center:<+47.0,+9.0>, radius:5000.00m) 
)} 
2013-12-13 20:01:42.070 N[] Started monitoring Hamburg region 
2013-12-13 20:01:42.072 N[] Monitored regions: {(
    CLCircularRegion (identifier:'Hamburg', center:<+47.0,+8.1>, radius:1000.00m), 
    CLCircularRegion (identifier:'Zürich', center:<+47.0,+8.0>, radius:500.00m), 
    CLCircularRegion (identifier:'St.Gallen', center:<+47.0,+9.0>, radius:5000.00m) 
)} 
2013-12-13 20:01:46.837 N[] Started monitoring Hamburg region 
2013-12-13 20:01:46.839 N[] Monitored regions: {(
    CLCircularRegion (identifier:'Hamburg', center:<+47.0,+8.1>, radius:1000.00m), 
    CLCircularRegion (identifier:'Zürich', center:<+47.0,+8.0>, radius:500.00m), 
    CLCircularRegion (identifier:'St.Gallen', center:<+47.0,+9.0>, radius:5000.00m) 
)} 

我開始didUpdateLocations監視其被稱爲我打電話startMonitoringSignificantLocationChanges

後回
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{ 
    NSLog(@"%s", __PRETTY_FUNCTION__); 
    [manager stopMonitoringSignificantLocationChanges]; 
    if (locations && [locations count]){ 
     CLLocation* position = [locations lastObject]; 
     NSLog(@"New Location latitude: %f longitude %f", position.coordinate.latitude, position.coordinate.longitude); 
     //self.geofences.allValues is containing Hamburg,Zürich and St.Gallen 
     for(CLCircularRegion *geofence in self.geofences.allValues) { 
      if(![self.locationManager.monitoredRegions containsObject:geofence]){ 
       [self.locationManager startMonitoringForRegion:geofence]; 
      } 
      if([geofence containsCoordinate:[position coordinate]]){ 
       [self locationManager:manager didEnterRegion:geofence]; 
      } 
     } 
    } 
} 

didEnterRegion@synchronized以保證原子性。

任何想法?

+0

你的意思是錯誤的?似乎你留在漢堡,胡默爾,胡默爾:-)在這種情況下還應該返回哪個區域? – thorb65

+0

我不知道你想解決什麼問題。如何註冊地區?向我們展示一些您的代碼並澄清您的問題。 –

+0

@DeanDavids我已經添加了一些代碼。問題是我開始監測3個地區(Hambug,蘇黎世和St.Gallen)。所以在此之後,我期待3個回調與這些地區。有時我得到三個(不同的)監控區域,有時候我沒有(如上所示) – cakl

回答

0

我不明白爲什麼它會出現重複註冊相同的區域。我的懷疑會導致我在那裏添加一些額外的NSLog調用來驗證源代碼self.geofences的內容。我要做的另一件事是在那裏休息觀察For循環中的值和條件。其他

兩個項目我會檢查:

  1. 確認您是從if(![self.locationManager.monitoredRegions containsObject:geofence]){得到預期的結果。不保證CLLocationManager中的對象與您最初註冊的對象相同。您應該使用isEqualToString正確測試標識符。您可能會無意中更換您的區域,因爲您已經寫入了該區域。
  2. 如果該地區已經註冊,我認爲您不需要撥打didEnterRegion。在發射之間報道邊界事件。即使應用程序被終止,它應該在重新啓動時自動處理。

如果這些都不能說明問題,我會研究如何以及何時啓動/停止位置服務。是否有可能每個調用都是didUpdateLocations方法的另一個迭代?

我認爲這是第一次被調用,在全新的會話中,monitoredRegions是空的,因此您的過程按預期工作。我發現在隨後的位置更新中可能出現不可預知的行爲的原因。

我會開始通過完全改變你的for循環。

if (locations && locations.count) { 
    CLLocation* position = [locations lastObject]; 
    NSSet *regionIdentifiers = [self.locationManager.monitoredRegions valueForKey:@"identifier"]; 
    NSSet *regionsForMonitoring = [NSSet setWithArray:self.geofences.allValues]; 
    NSSet *unMonitoredRegions = [regionsForMonitoring objectsPassingTest:^BOOL(id obj, BOOL *stop) { 
     CLCircularRegion *regionForTest = (CLCircularRegion *)obj; 
     if (![regionIdentifiers containsObject:regionForTest.identifier]) { 
      return YES; 
     } else { 
      return NO; 
     } 
    }]; 

    for (CLCircularRegion *geofence in unMonitoredRegions) { 
     [self.locationManager startMonitoringForRegion:geofence]; 
     // We'll check if we are in the new region as it was not previously monitored 
     if([geofence containsCoordinate:[position coordinate]]){ 
      [self locationManager:manager didEnterRegion:geofence]; 
     } 
    } 
} 
+0

感謝@DeanDavids for循環寄存器(3次迭代)三個(也是唯一的三個)不同的區域。否則,回調中的「monitoredRegions」日誌將不會顯示這三個區域。對? 即使在第一次運行(重置模擬器)時也會發生錯誤的回調。 我只在第一次應用程序啓動時使用'didEnterRegion'。當我已經在該地區時,我沒有收到一個didEnter-Callback。 – cakl

+0

爲什麼我不能使用'self.locationManager.monitoredRegions containsObject:geofence'?我認爲containsObject正在做一個「深層次」 - 相等測試(而不僅僅是引用)和'self.geofences'只能在應用程序重新啓動後才能改變(我保證!)。 – cakl

+0

來自CLLocationManager類的引用 - 「這個集合中的對象可能不一定是你在註冊時指定的對象,只有區域數據本身由系統維護,因此唯一識別註冊區域的唯一方法是使用其標識符屬性「。 –