I am converting from a [struct] to Swift Data. Two of my elements don't seem to work in Swift Data.
Color
and CLLocationCoordinate2D
conform to PersistentModel
and RelationshipCollection
?I am guessing this is either very easy or impossible. I don't know which, and I don't know how. Any help/pointers will be greatly appreciated‼️
import Foundation
import SwiftData
import CoreLocation
import CoreMotion
import SwiftUI
@Model
final class Item {
var timestamp: Date
var daCount: Int
var gpsTimestamp: Date
var location: CLLocationCoordinate2D
var latitude: Double
var longitude: Double
var myColor: Color
init(timestamp: Date, daCount: Int, gpsTimestamp: Date, location: CLLocationCoordinate2D, latitude: Double, longitude: Double, myColor: Color) {
self.timestamp = timestamp
self.daCount = daCount
self.gpsTimestamp = gpsTimestamp
self.location = location
self.latitude = latitude
self.longitude = longitude
self.myColor = myColor
}
}
When I compile I get the following six errors:
No exact matches in call to instance method 'setValue'
'_PersistedProperty'
here'Color'
conform to 'PersistentModel'
(requirement specified as 'Value'
: 'PersistentModel'
)'Color'
conform to 'RelationshipCollection'
(requirement specified as 'Value'
: 'RelationshipCollection'
)No exact matches in call to instance method 'setValue'
'_PersistedProperty'
here'CLLocationCoordinate2D'
conform to 'PersistentModel'
(requirement specified as 'Value'
: 'PersistentModel'
)'CLLocationCoordinate2D'
conform to
'RelationshipCollection'
(requirement specified as 'Value'
:
'RelationshipCollection'
)No exact matches in call to instance method 'getValue'
No exact matches in call to instance method 'getValue'
No exact matches in call to instance method 'setValue'
No exact matches in call to instance method 'setValue'
One straightforward solution is to create custom types that conform to Codable that holds the underlying values
struct Coordinate2D: Codable {
let latitude: Double
let longitude: Double
init(latitude: Double, longitude: Double) {
self.latitude = latitude
self.longitude = longitude
}
}
struct RGBValues: Codable {
let red: Double
let green: Double
let blue: Double
let opacity: Double
init(red: Double, green: Double, blue: Double, opacity: Double = 1.0) {
self.red = red
self.green = green
self.blue = blue
self.opacity = opacity
}
}
They can then be used in the model directly as property types
@Model
final class Place {
var name: String
var location: Coordinate2D
var color: RGBValues
init(name: String, location: Coordinate2D, color: RGBValues) {
self.name = name
self.location = location
self.color = color
}
}
You can then for convenience add ways to map between your custom types and the built in types
extension Coordinate2D {
init(_ location: CLLocationCoordinate2D) {
self.latitude = location.latitude
self.longitude = location.longitude
}
var location: CLLocationCoordinate2D {
CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
}
}
extension RGBValues {
init(_ color: Color) {
let resolvedColor = color.resolve(in: .init())
red = Double(resolvedColor.red)
green = Double(resolvedColor.green)
blue = Double(resolvedColor.blue)
opacity = Double(resolvedColor.opacity)
}
var color: Color {
Color(red: red, green: green, blue: blue, opacity: opacity)
}
}