我的应用程序可以通过PushKit接收后台通知。这些PushKit通知会触发一项操作,以清理先前传递的常规通知。
当我终止应用程序并收到PushKit通知时,我的初始视图控制器(在情节提要中配置)会触发viewDidAppear。这给我造成了一些问题。我知道PushKit在后台启动您的应用程序,但是我不明白为什么viewDidAppear会被触发。因为该应用实际上从未打开过。
伪AppDelegate.swift:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
voipRegistration()
Messaging.messaging().delegate = self
// setup Firebase/Bugfender
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) {granted, _ in
// setup regular notifications
}
application.registerForRemoteNotifications()
return true
}
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: identifiers)
}
func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType) {
// register token with server
}
fileprivate func voipRegistration() {
let voipRegistry = PKPushRegistry(queue: nil)
voipRegistry.delegate = self
voipRegistry.desiredPushTypes = [.voIP]
}
我想知道是否通过PushKit触发viewDidAppear是否是正常行为?初始控制器中的viewDidAppear启动了我的身份验证过程,我不希望在应用程序处于后台时发生这种情况。
答案 0 :(得分:1)
如发布的@fewlinesofcode链接中所述,viewDidAppear
在实际出现在屏幕上时不会触发,而是在将其添加到视图控制器层次结构时触发。因此,这会在启动时触发。
我使用UIApplication.shared.applicationState
解决了这个问题,就像这样:
伪AppDelegate.swift:
func applicationWillEnterForeground(_ application: UIApplication) {
center.post(name: .ApplicationWillEnterForeground, object: self, userInfo: nil)
}
伪BaseViewController.swift:
class BaseViewController: UIViewController {
var applicationWillEnterForegroundObserver: NSObjectProtocol?
let center = NotificationCenter.default
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if UIApplication.shared.applicationState != .background {
authenticate()
} else {
if applicationWillEnterForegroundObserver == nil {
applicationWillEnterForegroundObserver = center.addObserver(
forName: .ApplicationWillEnterForeground,
object: nil, queue: nil) { (_) in
self.center.removeObserver(self.applicationWillEnterForegroundObserver!)
self.authenticate()
}
}
}
}
fileprivate func authenticate() {
// do authentication logic
}
}
这会在viewDidAppear
中检查应用程序是否在后台运行(例如PushKit启动应用程序时)。如果没有,只需进行身份验证并继续。如果是这样,请为applicationWillEnterForeground
安排一个监听器,以在应用程序真正出现在前台时立即进行身份验证。
答案 1 :(得分:0)
您可以从Apple official documentation
中找到在收到PushKit通知后,如果应用未运行,系统会自动启动。相比之下,不能保证用户通知会启动您的应用。
是的,这是正确的行为。
UPD:关键是,在收到PushKit通知后,该应用程序将被唤醒。应用程序一旦运行,就会有一定的执行时间,并且您的代码也正在执行。