2

我想做以下

  • 在 APP Delegate 文件中在后台跟踪位置
  • 在 View Controller 中跟踪某人的位置。

这是我的做法:

在 APPDelegate 中:

在 applicationDidFinishLaunching 中:

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

在视图控制器中:

- (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

从设计的角度来看,我发现最好将位置管理器包装在单例类中(示例)。你在这里做什么:

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];
}

...非常混乱:您可能正在复制位置管理器对象或只是引用它(并且代码不清楚那里发生的事情而没有看到头文件)并且您通常不应该切换位置管理器的委托大约。

使用单例类将为您提供一个处理与位置相关的事情的单一位置,并且您的视图控制器和其他类可以随时请求这些数据。或者,您可以使用委托模式在单例中存储对每个位置感知类(例如视图控制器、应用程序委托)的引用,并在收到回调(例如locationManager:didUpdateToLocation.

我希望这会有所帮助 - 查看我添加的链接以了解我的意思:单例模式是在这里使用的完美方式,因为您只希望在任何时候都使用一个位置数据源。

于 2013-08-20T14:20:41.957 回答
1

您的代码看起来不错,但如果您已注册位置更改,它将在后台保持活动状态。如果您想暂停位置更改,有几种方法,我通常在我的AppDelegate.

- (void)applicationDidEnterBackground:(UIApplication *)application
{
   NSLog(@"Application entering background");
   CLLocationManager *locMan = [[CLLocationManager alloc] init];
   [locMan stopMonitoringSignificantLocationChanges];
   [locMan stopUpdatingLocation];
}


- (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.
    CLLocationManager *locMan = [[CLLocationManager alloc] init];
    [locMan startMonitoringSignificantLocationChanges];
}
于 2013-08-20T14:48:35.550 回答
0

如果您通过按 iphone 中的中心按钮关闭应用程序,则调用此方法

- (void)applicationWillEnterForeground:(UIApplication *)application
于 2013-08-20T14:23:17.237 回答