User's location and battery's consumption

允我心安 提交于 2019-12-22 09:29:15

问题


I am working on an iOS app that's focuses on pedestrians in a block of buildings (campus). I have developed a good enough (I believe) user's location update but, I would like anyone more expert than me to give me some tips, advices on accurate location, battery's issues etc. In addition, is it possible to stop the location update and start it again after n seconds? Is a thought that I did in order to save energy. As it is at the moment, app is detecting current location, but, blue dot (user) is still moving around and I don't like that. There is something that can be done?

Below is my didUpdateToLocation method:

App is reading buildings' info from a file (stored on device)

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

回答1:


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

You should read the official documentation about location services

It is an excellent guide and should get cover everything. I will do a quick recap for you and explain you the pros and cons for each available method, as I have worked extensively with Core Location services for our App:

There are 3 different ways to get the users location in iOS.

  1. Normal GPS location monitorins (pros: very acurate and updates quickly, cons: drains the battery way too fast)
  2. Significant Location services (pros: very battery efficient, can start the app from background, even when terminated if a region is entered, without requiring a background location monitoring task and permission, cons: very inaccurate in both determining the location and receiveing updates of location changes)
  3. Region Monitoring (pros: very battery efficient, can start the app from background, even when terminated if a region is entered, without requiring a background location monitoring task and permission cons: inaccurate in getting notifications about the regions entered, max 20 regions can be monitored by app)

So depending on the accuracy you want, you have to select the service. Of course, if you are going the GPS way, like you use in your code, you should always turn off the location updating after you get an update and request the position again, only after a certain period of time, else your app will drain the user's battery.

And of course you can restart the user's location updates at anytime. If you require location updates in many view controllers in your app, I suggest you create a singleton class for the location manager!

As for GPS monitoring, in your CoreLocation delegate method, didUpdateToLocation, do the following:

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

}

and to update the location again:

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

and to be sure we have canceled our performSelector in case the user changes viewController, add this to:

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];    
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
}


来源:https://stackoverflow.com/questions/13847229/users-location-and-batterys-consumption

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!