首页 文章

关于远程通知的后台任务在一段时间后暂停

提问于
浏览
3

我正在使用带有content-available:true标志的远程通知来在后台启动静态推送通知并处理或从远程API获取更新 . 当应用程序处于前台时,代码执行正常,或者在上次运行后处于挂起状态 .

在后台测试期间,当系统基于传入的静默推送通知启动应用程序时,代码仅部分处理,并且应用程序在大约150毫秒后快速暂停 . 我预计应用程序将有30秒的时间来处理传入通知及其有效负载 . 如果我需要更多时间处理和/或获取新数据,是否需要调整应用程序功能或请求后台任务?

部署目标iOS 8,在iOS 9上测试.Xcode 7.3.1,Swift 2.2.1 .

功能:后台模式开,模式:启用远程通知

AppDelegate

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {

    if let userInfo = userInfo as? [String: AnyObject] {

        // Processing of the payload is done in separate Operation class (using Operations framework)
        // The completion handler is called on the end of the processing/fetching in that operation
        // But in case of launching the app in the background it never reaches the call of the completion handler

        let parseNotificationOperation = ParseNotificationOperation(userInfo: userInfo, fetchCompletionHandler: completionHandler)
        MainService.shared.enqueueApnsOperation(parseNotificationOperation)
    }
}

1 回答

  • 4

    马丁科尔斯,

    您可以使用expirationHandlers来延长后台执行时间 . 虽然iOS分配给您的应用程序需要多长时间取决于我们无法控制的各种因素,但我们注意到它主要提供我们的应用程序在后台执行3分钟 .

    这是你如何实现它:)

    你在AppDelegate声明,

    UIBackgroundTaskIdentifier backgroundTask;
    

    当你在didReceiveRemoteNotification中收到APNS时写这个,

    if (!backgroundTask || backgroundTask == UIBackgroundTaskInvalid) {
            backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
                    //do all clean up job here gets called few seconds before expiration
                    [[UIApplication sharedApplication] endBackgroundTask:backgroundTask];
                    backgroundTask = UIBackgroundTaskInvalid;
            }];
        }
    

    EDIT

    刚刚意识到你正在使用swift所以这里是代码为你快速:)

    在AppDelegate中声明一个名为backgroundTask的变量,

    var backgroundTask : UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid
    

    并在你的didRecieveRemoteNotification中使用它,如下所示,

    func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
    
        if let userInfo = userInfo as? [String: AnyObject] {
            let parseNotificationOperation = ParseNotificationOperation(userInfo: userInfo, fetchCompletionHandler: completionHandler)
            MainService.shared.enqueueApnsOperation(parseNotificationOperation)
    
            if (backgroundTask == UIBackgroundTaskInvalid) {
                backgroundTask = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler { () -> Void in
                    self.endTask()
                }
            }
        }
    }
    

    最后写一个方法,一旦你完成它就使你的到期处理程序失效:)

    func endTask(){
       //do all your clean up here, this is called few seconds before the task expires.
       UIApplication.sharedApplication().endBackgroundTask(backgroundTask)
       backgroundTask = UIBackgroundTaskInvalid;
    }
    

    就是这样:)快乐的编码伙伴:)

相关问题