I'm using Swift and SwiftData. I have a class called Story and inside that class an array of another class called StoryBox.
I instantiate a Story with a StoryBox array and pass it to a view and try to display its content.
I can display the String of the Story object but if I add the lines to try to access the contents of the any element of the StoryBox array inside it I get an error stating:
"Thread 1: EXC_BREAKPOINT (code=1, subcode=0x1c3c6203c)" on the
return self.getValue(forKey: \.storyBoxArray)
This is autogenerated code from the SwiftData implementation.
Classes:
Story:
import SwiftUI
import SwiftData
@Model
class Story{
let id = UUID()
var storyTitle: String
var storyTitleImage: Data
var storyBoxArray: [StoryBox]
init(storyTitle: String, storyTitleImage: Data, storyBoxArray: [StoryBox]) {
self.storyTitle = storyTitle
self.storyTitleImage = storyTitleImage
self.storyBoxArray = storyBoxArray
}
}
StoryBox:
import SwiftUI
import SwiftData
@Model
class StoryBox {
let id = UUID()
var storyImage: Data
var storyIndex: Int
var storyIsCompleted: Bool
var storyText: String
init(storyImage: Data, storyIndex: Int, storyIsCompleted: Bool, storyText: String) {
self.storyImage = storyImage
self.storyIndex = storyIndex
self.storyIsCompleted = storyIsCompleted
self.storyText = storyText
}
}
View:
import SwiftUI
import SwiftData
struct TempNewView: View {
@State var CurrentStory: Story
var body: some View {
Text("\(CurrentStory.storyTitle)")
let myImage = UIImage(data: CurrentStory.storyTitleImage)
Image(uiImage: myImage!)
let myImage2 = UIImage(data: CurrentStory.storyBoxArray[0].storyImage)
Image(uiImage: myImage2!)
}
}
The error occurs when I try to access the Data here:
let myImage2 = UIImage(data: CurrentStory.storyBoxArray[0].storyImage)
Image(uiImage: myImage2!)
It also crashes the Preview.
Any ideas?
EDIT:
This is the call for the view
TempNewView(CurrentStory: Story(storyTitle: "Story Title_Preview", storyTitleImage: (UIImage(systemName: "5.lane")?.pngData())!, storyBoxArray: preview_createStoryBoxes(number: 6)))
This is the method which generates the array of StoryBox
func preview_createStoryBoxes(number: Int)->[StoryBox]{
var StoryData = [StoryBox]()
for i in 0...number {
StoryData.append(StoryBox(storyImage: UIImage(systemName: "\(i).circle")!.pngData()!, storyIndex: i, storyIsCompleted: false, storyText: "\(i): The quick fox jumps over the lazy dog"))
}
return StoryData
}
SwiftData is a bit sensitive to how you create objects and relationship, specially when all objects are new. The safest way I found is to create an object that is part of the relationship, insert it into the model context and then assign the object(s) that is the other part of the relationship.
So the line
TempNewView(CurrentStory: Story(storyTitle: "Story Title_Preview", storyTitleImage: (UIImage(systemName: "5.lane")?.pngData())!, storyBoxArray: preview_createStoryBoxes(number: 6)))
should be split up into
let story = Story(storyTitle: "Story Title_Preview", storyTitleImage: (UIImage(systemName: "5.lane")?.pngData())!, storyBoxArray: [])
modelContext.insert(story)
story.storyBoxArray = preview_createStoryBoxes(number: 6))) //or use append
And then call the view with story