2012-04-06 3 views
2

사용자가 퇴근 할 때 알림을 발생시키는 앱을 구성했습니다. 그래서 반경 25의 지역 모니터링을 구현했습니다. 내가 겪고있는 문제는 (iPhone 시뮬레이터 5.0) 시뮬레이션 할 때, 사용자 정의 위치 (집)를 설정하여 지역 경계를 설정하는 것입니다. 지역 경계 바깥, 즉 거리 끝의 다른 맞춤 위치를 입력하십시오. 하지만 앱은 해당 지역의 출입국을 등록하지 않습니다. 집 위치와 지역을 설정 한 다음에 만 Apple 본사로 변경하여 등록하고 알림을 시작합니다. 백그라운드 모드에서 앱이 중요한 위치로 변경됩니다. 그러나 전경이나 배경에서 같은 문제가 있습니다. "Reminder"앱과 마찬가지로 내가 뭘 찾고 있는지는 앱이 거리 경계를 벗어나거나 경계를 벗어난 직후에 알림을 시작하기위한 것입니다. 어떻게하면 더 정확하게 만들 수 있습니까?지역 경계 교차 정확도 (시뮬레이션) 개선 방법 (지오 펜싱)

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    // Create empty array to add region events to. 
    updateEvents = [[NSMutableArray alloc] initWithCapacity:0]; 

    // Create location manager with filters set for battery efficiency. 
    locationManager = [[CLLocationManager alloc] init]; 
    locationManager.delegate = self; 
    locationManager.distanceFilter = kCLLocationAccuracyBest; //could try KLDistanceFilterNone; 
    locationManager.desiredAccuracy = kCLLocationAccuracyBest; 

    // Start updating location changes. 
      [locationManager startUpdatingLocation]; 
} 

- (void)viewDidAppear:(BOOL)animated { 
    // Get all regions being monitored for this application. 
    NSArray *regions = [[locationManager monitoredRegions] allObjects]; 

    // Iterate through the regions and add annotations to the map for each of them. 
      for (int i = 0; i < [regions count]; i++) { 
        CLRegion *region = [regions objectAtIndex:i]; 
    RegionAnnotation *annotation = [[RegionAnnotation alloc] initWithCLRegion:region]; 
        [regionsMapView addAnnotation:annotation]; 
        [annotation release]; 
      } 
} 

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


- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { 
    NSLog(@"didUpdateToLocation %@ from %@", newLocation, oldLocation); 

    // Work around a bug in MapKit where user location is not initially zoomed to. 
      if (oldLocation == nil) { 
    // Zoom to the current user location. 
        MKCoordinateRegion userLocation = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 100.0, 100.0); 
        [regionsMapView setRegion:userLocation animated:YES]; 
      } 
} 


- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region { 
    NSString *event = [NSString stringWithFormat:@"didEnterRegion %@ at %@", region.identifier, [NSDate date]]; 

      [self updateWithEvent:event]; 
} 


- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region { 
    NSString *event = [NSString stringWithFormat:@"didExitRegion %@ at %@", region.identifier, [NSDate date]]; 
      [self updateWithEvent:event]; 
//implement local notification: 
    UIApplication *app    = [UIApplication sharedApplication]; 
    UILocalNotification *notification = [[UILocalNotification alloc] init]; 
    [[UIApplication sharedApplication] cancelAllLocalNotifications]; 

    if (notification == nil) 
     return; 
    notification.alertBody = [NSString stringWithFormat:@"Did You Lock Your House?"]; 
    notification.alertAction = @"Lock House"; 
    notification.soundName = UILocalNotificationDefaultSoundName; 
    notification.applicationIconBadgeNumber = 1; 
    [app presentLocalNotificationNow:notification]; 

    [notification release]; 
// ends here 

//following is an alert for the case of exiting boundary whilst app is in foreground 
    UIAlertView *alr=[[UIAlertView alloc] initWithTitle:@"Reminder didExitRegion" message:region.identifier delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Ok",nil]; 

    [alr show]; 

    [alr release]; 
    //ends here 
} 

- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error { 
    NSString *event = [NSString stringWithFormat:@"monitoringDidFailForRegion %@: %@", region.identifier, error]; 

      [self updateWithEvent:event]; 
} 

- (IBAction)addRegion { 
    if ([CLLocationManager regionMonitoringAvailable]) { 
    // Create a new region based on the center of the map view. 
    CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(regionsMapView.centerCoordinate.latitude, regionsMapView.centerCoordinate.longitude); 
    CLRegion *newRegion = [[CLRegion alloc] initCircularRegionWithCenter:coord 
                                               radius:25.0 
                                            identifier:[NSString stringWithFormat:@"%f, %f", regionsMapView.centerCoordinate.latitude, regionsMapView.centerCoordinate.longitude]]; 

    // Create an annotation to show where the region is located on the map. 
        RegionAnnotation *myRegionAnnotation = [[RegionAnnotation alloc] initWithCLRegion:newRegion]; 
        myRegionAnnotation.coordinate = newRegion.center; 
        myRegionAnnotation.radius = newRegion.radius; 

        [regionsMapView addAnnotation:myRegionAnnotation]; 

        [myRegionAnnotation release]; 

    // Start monitoring the newly created region. 
        [locationManager startMonitoringForRegion:newRegion desiredAccuracy:kCLLocationAccuracyBest]; 

        [newRegion release]; 
      } 
    else { 
    NSLog(@"Region monitoring is not available."); 
      } 
} 

이 작품은 "지역"템플릿에서 파생되었습니다

여기 내 viewcontroller.m 파일의 일부이다.

+0

Ive는 내 iPhone에 앱을 배포하고 15-25m 사이의 지역을 설정하고 지역 외 50m를 걸어갔습니다. 어떤 추천? –

답변

1

정확도는 얻을 수있는 최상의 정확도입니다. 지역 일치는 셀 타워 삼각 측량 만 사용하므로 조밀 한 지역에서는 50-100m에서 트리거 할 수 있지만 스파 스 지역에서는 100 초가 걸릴 수 있습니다.

세밀한 세부 사항을 원하면 직선 위치 서비스를 사용해야합니다. 하지만 그건 배터리를 먹을거야. 그래서 독을 골라 라.

6

iOS 시뮬레이터는 exit/enter로 지오 펜스 업데이트에 악명이 높습니다. 이것을 확신 할 수있는 한 가지 방법은 앱의 지오 펜스를 현재 위치로 설정하는 것입니다. 그런 다음 iOS 시뮬레이터의 디버그 메뉴에서 위치를 누른 다음 고속도로 드라이브를 누릅니다. 귀하의 장치는 이제 고속도로 주행을 시뮬레이션 할 것이며 시뮬레이터가 내 것과 같은 경우 didExitRegion 이벤트를 등록하지 않습니다.

왜? 지역은 대부분 Wi-Fi, 셀 타워 및 위치를 요청하는 전화의 다른 애플리케이션을 사용하는 Apple의 숨겨진 알고리즘에 의해 결정됩니다. 시뮬레이터로 보는 것은 Wi-Fi 나 셀 타워를 사용하지 않습니다. 지역 모니터링은 거의 불가능합니다.

나머지 코드가 영역 종료 후에 작동하는지 테스트하려면 locationManager : didExitRegion : 메소드를 수동으로 실행하는 버튼이나 다른 것을 만들 수 있습니다. 또한 장치를 연결하고 iPhone Simulator에서 iOS 장치로 변경하여 장치에서 프로젝트를 컴파일하는 것이 좋습니다. 그런 다음 장치를 분리하고 휴대 전화에서 앱을 실행하여 테스트 할 수 있습니다.