sunshinejr / SwiftyUserDefaults

Modern Swift API for NSUserDefaults
http://radex.io/swift/nsuserdefaults/static
MIT License
4.85k stars 366 forks source link

Custom setter/getter support #195

Closed StevenSorial closed 4 years ago

StevenSorial commented 5 years ago

Is custom setter/getter for defaults currently supported? I saw in #154 that it was initially planned but I don't see it in the docs.

sunshinejr commented 5 years ago

Hey @StevenMagdy! Yes, we introduced custom getters/setters with the introduction of bridges in version 4.0.

See the Custom Types section in the Readme to find out how to create your custom bridge.

Also, let me know if you have any troubles with that :)

StevenSorial commented 5 years ago

Thanks for the quick reply :) I have an array of a Codable struct that I want to filter before saving in SwiftyUserDefaults

what I understood should be done do is:

final class DefaultsCountryArrayBridge: DefaultsBridge<[Country]> {
  override func save(key: String, value: [Country]?, userDefaults: UserDefaults) {
    guard let value = value?.filter({ $0.id > 0 }),
      let data = try? JSONEncoder().encode(value) else {
      userDefaults.removeObject(forKey: key)
      return
    }
    // userDefaults.set(encodable: values, forKey: key) is not accessible
    userDefaults.set(data, forKey: key)
  }

  override func get(key: String, userDefaults: UserDefaults) -> [Country]? {
    guard let data = userDefaults.data(forKey: key) else { return nil }
    return deserialize(data)
  }

  override func isSerialized() -> Bool {
    return true
  }

  override func deserialize(_ object: Any) -> [Country]? {
    guard let data = object as? Data else { return nil }
    return try? JSONDecoder().decode([Country].self, from: data)
  }
}

extension Country: DefaultsSerializable {
  static var _defaults: DefaultsBridge<Country> { return DefaultsCodableBridge() }
  static var _defaultsArray: DefaultsBridge<[Country]> { return DefaultsCountryArrayBridge() }
}

but i feel (and hope) it should be simpler than this, shouldn't it be a simple clousure that would be called before saving ?

sunshinejr commented 5 years ago

@StevenMagdy yeah, you should be able to inherit from DefaultsCodableBridge and just override save func with the filtering and then calling super.save... when you filtered out the values.