首页 > 解决方案 > 使用 .init(suitename:) 时,对 NSUserDefaults 的观察不起作用

问题描述

如果我使用默认的 UserDefaults,我可以通过 keypath 订阅特定更改的更改。但是,如果我使用使用 init(suiteName:) 创建的 UserDefaults 实例,则不会传递任何更改。

根据 MA​​C Os 发行说明,该问题已在不久前得到解决。但是,我无法证实这一点。有谁知道这个问题并可能解决它?

在以前的版本中,KVO 只能用于 +standardUserDefaults 方法返回的 NSUserDefaults 实例。此外,KVO 忽略了来自其他进程(例如默认值 (1)、扩展程序或应用程序组中的其他应用程序)的更改。这些限制都已得到纠正。来自其他进程的更改将在主队列上异步传递,并忽略 NSKeyValueObservingOptionPrior。

https://developer.apple.com/library/archive/releasenotes/Miscellaneous/RN-Foundation-OSX10.12/index.html

代码示例:

    import UIKit
    import Combine
    import Foundation
    
    @main
    class AppDelegate: UIResponder, UIApplicationDelegate {
        let provider = CalendarProvider()
    }
    
    extension UserDefaults {
        @objc dynamic var startOfTheWeek: Int {
            return integer(forKey: "startOfTheWeek")
        }
    }
    
    final class CalendarProvider: ObservableObject {
        @Published var currentCalendar: Calendar = Calendar.current
        private var observer: NSKeyValueObservation?
        
        init() {
            var calendar = Calendar(identifier: .gregorian)
            calendar.firstWeekday = 1
            self.currentCalendar = calendar
        
            observer = UserDefaults(suiteName: "group.foo.com")?
                .observe(\.startOfTheWeek, options: [.new , .initial],
                                                     changeHandler: { (defaults, change) in
                DispatchQueue.main.async {
                    var calendar = Calendar(identifier: .gregorian)
                    calendar.firstWeekday = change.newValue ?? 1
                    self.currentCalendar = calendar
                }
            })
            
            DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: {
                UserDefaults(suiteName: "group.foo.com")?.setValue(8, forKey: "startOfTheWeek")
            })
        }
        
        deinit {
            observer?.invalidate()
        }
    }

标签: swiftnsuserdefaultskey-value-observingfoundation

解决方案


推荐阅读