Swift - 执行后台任务

时间:2016-12-23 17:40:57

标签: ios swift notifications

我正在尝试在收到通知时在后台运行此代码:

window?.rootViewController?.dismissViewControllerAnimated(false, completion: nil)
NSNotificationCenter.defaultCenter().postNotificationName("ResetStatusBar", object: nil)

所以我把这段代码放在didReceiveRemoteNotification中就像这样:

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
    print("Remote notification received in didReceiveRemoteNotification with fetchCompletionHandler")

    // just pop to rootViewController
    window?.rootViewController?.dismissViewControllerAnimated(false, completion: nil)
    NSNotificationCenter.defaultCenter().postNotificationName("ResetStatusBar", object: nil)
}

当应用程序处于活动状态时收到通知,或者用户点击收到的通知时执行此代码,但是,如果我收到通知,忽略它,然后打开应用程序(我没有杀死,只需按下主页按钮),更改在应用程序中没有生效。

以下是我目前正在做的事情:

  • 在推送通知有效负载中发送'content-available': 1
  • 已根据背景模式的功能检查remote notifications

这也是我在AppDelegate文件中注册推送通知的方式:

let notificationSettings = UIUserNotificationSettings(forTypes: [.Alert,.Badge,.Sound], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
UIApplication.sharedApplication().registerForRemoteNotifications()

我的代码没有执行的任何想法?是因为它是UI改变吗?

P.S。这是我的推送通知有效负载的样子:

let payload = {
  default: notificationDisplayText,
  APNS: {
    aps: {
      alert: notificationDisplayText,
      sound: 'default',
      badge: 1,
      'content-available' : 1
    },
    notificationId: notificationId
  }
}

我将content-available键放在aps对象中是正确的,还是应该将其直接嵌套在APNS对象中?

2 个答案:

答案 0 :(得分:1)

app委托中有两个区域:

如果您想在用户按下主页按钮后继续运行后台... func applicationDidEnterBackground(_ application: UIApplication) { ...}

如果您希望在用户返回应用程序时发生某些事情...... func applicationDidBecomeActive(_ application: UIApplication) { ...}

所以如果你想在后台发生某些事情......比如发送或接收通知,你就会想要使用appDidEnterBackground ......

答案 1 :(得分:1)

如果您想在应用启动时处理未处理的通知,请在didFinishLaunchingWithOptions中使用.remoteNotification键在Swift 3(Swift 2.3中的UIApplicationLaunchOptionsRemoteNotificationKeylaunchOptions中执行该操作{1}}字典。

正如the documentation for application(_:didReceiveRemoteNotification:)所说:

  

如果远程通知到达时应用程序未运行,该方法将启动应用程序并在启动选项字典中提供相应的信息。该应用程序不会调用此方法来处理该远程通知。相反,您对application(_:willFinishLaunchingWithOptions:)application(_:didFinishLaunchingWithOptions:)方法的实现需要获取远程通知有效负载数据并做出相应的响应。

无关,请记住,在didReceiveRemoteNotification中,您必须在处理完通知后致电completionHandler

正如the documentation所说(重点在于原文):

  

完成处理通知后,必须在处理程序参数中调用该块,否则您的应用将被终止。您的应用程序有最多30秒的挂钟时间来处理通知并调用指定的完成处理程序块。实际上,您应该在处理完通知后立即调用处理程序块。系统会跟踪应用程序后台下载的已用时间,功耗和数据成本。处理远程通知时使用大量电源的应用可能无法提前唤醒以处理未来的通知。

相关问题