Post

Replies

Boosts

Views

Activity

How to declare a Protocol that conforms to Observable
I'm learning Swift — from the language docs, it seems to me that this should be possible, but I get the commented compiler error on the line below. Can someone explain why this is illegal? import SwiftUI struct ContentView: View { // 'init(wrappedValue:)' is unavailable: The wrapped value must be an object that conforms to Observable @Bindable var failing : SomeProtocol var body: some View { Text(failing.foo) } } protocol SomeProtocol : Observable { var foo: String { get } } The use case is adapting different class hierarchies to be displayed by the same View: final SwiftData model classes and dynamic models supporting editing and calculation during model creation. Apple docs on Observation and Protocol Inheritance have led me to believe this should be possible. Thanks for taking time to read (and reply).
1
0
396
Dec ’23
SwiftData Unexpected type for CompositeAttribute
I'm getting SwiftData/SchemaProperty.swift:369: Fatal error: Unexpected type for CompositeAttribute CLLocationCoordinate2D in the following situation - this is simplified, but demonstrates the issue. There are a lot of posts discussing Measurements running into the same issue, and the recommended fix is to turn the Measurement (or CLLocationCoordinate2D in this example) into a computed property and generate it on the fly. I'm trying to cache instances of CLLocationCoordinate2D, rather than creating new ones every time a View renders, so those work arounds don't work around. The SwiftData docs seem to indicate that this should be possible. Can anyone recommend a fix? Thanks in advance. import SwiftData import MapKit @Model final class foo : Codable { var bar: SomeStruct init( bar: SomeStruct ) { self.bar = bar } enum CodingKeys : CodingKey { case bar } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.bar = try container.decode(SomeStruct.self, forKey: .bar) } func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(bar, forKey: .bar) } } struct SomeStruct : Codable { var latitude: Double var longitude: Double @Transient var clLocation: CLLocationCoordinate2D init(latitude: Double, longitude: Double) { self.latitude = latitude self.longitude = longitude self.clLocation = CLLocationCoordinate2D(latitude: latitude, longitude: longitude) } enum CodingKeys : CodingKey { case latitude, longitude } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.latitude = try container.decode(Double.self, forKey: .latitude) self.longitude = try container.decode(Double.self, forKey: .longitude) self.clLocation = CLLocationCoordinate2D(latitude: latitude, longitude: longitude) } func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(latitude, forKey: .latitude) try container.encode(longitude, forKey: .longitude) } }
4
0
1.1k
Dec ’23