在后台模式下调用Web服务 – iOS

我需要每分钟调用一次Web服务,并在应用程序处于后台状态时parsing数据。

由于APP使用位置服务,我已启用后台模式更新位置。

我试图通过使用定时器后台任务来调用位置更新,但它不工作。

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

有没有什么办法可以用更less的电池消耗来实现这一点。

我提到这个链接,我没有得到哪个解决scheme在这里更好。

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; }); } 

在上面的实现中有几个关键线:

首先是行bgTask = [应用程序beginBackgroundTaskWithExpirationHandler …,它要求额外的时间在后台运行清理任务。

第二个是以dispatch_async开头的委托方法的最终代码块。 这基本上是检查是否有时间通过​​调用[application backgroundTimeRemaining]运行一个操作。 在这个例子中,我正在寻找一次运行后台服务,但是也可以在每次迭代时使用循环检查backgroundTimeRemaining。

该行[[BackgroundCleanupService getInstance] run]将是对我们现在正在构build的单例服务类的调用。

随着应用程序委托准备好触发我们的后台任务,我们现在需要一个服务类,将与Web服务器进行通信。 在下面的例子中,我将发布一个虚构的会话密钥并parsing一个JSON编码的响应。 另外,我使用两个有用的库来完成请求并反序列化返回的JSON,特别是JSONKit和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 

可能会有帮助