我对这个话题很头疼。我正在开发一个需要定期轮询网络服务器以检查新数据的应用程序。根据返回的信息,我希望向用户推送本地通知。
我知道这种方法与 Apple 所描述的方法略有不同,在这种方法中,远程服务器进行工作,基于 APNS 推送远程通知。但是,有很多原因我不能考虑这种方法。其中之一就是用户认证机制。出于安全原因,远程服务器不能考虑用户凭据。我所能做的就是将登录和获取核心移动到客户端(iPhone)。
我注意到 Apple 为应用程序提供了唤醒并保持打开 Socket 连接(即 VoIP 应用程序)的机会。
于是,我开始以这种方式进行调查。在 plist 中添加了所需的信息,我可以在我的 appDelegate 中使用类似的东西“唤醒”我的应用程序:
[[UIApplication sharedApplication] setKeepAliveTimeout:1200 handler:^{
NSLog(@"startingKeepAliveTimeout");
[self contentViewLog:@"startingKeepAliveTimeout"];
MyPushOperation *op = [[MyPushOperation alloc] initWithNotificationFlag:0 andDataSource:nil];
[queue addOperation:op];
[op release];
}];
NSOperation,然后使用以下代码块启动后台任务:
#pragma mark SyncRequests
-(void) main {
NSLog(@"startSyncRequest");
[self contentViewLog:@"startSyncRequest"];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
NSLog(@"exipiration handler triggered");
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
[self cancel];
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSMutableURLRequest *anURLRequest;
NSURLResponse *outResponse;
NSError *exitError;
NSString *username;
NSString *password;
NSLog(@"FirstLogin");
anURLRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:webserverLogin, username, password]]];
[anURLRequest setHTTPMethod:@"GET"];
[anURLRequest setTimeoutInterval:120.00];
[anURLRequest setCachePolicy:NSURLRequestReloadIgnoringCacheData];
exitError = nil;
NSData *tmpData = [NSURLConnection sendSynchronousRequest:anURLRequest returningResponse:&outResponse error:&exitError];
[anURLRequest setTimeoutInterval:120.00];
if(exitError != nil) { //somethings goes wrong
NSLog(@"somethings goes wrong");
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
[self cancel];
return;
}
//do some stuff with NSData and prompt the user with a UILocalNotification
NSLog(@"AlltasksCompleted");
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
[self cancel];
});
}
}
上面的代码似乎工作(有时),但许多其他它使我的应用程序崩溃,并带有以下日志信息:
Exception Type: 00000020
Exception Codes: 0x8badf00d
Highlighted Thread: 3
Application Specific Information:
DemoBackApp[5977] has active assertions beyond permitted time:
{(
<SBProcessAssertion: 0xa9da0b0> identifier: UIKitBackgroundCompletionTask process: DemoBackApp[5977] permittedBackgroundDuration: 600.000000 reason: finishTask owner pid:5977 preventSuspend preventIdleSleep
)}
Elapsed total CPU time (seconds): 0.010 (user 0.010, system 0.000), 100% CPU
Elapsed application CPU time (seconds): 0.000, 0% CPU
对于那些问的人,是的。我也尝试过 Async NSURLConnection 方法。不管。即使我使用带有超时处理程序和 didFinishLoading:WithError 的异步方法,它也会崩溃。
我被困住了。任何提示都非常感谢。