问题描述
我有一个iOS应用,我想在其中使用Google Cloud Firestore来存储用户偏好设置,但是我想出一个优雅的解决方案来解决我的问题,该解决方案在更改以下任何一项后都可以调用我的saveSettingsToFirestore()
Settings
结构的属性。
我当然不希望在应用程序中修改设置的每个实例之后手动调用我的saveSettingsToFirestore()
函数。我想我可以在此Settings结构的所有15个以上的属性中放置一个单独的“ didSet”属性观察器,但这看起来很难看,我无法想象这是最佳实践。
我已经考虑过KVO,但是找不到适合我的案例的好例子,并且在设置它时遇到了困难。
同样,如果您有更好的解决方案来管理与用户帐户相关联的一组变量,请告诉我。我特别不使用NSUserDefaults,因为我想将数据与用户ID而不是用户的iCloud帐户关联。
这是我要观察的结构:
struct Settings: Codable {
static var shared = Settings()
var hideTimesAfter = "10:00 PM"
var hideTimesBefore = "5:00 AM"
var increment = 15
var nextColorIndex = 1
var adsEnabled = true
var alertsEnabled = true
var bugShakeEnabled = true
var didSeeIOSUpdateRequest = false
var firstTime = true
var isIdleTimerdisabled = false
var notificationsEnabled = true
var premiumEnabled = false
var soundsEnabled = true
var twentyFourHourModeEnabled = false
var vibrationsEnabled = true
private init() { }
}
这是我尝试与观察者将struct
重组为NSObject class
的尝试,但我仍在尝试弄清楚行进方向,并希望从中获得任何见识。
class Settings: NSObject,Codable {
static let shared = Settings()
@objc dynamic var hideTimesAfter = "10:00 PM"
@objc dynamic var hideTimesBefore = "5:00 AM"
@objc dynamic var increment = 15
@objc dynamic var nextColorIndex = 1
@objc dynamic var adsEnabled = true
@objc dynamic var alertsEnabled = true
@objc dynamic var bugShakeEnabled = true
@objc dynamic var didSeeIOSUpdateRequest = false
@objc dynamic var firstTime = true
@objc dynamic var isIdleTimerdisabled = false
@objc dynamic var notificationsEnabled = true
@objc dynamic var premiumEnabled = false
@objc dynamic var soundsEnabled = true
@objc dynamic var twentyFourHourModeEnabled = false
@objc dynamic var vibrationsEnabled = true
func updateDate() {
print("yo firestore,get this shit")
}
let observed = Settings.shared
let observer = MyObserver(object: observed)
}
class MyObserver: NSObject {
@objc var objectToObserve: Settings
var observation: NSkeyvalueObservation?
init(object: Settings) {
objectToObserve = object
super.init()
observation = observe(
\.objectToObserve.adsEnabled,options: [.old,.new]
) { object,change in
print("myDate changed from: \(change.oldValue!),updated to: \(change.newValue!)")
}
}
}
解决方法
如果所有(或几乎所有)这些设置都在单个视图控制器中进行了更改,那么我不会考虑使用KVO模型或放弃对较新框架的OS支持,因为您的问题确实比应有的问题简单得多更简单的解决方案。
您不必在乎这些设置的各个值更改,因为那意味着您在乎每次用户更改数据库时都更新数据库。即使使用Firestore的定价模型,效率也不高。您应该关心的是,当用户完成对视图控制器的操作后,任何值都没有更改-如果更改了该值,则您想在用户下方更新数据库(他们不需要等待或点击保存按钮,因为Firestore具有脱机功能。
因此,当用户打开此视图控制器时,只需将这些设置的当前值记录在视图控制器本身中(也许在viewDidLoad
中),当用户离开视图控制器时,请检查是否存在任何值已更改(也许在viewWillDisappear
中);如果是,则更新数据库。