简体   繁体   中英

iOS Background app : best way to run app

I need to create an app that retrieves iOS radio informations (rssi, bearer, ...) in background mode ; the app will be available on app store and thereby is under App Store guidelines. The app should rationally keep the phone's battery.

I currently use BackgroundFetch and GPS together, it works pretty good but when iOS has not enough memory the app is killed by OS.

I also looked Google app (Google Now) that uses GPS and keep iPhone's battery life, but i don't know how they do that.

Thanks

  1. Make sure "Background Fetch" and "Location Updates" are enabled in your Plist.
  2. When your app is in the background, user startMonitoringSignificantLocationChanges instead of startUpdatingLocation. Here's some info from the documentation.

"[startUpdatingLocation] typically require the location-tracking hardware to be enabled for longer periods of time, which can result in higher power usage." "[With startMonitoringSignificantLocationChanges] Apps can expect a notification as soon as the device moves 500 meters or more from its previous notification. It should not expect notifications more frequently than once every five minutes."

I'd go through the documentation here so you can grab a better understanding ( https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CLLocationManager_Class/CLLocationManager/CLLocationManager.html#//apple_ref/occ/instm/CLLocationManager/startMonitoringSignificantLocationChanges )

As you can probably see, using startMonitoringSignificantLocationChanges significantly increases battery life. Here's how I implemented it in my AppDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    ...
    [self.locationManager startMonitoringSignificantLocationChanges];
    ...
}

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

- (void)applicationWillEnterForeground:(UIApplication *)application {
    ...
    [self.locationManager stopMonitoringSignificantLocationChanges];
    [self.locationManager startUpdatingLocation];
    ...
}

-(CLLocationManager *)locationManager{

    if(!_locationManager){
        _locationManager = [[CLLocationManager alloc]init];
        _locationManager.delegate = self;
        _locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
        _locationManager.distanceFilter = 5;
    }
    return _locationManager;
}

This way I ensure that I only use the power-draining "startUpdatingLocation" method when the app is active and the power-saving "stopMonitoringSignificantLocationChanges" when inactive.

I made on test on your code above.

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{
    //NSLog(@"Location: %f, %f", newLocation.coordinates.longtitude, newLocation.coordinates.latitude);
    longitude = newLocation.coordinate.longitude;
    latitude = newLocation.coordinate.latitude;
    gpsTimestamp = [newLocation.timestamp timeIntervalSince1970];
    NSLog(@"Changed ! ");
    if (!timer &&  ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground)) {
        NSLog(@"Starting task");
        timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(createBgIndicator) userInfo:nil repeats:YES];

    }

}

In this case, the timer will start only while I'm moving and is executed 5 times (10s). I would like to get the timer running all the time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM