Problem while Working in background and Nstimer?

2019-02-19 18:25发布

问题:

Hi i have atask to develop the application with Nstimer and background process.

I have already implement background process with timer. And it is excuting good.but i have problem when i minimize application first time at that time it is not running the background process. after minimizing application 3 to 4 times. After that it is working smoothly. i also display the code of background task and timer as follow.

 - (void)applicationDidEnterBackground:(UIApplication *)application {

    UIApplication*    app = [UIApplication sharedApplication];
    NSLog(@"Application enter in background");
    [NSTimer scheduledTimerWithTimeInterval:2.0f
                                     target:self
                                   selector:@selector(updateCounter:)
                                   userInfo:nil
                                    repeats:YES]; 
}

And My updateCounter method is as given follow:

    - (void)updateCounter:(NSTimer*)timer {

    NSString *id = [[UIDevice currentDevice] uniqueIdentifier];
    NSLog(@"uniqueid:%@",id);

    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self; 
    locationManager.desiredAccuracy = kCLLocationAccuracyBest; 
    locationManager.distanceFilter = kCLDistanceFilterNone; 
    [locationManager startUpdatingLocation];

    CLLocation *location = [locationManager location];

    // Configure the new event with information from the location
    CLLocationCoordinate2D coordinate = [location coordinate];

    NSString *latitude = [NSString stringWithFormat:@"%f", coordinate.latitude]; 
    NSString *longitude = [NSString stringWithFormat:@"%f", coordinate.longitude];

    NSLog(@"dLatitude : %@", latitude); 
    NSLog(@"dLongitude : %@",longitude);

}

Is their any problem related code Please help me to solve it.

回答1:

First of all: Timers won't work as you expect when your app goes in background. (depends on the availability of the run loop and your timeout)

From what i gather from your code, seems you like to have location update when the app is running in background. For this, you should check the guidelines from here: https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html#//apple_ref/doc/uid/TP40007072-CH4-SW24

There are several ways to track the user’s location in the background, some of which do not actually involve running regularly in the background:

  • Applications can register for significant location changes. (Recommended) The significant-change location service offers a low-power way to receive location data and is highly recommended for applications that do not need high-precision location data. With this service, location updates are generated only when the user’s location changes significantly; thus, it is ideal for social applications or applications that provide the user with noncritical, location-relevant information. If the application is suspended when an update occurs, the system wakes it up in the background to handle the update. If the application starts this service and is then terminated, the system relaunches the application automatically when a new location becomes available. This service is available in iOS 4 and later, only on devices that contain a cellular radio.
  • Applications can continue to use the standard location services. Although not intended for running indefinitely in the background, the standard location services are available in all versions of iOS and provide the usual updates while the application is running, including while running in the background. However, updates stop as soon as the application is suspended or terminated, and new location updates do not cause the application to be woken up or relaunched. This type of service is appropriate when location data is used primarily when the application is in the foreground.
  • An application can declare itself as needing continuous background location updates. An application that needs regular location updates, both in the foreground and background, should add the UIBackgroundModes key to its Info.plist file and set the value of this key to an array containing the location string. This option is intended for applications that provide specific services, such as navigation services, that involve keeping the user informed of his or her location at all times. The presence of the key in the application’s Info.plist file tells the system that it should allow the application to run as needed in the background.

You are encouraged to use the significant location change service or use the standard services sparingly. Location services require the active use of an iOS device’s onboard radio hardware. Running this hardware continuously can consume a significant amount of power. If your application does not need to provide precise and continuous location information to the user, it is best to use those services that minimize power consumption. Chief among these low-power services is the significant location change service introduced in iOS 4. This service provides periodic location updates and can even wake up a background application, or relaunch a terminated application, to deliver them.

For applications that require more precise location data at regular intervals, such as navigation applications, you need to declare the application as a continuous background application. This option is available for applications that truly need it, but it is the least desirable option because it increases power usage considerably.



回答2:

NSTimer are paused when the app is in background state.

You'll have to start some background task to do what you want. But even with that, you will be limited to a certain amount of time after the app was put in background.

Real backgrounding behavior is only granted for location tracking, VoIP or Audio apps. Other apps must face limitations: once in background, you are given an amount of time to complete tasks you start with beginBackgroundTaskWithExpirationHandler: (backgroundTimeRemaining).

The whole thing is described in iOS Application Programming Guide, Executing Code in the Background, especially here.



回答3:

Check when your app goes to background mode and when it came into foregroud, calculate this difference and add the elapsed time in your timer so that you get an approx total time. I have also implemented the same and its working pretty well in my end.