Calling a web service in the background - iOS

I need to call a web service every minute and analyze the data when the application is in the background.

Because APP uses the location service, I have turned on background mode for the update location.

I tried calling a location update using a timer background job, but it doesn't work.

- (void)applicationDidEnterBackground:(UIApplication *)application { self.bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ NSLog(@"ending background task"); [[UIApplication sharedApplication] endBackgroundTask:self.bgTask]; self.bgTask = UIBackgroundTaskInvalid; }]; self.timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self.locationManager selector:@selector(startUpdatingLocation) userInfo:nil repeats:YES]; } 

Is there any way to realize this with less battery consumption.

I named this link. I don’t understand which solution is better here.

+1
source share
1 answer

Appdelegate.h

 #import <UIKit/UIKit.h> @interface AppDelegate : NSObject { // Instance member of our background task process UIBackgroundTaskIdentifier bgTask; } @end 

AppDelegate.m

 - (void)applicationDidEnterBackground:(UIApplication *)application { NSLog(@"Application entered background state."); // bgTask is instance variable NSAssert(self->bgTask == UIBackgroundTaskInvalid, nil); bgTask = [application beginBackgroundTaskWithExpirationHandler: ^{ dispatch_async(dispatch_get_main_queue(), ^{ [application endBackgroundTask:self->bgTask]; self->bgTask = UIBackgroundTaskInvalid; }); }]; dispatch_async(dispatch_get_main_queue(), ^{ if ([application backgroundTimeRemaining] > 1.0) { // Start background service synchronously [[BackgroundCleanupService getInstance] run]; } [application endBackgroundTask:self->bgTask]; self->bgTask = UIBackgroundTaskInvalid; }); } 

There are several key lines in the above implementation:

First line: bgTask = [application beginBackgroundTaskWithExpirationHandler ..., which requests additional time to run cleanup tasks in the background.

The second is the final code block of the delegate method, starting with dispatch_async. It basically checks if there is time left to complete the operation through a call to [application backgroundTimeRemaining] . In this example, I want to start the background service once, but as an alternative, you can use a loop check on backgroundTimeRemaining at each iteration.

The string [[BackgroundCleanupService getInstance] run] will be the call to our singleton service class, which we will now create.

When the application delegate is ready to launch our background task, now we need a service class that will communicate with the web server. In the following example, I go to a dummy session key and parse the JSON encoded response. In addition, I use two useful libraries to make a request and deserialize the returned JSON, in particular JSONKit and ASIHttpRequest.

BackgroundCleanupService.h

 #import <Foundation/Foundation.h> @interface BackgroundCleanupService : NSObject + (BackgroundCleanupService *)getInstance; - (void)run; @end 

BackgroundCleanupService.m

 #import "BackgroundCleanupService.h" #import "JSONKit.h" #import "ASIHTTPRequest.h" @implementation BackgroundCleanupService /* * The singleton instance. To get an instance, use * the getInstance function. */ static BackgroundCleanupService *instance = NULL; /** * Singleton instance. */ +(BackgroundCleanupService *)getInstance { @synchronized(self) { if (instance == NULL) { instance = [[self alloc] init]; } } return instance; } - (void)run { NSURL* URL = [NSURL URLWithString:[NSString stringWithFormat:@"http://www.example.com/user/%@/endsession", @"SESSIONKEY"]]; __block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:URL]; [request setTimeOutSeconds:20]; // 20 second timeout // Handle request response [request setCompletionBlock:^{ NSDictionary *responseDictionary = [[request responseData] objectFromJSONData]; // Assume service succeeded if JSON key "success" returned if([responseDictionary objectForKey:@"success"]) { NSLog(@"Session ended"); } else { NSLog(@"Error ending session"); } }]; // Handle request failure [request setFailedBlock:^{ NSError *error = [request error]; NSLog(@"Service error: %@", error.localizedDescription); }]; // Start the request synchronously since the background service // is already running on a background thread [request startSynchronous]; } @end 

may I help

0
source

Source: https://habr.com/ru/post/1258682/


All Articles