Created
March 31, 2024 21:07
-
-
Save stephancasas/38cc9d5aaf0dc990078629a1a36a30b6 to your computer and use it in GitHub Desktop.
Syntactically-clean and portable SwiftUI bindings for optional properties on CoreData entities.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// NSManagedObject+DynamicBindings.swift | |
// | |
// Created by Stephan Casas on 3/31/24. | |
// | |
import SwiftUI; | |
import CoreData; | |
protocol DynamicBindings: NSManagedObject { } | |
extension DynamicBindings { | |
/// Create a SwiftUI binding for a managed object's optional property | |
/// - Parameters: | |
/// - key: The keypath to the binding's mutable property. | |
/// - defaultValue: The default value provided to the binding if no value is present. | |
func binding<T>( | |
for key: ReferenceWritableKeyPath<Self, T?>, | |
defaultValue: T? = nil | |
) -> Binding<T> { | |
let defaultValue = defaultValue ?? { | |
switch T.self { | |
case is String.Type: | |
return "" as! T; | |
case is Int.Type: | |
return 0 as! T; | |
case is Bool.Type: | |
return false as! T; | |
case is Float.Type: | |
return Float(0.0) as! T; | |
case is Double.Type: | |
return Double(0.0) as! T; | |
default: | |
fatalError("No inferred default value declared for type \(T.self). Provide a value to `defaultValue`."); | |
break | |
} | |
}(); | |
return .init(get: { | |
self[keyPath: key] ?? defaultValue | |
}, set: { | |
self[keyPath: key] = $0; | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Apply the protocol to your CoreData entity using an extension:
Then use the utility in your SwiftUI views: