OStack程序员社区-中国程序员成长平台

标题: ios - 使用位置管理器 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-13 03:38
标题: ios - 使用位置管理器

我想做以下事情

这是我的做法:

在 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)locationManagerCLLocationManager *)manager didUpdateToLocationCLLocation *)newLocation fromLocationCLLocation *)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)applicationDidEnterBackgroundUIApplication *)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)applicationDidBecomeActiveUIApplication *)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)applicationWillTerminateUIApplication *)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)locationManagerCLLocationManager *)manager didUpdateToLocationCLLocation *)newLocation fromLocationCLLocation *)oldLocation {

    self.myLocation = newLocation;

    [self uploadLocationCoordinates];


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

        [self.locationManager stopUpdatingLocation];
    }

    //_horizontalAccuracy.text = currentHorizontalAccuracy;
}

我这样做是否正确?当有人关闭应用时,位置服务似乎仍然处于开启状态。



Best Answer-推荐答案


从设计的角度来看,我发现最好将位置管理器封装在单例类中(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 和其他类可以随时请求这些数据。或者,您可以使用委托(delegate)模式在单例中存储对每个位置感知类(例如 View Controller 、应用程序委托(delegate))的引用,并在收到诸如 locationManager:didUpdateToLocation 之类的回调时向这些类广播.

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

关于ios - 使用位置管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18337227/






欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) Powered by Discuz! X3.4