在后台模式下调用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
可能会有帮助