我正在尝试使用 XMPPFramework 在应用程序终止之前在“10 分钟窗口”中显示背景通知。似乎所有网络请求都在后台排队,xmppStream:didReceiveMessage:
直到应用程序回到前台才被调用。
我注意到像动词这样的应用程序支持这种行为。它们显然不是 VoIP 应用程序,所以我很好奇它们是如何实现这种行为的。
我正在尝试使用 XMPPFramework 在应用程序终止之前在“10 分钟窗口”中显示背景通知。似乎所有网络请求都在后台排队,xmppStream:didReceiveMessage:
直到应用程序回到前台才被调用。
我注意到像动词这样的应用程序支持这种行为。它们显然不是 VoIP 应用程序,所以我很好奇它们是如何实现这种行为的。
如果其他人遇到此问题,您可以通过将此代码添加到您的 App Delegate 来解决它。如果您想查看,我的完整源代码在这里:OTRAppDelegate.m。其他相关代码在OTRBuddy.m的 receiveMessage: 中。
- (void)applicationDidEnterBackground:(UIApplication *)application
{
NSLog(@"Application entered background state.");
NSAssert(self.backgroundTask == UIBackgroundTaskInvalid, nil);
self.didShowDisconnectionWarning = NO;
self.backgroundTask = [application beginBackgroundTaskWithExpirationHandler: ^{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Background task expired");
if (self.backgroundTimer)
{
[self.backgroundTimer invalidate];
self.backgroundTimer = nil;
}
[application endBackgroundTask:self.backgroundTask];
self.backgroundTask = UIBackgroundTaskInvalid;
});
}];
dispatch_async(dispatch_get_main_queue(), ^{
self.backgroundTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(timerUpdate:) userInfo:nil repeats:YES];
});
}
- (void) timerUpdate:(NSTimer*)timer {
UIApplication *application = [UIApplication sharedApplication];
NSLog(@"Timer update, background time left: %f", application.backgroundTimeRemaining);
if ([application backgroundTimeRemaining] < 60 && !self.didShowDisconnectionWarning)
{
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif) {
localNotif.alertBody = EXPIRATION_STRING;
localNotif.alertAction = OK_STRING;
[application presentLocalNotificationNow:localNotif];
}
self.didShowDisconnectionWarning = YES;
}
if ([application backgroundTimeRemaining] < 10)
{
// Clean up here
[self.backgroundTimer invalidate];
self.backgroundTimer = nil;
[application endBackgroundTask:self.backgroundTask];
self.backgroundTask = UIBackgroundTaskInvalid;
}
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
/*
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
*/
NSLog(@"Application became active");
if (self.backgroundTimer)
{
[self.backgroundTimer invalidate];
self.backgroundTimer = nil;
}
if (self.backgroundTask != UIBackgroundTaskInvalid)
{
[application endBackgroundTask:self.backgroundTask];
self.backgroundTask = UIBackgroundTaskInvalid;
}
application.applicationIconBadgeNumber = 0;
}