Skip to content

Instantly share code, notes, and snippets.

@AndresR173
Created April 6, 2020 23:31
Show Gist options
  • Save AndresR173/209ebb2c51db3be3c214008d54ea7756 to your computer and use it in GitHub Desktop.
Save AndresR173/209ebb2c51db3be3c214008d54ea7756 to your computer and use it in GitHub Desktop.
This example will show you how to use property wrappers to save Codable objects into UserDefaults
import Foundation
struct Task: Codable {
var title: String
var isDone: Bool
}
enum Errors: Error {
case encodeError
case decodeError
case noUserDefaults
}
func saveTask(_ task: Task, forKey key: String) throws {
let userDefaults = UserDefaults.standard
let encoder = JSONEncoder()
do {
let data = try encoder.encode(task)
userDefaults.set(data, forKey: key)
userDefaults.synchronize()
} catch {
throw(Errors.encodeError)
}
}
func getTask(forKey key: String) throws -> Task? {
let userDefaults = UserDefaults.standard
let decoder = JSONDecoder()
guard let data = userDefaults.object(forKey: key) as? Data else {
throw(Errors.noUserDefaults)
}
do {
let task = try decoder.decode(Task.self, from: data)
return task
} catch {
throw(Errors.decodeError)
}
}
@propertyWrapper
struct UserDefaultsWrapper<Value: Codable> {
let key: String
let defaultValue: Value
let userDefaults = UserDefaults.standard
var wrappedValue: Value {
get {
let data = userDefaults.data(forKey: key)
let value = data.flatMap { try? JSONDecoder().decode(Value.self, from: $0) }
return value ?? defaultValue
}
set {
let data = try? JSONEncoder().encode(newValue)
userDefaults.set(data, forKey: key)
userDefaults.synchronize()
}
}
}
let defaultTasks: [Task] = [
Task(title: "Learn SwiftUI", isDone: false),
Task(title: "Share this article", isDone: true)
]
struct TaskProvider {
@UserDefaultsWrapper(key: "Tasks", defaultValue: defaultTasks)
var tasks: [Task]
}
var provider = TaskProvider()
dump(provider.tasks)
provider.tasks.append(Task(title: "Code in Swift", isDone: true))
dump(provider.tasks)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment