Skip to content

Commit eb0cc95

Browse files
committed
wip
1 parent 3879d2c commit eb0cc95

File tree

1 file changed

+36
-17
lines changed

1 file changed

+36
-17
lines changed

Sources/ComposableArchitecture/SharedState/PersistenceKey/AppStorageKey.swift

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -290,37 +290,56 @@ extension AppStorageKey: PersistenceKey {
290290
didSet: @escaping @Sendable (_ newValue: Value?) -> Void
291291
) -> Shared<Value>.Subscription {
292292
let previousValue = LockIsolated(initialValue)
293-
let userDefaultsDidChange = NotificationCenter.default.addObserver(
294-
forName: UserDefaults.didChangeNotification,
295-
object: self.store.wrappedValue,
296-
queue: nil
297-
) { _ in
298-
let newValue = load(initialValue: initialValue)
299-
defer { previousValue.withValue { $0 = newValue } }
300-
guard
301-
!(_isEqual(newValue as Any, previousValue.value as Any) ?? false)
302-
|| (_isEqual(newValue as Any, initialValue as Any) ?? true)
303-
else {
304-
return
293+
let removeObserver: () -> Void
294+
if key.contains(".") {
295+
let userDefaultsDidChange = NotificationCenter.default.addObserver(
296+
forName: UserDefaults.didChangeNotification,
297+
object: store.wrappedValue,
298+
queue: nil
299+
) { _ in
300+
let newValue = load(initialValue: initialValue)
301+
defer { previousValue.withValue { $0 = newValue } }
302+
func isEqual<T>(_ lhs: T, _ rhs: T) -> Bool? {
303+
func open<U: Equatable>(_ lhs: U) -> Bool {
304+
lhs == rhs as? U
305+
}
306+
guard let lhs = lhs as? any Equatable else { return nil }
307+
return open(lhs)
308+
}
309+
guard
310+
!(isEqual(newValue, previousValue.value) ?? false)
311+
|| (isEqual(newValue, initialValue) ?? true)
312+
else {
313+
return
314+
}
315+
guard !SharedAppStorageLocals.isSetting
316+
else { return }
317+
didSet(newValue)
305318
}
306-
guard !SharedAppStorageLocals.isSetting
307-
else { return }
308-
didSet(newValue)
319+
removeObserver = { NotificationCenter.default.removeObserver(userDefaultsDidChange) }
320+
} else {
321+
let observer = Observer { newValue in
322+
guard !SharedAppStorageLocals.isSetting
323+
else { return }
324+
didSet(newValue)
325+
}
326+
store.wrappedValue.addObserver(observer, forKeyPath: key, options: .new, context: nil)
327+
removeObserver = { store.wrappedValue.removeObserver(observer, forKeyPath: key) }
309328
}
310329
let willEnterForeground: (any NSObjectProtocol)?
311330
if let willEnterForegroundNotificationName {
312331
willEnterForeground = NotificationCenter.default.addObserver(
313332
forName: willEnterForegroundNotificationName,
314333
object: nil,
315-
queue: nil
334+
queue: .main
316335
) { _ in
317336
didSet(load(initialValue: initialValue))
318337
}
319338
} else {
320339
willEnterForeground = nil
321340
}
322341
return Shared.Subscription {
323-
NotificationCenter.default.removeObserver(userDefaultsDidChange)
342+
removeObserver()
324343
if let willEnterForeground {
325344
NotificationCenter.default.removeObserver(willEnterForeground)
326345
}

0 commit comments

Comments
 (0)