我需要在每分钟调用一个Web服务,并在app处于后台状态时解析数据。
由于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];
}
有没有办法以更少的电池消耗来实现这一点。
我提到this link 我没有在这里找到更好的解决方案。
答案 0 :(得分:0)
<强> 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 = [application beginBackgroundTaskWithExpirationHandler ...,它要求额外的时间在后台运行清理任务。
第二个是以dispatch_async开头的委托方法的最终代码块。它基本上是通过调用[application backgroundTimeRemaining]
检查是否还有时间来运行操作。在这个例子中,我想要运行一次后台服务,但是,你可以在每次迭代时使用backgroundTimeRemaining的循环检查。
行[[BackgroundCleanupService getInstance] run]将调用我们的单例服务类,我们现在将构建它。
随着app delegate准备好触发我们的后台任务,我们现在需要一个与Web服务器通信的服务类。在下面的示例中,我将发布一个虚构的会话密钥并解析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
可以帮助