3

我正在开发一个 iOS 应用程序,该应用程序专注于建筑物(校园)中的行人。我已经开发了一个足够好的(我相信)用户的位置更新,但是,我希望比我更专业的人给我一些提示,关于准确位置的建议,电池问题等。此外,是否可以停止位置更新和n秒后重新启动?是我为了节省能源而做的一个想法。就目前而言,应用程序正在检测当前位置,但是,蓝点(用户)仍在四处移动,我不喜欢这样。有什么可以做的吗?

下面是我的 didUpdateToLocation 方法:

应用程序正在从文件中读取建筑物的信息(存储在设备上)

    - (void)viewDidLoad{

        [super viewDidLoad];

        if ([self checkForInternet]) {

            _locationManager = [[CLLocationManager alloc] init];
            _locationManager.delegate = self;
            _locationManager.distanceFilter = 10.0f;
            _locationManager.desiredAccuracy = 20.0f;

            [_locationManager startUpdatingLocation];

        }
    }

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

        if (newLocation.horizontalAccuracy > manager.desiredAccuracy) return;

        [self.mapView removeAnnotations:listOfAnn];
        [listOfAnn removeAllObjects];
        if ([manager locationServicesEnabled]) {

            for (NSString* row in rows){
                NSArray* cells = [row componentsSeparatedByString:@"\t"];

                CLLocationCoordinate2D newCoord;
                newCoord.latitude = [[cells objectAtIndex:5]floatValue];
                newCoord.longitude = [[cells objectAtIndex:6]floatValue];

                CLLocation *locB = [[CLLocation alloc] initWithLatitude:newLocation.coordinate.latitude longitude:newLocation.coordinate.longitude];
                CLLocation *centerLoc = [[CLLocation alloc] initWithLatitude:CAMPUS_LATITUDE longitude:CAMPUS_LONGITUDE];
                CLLocationDistance borders = [locB distanceFromLocation:centerLoc];

                if ((int)round(borders) > 500) {

                    BuildingViewController *newBuilding = [[BuildingViewController alloc] initBuildingWithName:[cells objectAtIndex:2]                                                                                                       coordinates:newCoord shortDescription:[cells objectAtIndex:4] image:(NSString*)[cells objectAtIndex:3]                                                                                                               inDistance: borders];

                    if ([[prefs stringForKey:newBuilding.title] isEqualToString:[prefs stringForKey:@"userName"]]) {
                        [newBuilding retrieveID];
                        [listOfAnn addObject:newBuilding];
                    }

                } else{

                    CLLocation *locA = [[CLLocation alloc] initWithLatitude:newCoord.latitude longitude:newCoord.longitude];

                    CLLocationDistance distance = [locA distanceFromLocation:locB];

                    BuildingViewController *newBuilding = [[BuildingViewController alloc] initBuildingWithName:[cells objectAtIndex:2]
                                                        coordinates:newCoord shortDescription:[cells objectAtIndex:4] image:(NSString*)[cells objectAtIndex:3]
                                                        inDistance: distance];

                    if ((int)round(distance) < 100 ||
                       [[prefs stringForKey:newBuilding.title] isEqualToString:[prefs stringForKey:@"userName"]]){
                          [newBuilding retrieveID];
                          [listOfAnn addObject:newBuilding];
                    }

                }

           }
           [self.mapView addAnnotations:listOfAnn];
      }
 }
4

1 回答 1

3

Γεια σου Παναγιώτη。

您应该阅读有关位置服务的官方文档

这是一个很好的指南,应该涵盖所有内容。我将为您做一个快速回顾,并向您解释每种可用方法的优缺点,因为我已经为我们的应用程序与核心位置服务进行了广泛的合作:

有 3 种不同的方法可以在 iOS 中获取用户位置。

  1. 普通 GPS 位置监控器(优点:非常准确且更新迅速,缺点:电池电量消耗太快)
  2. 重要的定位服务(优点:非常省电,可以从后台启动应用程序,即使在进入区域后终止,无需后台位置监控任务和许可,缺点:在确定位置和接收位置更新方面非常不准确变化)
  3. 区域监控(优点:非常省电,可以从后台启动应用程序,即使在输入区域后终止,无需后台位置监控任务和权限缺点:获取有关输入区域的通知不准确,最多 20 个区域可以由应用程序监控)

因此,根据您想要的准确性,您必须选择服务。当然,如果您采用 GPS 方式,就像您在代码中使用的那样,您应该始终在获得更新后关闭位置更新并再次请求位置,仅在一段时间后,否则您的应用程序将耗尽用户的电池。

当然,您可以随时重新启动用户的位置更新。如果您需要在应用程序的许多视图控制器中更新位置,我建议您为位置管理器创建一个单例类!

至于 GPS 监控,在您的 CoreLocation 委托方法 didUpdateToLocation 中,执行以下操作:

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

    NSDate* eventDate = newLocation.timestamp;
    NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
    //prevent Location caching... (only accepts cached data 1 minute old)
    if( abs(howRecent) < 60.0) {
        [self.locationManager stopUpdatingLocation];
        //capture the location... (this is your code)

        //update location after 90 seconds again
        [self performSelector:@selector(startUpdatingLocation) withObject:nil afterDelay:90];
     }

}

并再次更新位置:

- (void)startUpdatingLocation {
    if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusAuthorized || [CLLocationManager authorizationStatus]==kCLAuthorizationStatusNotDetermined) {
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        [locationManager startUpdatingLocation];
    }
}

并确保我们取消了 performSelector 以防用户更改 viewController,将其添加到:

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];    
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
}
于 2012-12-12T19:59:39.763 回答