推送扩展到 App 触发 KVO
Triggering KVO from Push Extension to App
我正在尝试在主应用程序中实现 KVO 并观察扩展何时更改值。
收到推送时主应用程序打开,但主应用程序中没有触发。只有当我关闭并打开它时,我才能看到变化。
通知Class:
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if let bestAttemptContent = bestAttemptContent {
var user = (bestAttemptContent.userInfo["user"] as! String?)!
let userDefaults = UserDefaults(suiteName: "group.com.test.apps")
userDefaults!.set(user as String, forKey: "User")
userDefaults!.synchronize()
contentHandler(bestAttemptContent)
}
}
}
主要ViewController:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let userDefaults = UserDefaults(suiteName: "group.com.test.apps")
userDefaults!.addObserver(self, forKeyPath: "User", options: NSKeyValueObservingOptions.new, context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
//Not triggered
let userDefaults = UserDefaults(suiteName: "group.com.test.apps")
let user = userDefaults!.string(forKey: "User")
NSLog("User \(user)")
}
}
您使用的是 iOS 10 或更高版本吗? KVO 跨进程(比如扩展)直到 10 才起作用。https://developer.apple.com/library/archive/releasenotes/Miscellaneous/RN-Foundation-OSX10.12/index.html,搜索"Key-Value Observing and NSUserDefaults"
套件的UserDefault
不是共享实例,所以你必须保留它,否则它只是被释放。
这里是固定的App端控制器。使用 Xcode 11.4 / iOS 13.4
测试
注意:KVO 仅在设置了真正的新值时才起作用,因此如果在您的扩展中将相同的值设置为 UserDefaults,则不会通知观察者。
class ViewController: UIViewController {
// keep suite instance as member
let userDefaults = UserDefaults(suiteName: "group.com.test.apps")
override func viewDidLoad() {
super.viewDidLoad()
userDefaults!.addObserver(self, forKeyPath: "User", options: [.new], context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?,
change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
let user = userDefaults!.string(forKey: "User")
NSLog("User \(user)")
}
}
我正在尝试在主应用程序中实现 KVO 并观察扩展何时更改值。 收到推送时主应用程序打开,但主应用程序中没有触发。只有当我关闭并打开它时,我才能看到变化。
通知Class:
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if let bestAttemptContent = bestAttemptContent {
var user = (bestAttemptContent.userInfo["user"] as! String?)!
let userDefaults = UserDefaults(suiteName: "group.com.test.apps")
userDefaults!.set(user as String, forKey: "User")
userDefaults!.synchronize()
contentHandler(bestAttemptContent)
}
}
}
主要ViewController:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let userDefaults = UserDefaults(suiteName: "group.com.test.apps")
userDefaults!.addObserver(self, forKeyPath: "User", options: NSKeyValueObservingOptions.new, context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
//Not triggered
let userDefaults = UserDefaults(suiteName: "group.com.test.apps")
let user = userDefaults!.string(forKey: "User")
NSLog("User \(user)")
}
}
您使用的是 iOS 10 或更高版本吗? KVO 跨进程(比如扩展)直到 10 才起作用。https://developer.apple.com/library/archive/releasenotes/Miscellaneous/RN-Foundation-OSX10.12/index.html,搜索"Key-Value Observing and NSUserDefaults"
套件的UserDefault
不是共享实例,所以你必须保留它,否则它只是被释放。
这里是固定的App端控制器。使用 Xcode 11.4 / iOS 13.4
测试注意:KVO 仅在设置了真正的新值时才起作用,因此如果在您的扩展中将相同的值设置为 UserDefaults,则不会通知观察者。
class ViewController: UIViewController {
// keep suite instance as member
let userDefaults = UserDefaults(suiteName: "group.com.test.apps")
override func viewDidLoad() {
super.viewDidLoad()
userDefaults!.addObserver(self, forKeyPath: "User", options: [.new], context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?,
change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
let user = userDefaults!.string(forKey: "User")
NSLog("User \(user)")
}
}