2

私は次のことをしたい

  • APPデリゲートファイルでバックグラウンドで位置を追跡
  • View Controller で誰かの位置を追跡します。

これが私がやっている方法です:

APPDelegate で:

アプリケーションでDidFinishLaunching:

if ([CLLocationManager locationServicesEnabled])
{
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    _startLocation = nil;
    self.locationManager.desiredAccuracy=kCLLocationAccuracyBest;
    self.locationManager.distanceFilter=500;
}


- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    // Set Property
    self.myLocation = newLocation;

    BOOL isInBackground = NO;
    if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground)
    {
        isInBackground = YES;
    }

    // Handle location updates as normal, code omitted for brevity.
    // The omitted code should determine whether to reject the location update for being too
    // old, too close to the previous one, too inaccurate and so forth according to your own
    // application design.

    if (isInBackground)
    {
        [self sendBackgroundLocationToServer:newLocation];
    }

    if(newLocation.horizontalAccuracy <= 100.0f)
    {
        [self.locationManager stopMonitoringSignificantLocationChanges];
    }
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [self.locationManager stopUpdatingLocation];
    [self.locationManager startMonitoringSignificantLocationChanges];

    // 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.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    if(self.locationManager == nil)
    {
        self.locationManager = [[CLLocationManager alloc] init];
    }
    [self.locationManager stopMonitoringSignificantLocationChanges];
    // 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.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    self.locationManager = nil;
    [self.locationManager stopUpdatingLocation];
    [self.locationManager stopMonitoringSignificantLocationChanges];
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

ViewController で:

- (void) startLocationChanges {

    if ([CLLocationManager locationServicesEnabled])
    {
        PLAppDelegate *appDelegate = (PLAppDelegate *) [[UIApplication sharedApplication] delegate];

        if(appDelegate.locationManager == nil)
        {
            self.locationManager = [[CLLocationManager alloc] init];
        }
        else {
            self.locationManager = appDelegate.locationManager;
        }

        self.locationManager.delegate = self;
        [self.locationManager startUpdatingLocation];
    }
}


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

    self.myLocation = newLocation;

    [self uploadLocationCoordinates];


    if(newLocation.horizontalAccuracy <= 100.0f)
    {
        NSLog(@"stop updating location");

        [self.locationManager stopUpdatingLocation];
    }

    //_horizontalAccuracy.text = currentHorizontalAccuracy;
}

私はこれを正しい方法でやっていますか?誰かがアプリを閉じても、位置情報サービスはオンのままのようです。

4

3 に答える 3

2

設計の観点からは、ロケーション マネージャーをシングルトン クラス ( example ) にラップしておくのが最善だと思います。ここで行っていること:

if ([CLLocationManager locationServicesEnabled])
{
    PLAppDelegate *appDelegate = (PLAppDelegate *) [[UIApplication sharedApplication] delegate];

    if(appDelegate.locationManager == nil)
    {
        self.locationManager = [[CLLocationManager alloc] init];
    }
    else {
        self.locationManager = appDelegate.locationManager;
    }

    self.locationManager.delegate = self;
    [self.locationManager startUpdatingLocation];
}

...非常に面倒です。ロケーションマネージャーオブジェクトをコピーするか、参照するだけである可能性があり (ヘッダーファイルを見ないとそこで何が起こっているのかコードは明確ではありません)、通常、ロケーションマネージャーのデリゲートを切り替えるべきではありませんその周り。

シングルトン クラスを使用すると、場所に関連するものを処理する単一の場所が得られ、View Controller や他のクラスはいつでもこのデータを要求できます。または、デリゲート パターンを使用して、すべての位置認識クラス (ビュー コントローラー、アプリ デリゲートなど) への参照をシングルトンに格納し、locationManager:didUpdateToLocation.

それが役に立てば幸いです - 私が追加したリンクを見て、私が何を意味するかを確認してください: シングルトン パターンは、一度に 1 つの位置データ ソースのみを使用する必要があるため、ここで使用するのに最適です。

于 2013-08-20T14:20:41.957 に答える