2012-06-11 6 views
4

사용자 위치를 항상 추적해야하지만 배터리를 소모하지 않아야합니다. 앱 종료 후 업데이트를 가져 오는 유일한 방법은 startMonitoringSignificantLocationChanges를 사용하는 것입니다.앱 종료 후 위치 업데이트 수신

startMonitoringSignificantLocationChanges에 애플의 위치 인식 프로그래밍 가이드에서

:이 서비스를 시작하고 응용 프로그램이 연속적으로 종료 된 경우 새 이벤트가 도착하면

시스템이 자동으로 에 배경 응용 프로그램을 다시 실행합니다. 이 경우 응용 프로그램에 전달 된 옵션 사전 : didFinishLaunchingWithOptions : 응용 프로그램 대리인의 메서드는 UIApplicationLaunchOptionsLocationKey라는 키가있어 위치 이벤트로 인해 응용 프로그램이 시작되었음을 나타냅니다. 다시 실행하면 위치 관리자 개체를 구성하고이 메서드를 호출하여 위치 이벤트를 계속 받아 와야합니다. 위치 서비스를 다시 시작하면 현재 이벤트가 대리인에게 즉시 전달됩니다. 또한 위치 서비스를 시작하기 전에 관리자 개체의 위치 속성에 가장 최근 위치 개체 인 도 채워집니다. 누군가가 (예를 들어 줄) 난에 트링있어 다음 코드에서

를 사용해야하는 방법 코드에서 보여 수 있다면

내가 기쁠 : - AppDelegate에에서 위치 관리자를 시작 이 모니터는 중요한 모니터 변경 사항을 업데이트하고 시작 날짜를 표시합니다. - didUpdateToLocation 내가 배경에 있는지 그리고 중요한 모니터 위치 업데이트로 인해 시작했는지 알기 위해 UIApplicationLaunchOptionsLocationKey가 있는지 확인하면 didFinishLaunchingWithOptions에서 을 stopupdating한다고합니다. - 그렇다면 startMonitoringSignificantLocationChanges를 다시 호출합니다 (이유는 확실하지 않음 ...) 및 startupdating 메서드를 호출하기위한 UIBackgeoundTaskIdentifier를 시작합니다.

LocationController.m : 
+ (LocationController*)sharedInstance { 
    @synchronized(self) { 
     if (sharedCLDelegate == nil) { 
      [[self alloc] init]; 
     } 
    } 
    return sharedCLDelegate; 
} 

- (id)init 
{ 
    self = [super init]; 
    if (self != nil) { 
     self.locationManager = [[[CLLocationManager alloc] init] autorelease]; 
     self.locationManager.delegate = self; 
     self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters; 
     [self.locationManager startUpdatingLocation]; 
     [self.locationManager startMonitoringSignificantLocationChanges]; 

    } 
    return self; 
} 
- (void) startMonitoringSignificantLocationChanges 
{ 
    [self.locationManager startMonitoringSignificantLocationChanges]; 
} 
- (void) stopMonitoringSignificantLocationChanges 
{ 
    [self.locationManager stopMonitoringSignificantLocationChanges]; 
} 
-(void) start{ 
    [self.locationManager startUpdatingLocation]; 
} 
- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
      fromLocation:(CLLocation *)oldLocation{ 
    if (abs([newLocation.timestamp timeIntervalSinceDate: [NSDate date]]) < 30) { 
     self.lastLocation = newLocation; 
     [self updateLocation]; //sending location to server 
     [self.locationManager stopUpdatingLocation]; 
    } 
} 
- (void)locationManager:(CLLocationManager*)manager 
     didFailWithError:(NSError*)error{ 
    [self.locationManager stopUpdatingLocation]; 
} 

AppDelegate.h : 

@interface AppDelegate : NSObject <UIApplicationDelegate> { 
    UIBackgroundTaskIdentifier bgTask; 
} 

AppDelegate.m : 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
     id locationValue = [launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]; 
     if (locationValue) { 
      [[LocationController sharedInstance] startMonitoringSignificantLocationChanges]; 
      UIApplication *app = [UIApplication sharedApplication]; 
      bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ 
       [app endBackgroundTask:bgTask]; 
       bgTask = UIBackgroundTaskInvalid; 
      }]; 
      [[LocationController sharedInstance] start]; //startupdating 
      return YES; 
     } 
    else { 
      [[LocationController sharedInstance] init]; 
    } 
} 
-(void) applicationDidEnterBackground:(UIApplication *) application 
{ 
    NSLog(@"entered background Mode"); 
} 

-(void) applicationDidBecomeActive:(UIApplication *) application 
{ 
    NSLog(@"application Did Become Active"); 
} 

감사합니다.

답변

11

클래스를 사용하면 이것이 가능합니다.

AppDelegate.m에서 앱이 포 그라운드 나 배경에있을 때 전경/배경에서 실행되도록 CLLocationManager를 이동합니다. 앱이 배경에있을 때 CLLocationManager이 백그라운드로 이동되지 않은 경우에는 위치 업데이트가 CLLocationManager의 콜백로 전송되지 않기 때문에 나는이 일을 해요 이유는

- (void)applicationDidEnterBackground:(UIApplication *) application { 
    [[LocationController sharedInstance] stop]; 
    [[LocationController sharedInstance] startMonitoringSignificantLocationChanges]; 
    NSLog(@"entered background Mode"); 
} 

- (void)applicationDidBecomeActive:(UIApplication *) application { 
    [[LocationController sharedInstance] stopMonitoringSignificantLocationChanges]; 
    [[LocationController sharedInstance] start]; 
    NSLog(@"application Did Become Active"); 
} 

그래서 앱이 다음에 이동 말할 수 배경과 잠시 후 iOS가 너무 많은 메모리를 사용하여 앱을 종료한다고 결정합니다.

몇 분 후 iOS가 위치 업데이트를 수신하고 위치 서비스로 인해 다시 생성되었음을 알리는 앱을 다시 보냅니다. 그런 다음 백그라운드 위치 서비스를 다시 시작해야합니다. 앱에서 수행해야 할 유일한 기회이기 때문입니다.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) { 
     [[LocationController sharedInstance] startMonitoringSignificantLocationChanges]; 
    } 
    return YES; 
} 

아, 그리고 마지막으로 변화, 당신의 locationManager:didUpdateToLocation:fromLocation: 방법 당신은 당신이 더 이상 업데이트가 나오지 그렇게 할 때와 같이, 위치 서비스를 중지하는 이유를 모르겠어요. 그냥 실행 상태로두면 위치 변경이 발생할 때마다 서버로 보낼 수 있습니다.

- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
      fromLocation:(CLLocation *)oldLocation { 

    if (abs([newLocation.timestamp timeIntervalSinceDate: [NSDate date]]) < 30) { 
     self.lastLocation = newLocation; 
     [self updateLocation]; //sending location to server 

} 
+1

이 문서는 Apple docs에 문서화되어 있습니다. – hariszaman

관련 문제