一尘不染

为计算属性添加@Published行为

swift

我试图使它ObservableObject具有包装UserDefaults变量的属性。

为了符合要求ObservableObject,我需要使用来包装属性@Published。不幸的是,我不能将其应用于计算的属性,因为我使用了这些UserDefaults值。

我该如何运作?我该怎么做才能达到目的@Published


阅读 460

收藏
2020-07-07

共1个答案

一尘不染

更新:使用EnclosingSelf下标,可以做到!

奇迹般有效!

import Combine
import Foundation

class LocalSettings: ObservableObject {
  static var shared = LocalSettings()

  @Setting(key: "TabSelection")
  var tabSelection: Int = 0
}

@propertyWrapper
struct Setting<T> {
  private let key: String
  private let defaultValue: T

  init(wrappedValue value: T, key: String) {
    self.key = key
    self.defaultValue = value
  }

  var wrappedValue: T {
    get {
      UserDefaults.standard.object(forKey: key) as? T ?? defaultValue
    }
    set {
      UserDefaults.standard.set(newValue, forKey: key)
    }
  }

  public static subscript<EnclosingSelf: ObservableObject>(
    _enclosingInstance object: EnclosingSelf,
    wrapped wrappedKeyPath: ReferenceWritableKeyPath<EnclosingSelf, T>,
    storage storageKeyPath: ReferenceWritableKeyPath<EnclosingSelf, Setting<T>>
  ) -> T {
    get {
      return object[keyPath: storageKeyPath].wrappedValue
    }
    set {
      (object.objectWillChange as? ObservableObjectPublisher)?.send()
      UserDefaults.standard.set(newValue, forKey: object[keyPath: storageKeyPath].key)
    }
  }
}
2020-07-07