I’ve outlined the next fashions in a Swift iOS utility:
import Basis
import SwiftData
@Mannequin
class Person: Identifiable {
let id: UUID
let identify: String
var location: NamedLocation?
var buddy: Bool = false
init(id: UUID = UUID(), identify: String) {
self.id = id
self.identify = identify
}
}
struct NamedLocation: Codable {
let identify: String?
let loc: Location
init(identify: String?, location: Location) {
self.identify = identify
self.loc = location
}
}
enum Location: Codable {
case deal with(String)
case coordinates(Double, Double)
}
When I attempt to populate with take a look at information to see how my consumer interface appears, it
works high quality:
import SwiftUI
import SwiftData
struct HomeView: View {
@Atmosphere(.modelContext) personal var modelContext
@Question personal var objects: [User]
var physique: some View {
// different views omitted for brevity
VStack(alignment: .main, spacing: 16.0) {
Textual content("your close by mates")
Record {
ForEach(objects) { merchandise in
HStack {
VStack {
Textual content(merchandise.identify)
if let location = merchandise.location {
Textual content(location.identify ?? "unknown location")
}
}
}
}
}
.listStyle(.plain)
.scrollContentBackground(.hidden)
Spacer()
}
}
}
#Preview {
let config = ModelConfiguration(isStoredInMemoryOnly: true, allowsSave: true)
let container = attempt! ModelContainer(for: Schema([User.self]), configurations: config)
for i in 1..<10 {
var consumer = Person(identify: "Instance Person (i)")
container.mainContext.insert(consumer)
}
return HomeView().modelContainer(container)
}
However as quickly as I add places to the customers, then my preview begins crashing
(and it additionally crashes once I take a look at within the simulator).
for i in 1..<10 {
var consumer = Person(identify: "Instance Person (i)")
container.mainContext.insert(consumer)
// I checked out different SO solutions, and so they advised the problem comes from
// not saving the mannequin earlier than making an attempt to switch its properties. No cube.
attempt! container.mainContext.save()
consumer.location = NamedLocation(identify: "hurk", location: .coordinates(40.72, -75.49))
attempt! container.mainContext.save()
}
The crash is EXC_BREAKPOINT
on Person.location.getter
, and the crash logs
do not present a lot element.
Exception Kind: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x00000001c4352d5c
Termination Motive: SIGNAL 5 Hint/BPT entice: 5
Terminating Course of: exc handler [82555]
Triggered by Thread: 0
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 SwiftData 0x1c4352d5c 0x1c42d1000 + 531804
1 SwiftData 0x1c435597c 0x1c42d1000 + 543100
2 SwiftData 0x1c4316014 0x1c42d1000 + 282644
3 rdvz 0x100357830 Person.location.getter + 332 (@__swiftmacro_4rdvz4UserC8location18_PersistedPropertyfMa_.swift:10)
4 HomeView.1.preview-thunk.dylib 0x101592f28 closure #1 in closure #1 in closure #1 in closure #1 in closure #1 in closure #2 in closure #1 in HomeView.__preview__body.getter + 476 (HomeView.swift:73)
5 SwiftUI 0x1c49e38b8 0x1c4371000 + 6760632
6 HomeView.1.preview-thunk.dylib 0x101592b7c closure #1 in closure #1 in closure #1 in closure #1 in closure #2 in closure #1 in HomeView.__preview__body.getter + 144 (HomeView.swift:68)
7 SwiftUI 0x1c52e0840 0x1c4371000 + 16185408
8 HomeView.1.preview-thunk.dylib 0x1015928cc closure #1 in closure #1 in closure #1 in closure #2 in closure #1 in HomeView.__preview__body.getter + 148 (HomeView.swift:67)
9 SwiftUI 0x1c532f9a0 0x1c4371000 + 16509344
10 SwiftUI 0x1c53379e4 0x1c4371000 + 16542180
11 SwiftUI 0x1c4cfd750 0x1c4371000 + 10012496
12 SwiftUI 0x1c5337a00 0x1c4371000 + 16542208
13 libswiftCore.dylib 0x192adba04 withUnsafePointer<A, B>(to:_:) + 20
14 libswiftCore.dylib 0x192c862ac withUnsafeMutablePointer<A, B>(to:_:) + 12
15 SwiftUI 0x1c532f0f0 0x1c4371000 + 16507120
16 SwiftUI 0x1c5330e24 0x1c4371000 + 16514596
17 SwiftUI 0x1c5330838 0x1c4371000 + 16513080
18 SwiftUI 0x1c533575c 0x1c4371000 + 16533340
19 SwiftUI 0x1c52f7950 0x1c4371000 + 16279888
20 SwiftUI 0x1c497bc10 0x1c4371000 + 6335504
21 SwiftUI 0x1c5374abc 0x1c4371000 + 16792252
Why is that this crash occurring, and the way do I repair it?
Edit: If I take away the member loc
from NamedLocation
, or I make it non-compulsory and nil
, the preview stops crashing. Why? And the way do I make it work?
Edit 2: I discovered that the problem is said to how Location
is continued. I assumed that its implementation of Codable
was flawed, so I attempted offering a handbook one, nevertheless it doesn’t work as a result of the info handed to the decoding methodology doesn’t match the info produced by the encoding methodology:
enum Location: Codable {
case deal with(String)
case coordinates(Double, Double)
enum CodingKeys: String, CodingKey {
case type
case deal with
case latitude
case longitude
}
init(from decoder: Decoder) throws {
let container = attempt! decoder.container(keyedBy: CodingKeys.self)
// this assertion fails; SwiftData provides a container with keys "deal with" and "coordinates" for some purpose
let type = attempt! container.decode(String.self, forKey: .type)
swap type {
case "deal with":
let deal with = attempt! container.decode(String.self, forKey: .deal with)
self = .deal with(deal with)
case "coordinates":
let latitude = attempt! container.decode(Double.self, forKey: .latitude)
let longitude = attempt! container.decode(Double.self, forKey: .longitude)
self = .coordinates(latitude, longitude)
default:
throw DecodingError.dataCorruptedError(forKey: .type, in: container, debugDescription: "Invalid location kind")
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
swap self {
case .deal with(let deal with):
attempt! container.encode("deal with", forKey: .type)
attempt! container.encode(deal with, forKey: .deal with)
case .coordinates(let latitude, let longitude):
attempt! container.encode("coordinates", forKey: .type)
attempt! container.encode(latitude, forKey: .latitude)
attempt! container.encode(longitude, forKey: .longitude)
}
}
}