danieltj27
(Daniel James)
1
I am trying to save a Date as a default value inside AppStorage but I can't get it to work. This is my code:
@AppStorage("CREATED_AT") var created_at = Date()
The error that I get it this:
No exact matches in call to initializer
How can I store a Date value that I can update later on?
Martin
(Martin R)
2
1 Like
I think it's better not to pollute Date with a somewhat arbitrary raw representation, everywhere. Instead, you can do something like this—unfortunately, copying and pasting for all necessary overloads, to match the AppStorage API. 
@AppStorage.Converter("🗝️") var date = .now
import SwiftUI
public extension AppStorage {
/// A way to use `AppStorage` with more types,
/// via conversion to and from the limited supported types.
typealias Converter<Converted> = StorageConverter<Self, Converted>
}
// MARK: - StorageDynamicProperty
extension AppStorage: StorageDynamicProperty { }
// MARK: - Double
public extension AppStorage<Double>.Converter where Storage == AppStorage<Double> {
init(
wrappedValue: Converted,
_ key: String,
store: UserDefaults? = nil,
fromStorage: @escaping FromStorage,
toStorage: @escaping ToStorage
) {
self.init(
storage: .init(wrappedValue: toStorage(wrappedValue), key, store: store),
fromStorage: fromStorage, toStorage: toStorage
)
}
}
public extension AppStorage<Double>.Converter<Date> {
init(
wrappedValue: Converted,
_ key: String,
store: UserDefaults? = nil
) {
self.init(
wrappedValue: wrappedValue,
key,
store: store,
fromStorage: Date.init(timeIntervalSinceReferenceDate:),
toStorage: \.timeIntervalSinceReferenceDate
)
}
}
import SwiftUI
@propertyWrapper public struct StorageConverter<Storage: StorageDynamicProperty, Converted> {
public typealias ToStorage = (Converted) -> Storage.Value
public typealias FromStorage = (Storage.Value) -> Converted
public var wrappedValue: Converted {
get { fromStorage(storage.wrappedValue) }
nonmutating set { storage.wrappedValue = toStorage(newValue) }
}
public var projectedValue: Binding<Converted> {
.init(
get: { wrappedValue },
set: { wrappedValue = $0 }
)
}
// MARK: internal
init(
storage: Storage,
fromStorage: @escaping FromStorage,
toStorage: @escaping ToStorage
) {
self.storage = storage
self.toStorage = toStorage
self.fromStorage = fromStorage
}
// MARK: private
private let storage: Storage
private let fromStorage: FromStorage
private let toStorage: ToStorage
}
public protocol StorageDynamicProperty<Value>: DynamicProperty {
associatedtype Value
var wrappedValue: Value { get nonmutating set }
}
// MARK: - DynamicProperty
extension StorageConverter: DynamicProperty { }
5 Likes
danieltj27
(Daniel James)
4
Thank you for both of your help 
1 Like
nroose
(Nick Roosevelt)
5
That link is now redirecting improperly.
nroose
(Nick Roosevelt)
6
I ended up using a set/get:
@AppStorage("storedStartTime") var storedStartTime = Date.now.timeIntervalSinceReferenceDate
var startTime: Date {
set {storedStartTime = newValue.timeIntervalSinceReferenceDate}
get {return Date(timeIntervalSinceReferenceDate: storedStartTime)}
}
Martin
(Martin R)
7
Can you elaborate? I cannot detect a problem with that link, but please let me know if something needs to be fixed.
nroose
(Nick Roosevelt)
9
Seems to be working now. Sorry.