后台任务即将到期时的本地通知

时间:2012-07-10 12:49:07

标签: ios background uilocalnotification

iOS应用可以在后台任务即将到期时安排本地通知吗? 当应用程序使用NSOperationQueue进入后台时,基本上我有一些服务器端正在进行下载 我想要的是当后台任务即将完成时通过本地通知通知用户。那么该用户可以将应用程序带到前台以保持持续的服务器数据下载
下面是我正在使用的代码,但我没有看到任何本地通知

UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler: ^{
        dispatch_async(dispatch_get_main_queue(), ^{
           /*TO DO
            prompt the user if they want to continue syncing through push notifications. This will get the user to essentially wake the app so that sync can continue.
             */
            // create the notification and then set it's parameters
            UILocalNotification *beginNotification = [[[UILocalNotification alloc] init] autorelease];
            if (beginNotification) {
                beginNotification.fireDate = [NSDate date];
                beginNotification.timeZone = [NSTimeZone defaultTimeZone];
                beginNotification.repeatInterval = 0;
                beginNotification.alertBody = @"App is about to exit .Please bring app to background to continue dowloading";
                beginNotification.soundName = UILocalNotificationDefaultSoundName;
                // this will schedule the notification to fire at the fire date
                //[app scheduleLocalNotification:notification];
                // this will fire the notification right away, it will still also fire at the date we set
                [application scheduleLocalNotification:beginNotification];
            }

            [application endBackgroundTask:self->bgTask];
            self->bgTask = UIBackgroundTaskInvalid;
        });
    }];

2 个答案:

答案 0 :(得分:5)

我相信您的代码问题是dispatch_async调用。这是来自docs的东西:

  

<强> -beginBackgroundTaskWithExpirationHandler:
  (...)在主线程上同步调用处理程序,从而在通知应用程序时暂时阻止应用程序的暂停。

这意味着您的应用程序在此到期处理程序完成后立即暂停。您正在主队列上提交异步块,因为这个实际主队列(请参阅文档),它将在以后执行

解决方法不是调用dispatch_async ,而是直接在此处理程序中运行该代码。

我看到的另一个问题是,在过期处理程序中通知用户为时已晚,应该在到期之前完成(比如一分钟左右)。您只需定期检查backgroundTimeRemaining并在达到间隔时显示此警报。

答案 1 :(得分:0)

您的代码永远不会被执行,因为您计划将来运行代码,然后通过endBackgroundTask:终止您的backoground任务。此外,在主线程上调用过期处理程序,因此您只需将代码放在那里并避免使用此dispatch_asyncperformSelectorOnMainThread: foobar。