protocol StorageItem: AnyObject { associatedtype Data: Equatable var savedData: Data? { get set } var data: Data { get } func saveToDisk(_ data: Data) -> Bool } extension StorageItem { /** Get the data to save, if the object has changed */ func dataToSave() -> Data? { guard let savedData else { return data } if savedData != data { return data } return nil } func saveIfNeeded() -> Bool? { guard let data = dataToSave() else { return nil } guard saveToDisk(data) else { return false } savedData = data return true } }