I have been working on an watchOS version of my iOS app using SwiftData. I have a TabView and on one of the views there is a plus button in the bottom bar. It contains a navigation link. When I tap it for some reason two of the views are stacked and I have to click the back button twice to pop both. After that, when I navigate to another view in the TabView, the app freezes. I checked this in instruments and apparently in "All heap and Anonymous VM" and also "All heap allocations" it is generating hundreds of thousands of objects with category "Malloc 32 bytes" and responsible library "libswiftCore.dylib" and responsible caller "swift_allocObject." This is happening every second, all while the app is frozen. The body of the file that includes the plus button(only watchOS):
List(sessions) { session in
HStack {
VStack {
HStack {
if session.selected == false {
Text(session.name ?? "no name")
} else {
Text(session.name ?? "no name")
.font(.system(size: 12))
Text("(Selected)")
.font(.system(size: 12))
}
Spacer()
}
Spacer()
HStack {
Text(session.cube ?? "no cube")
Spacer()
}
}
Spacer()
if session.cube == "3x3" {
Image(systemName: "square.grid.3x3")
.font(.title2)
} else if session.cube == "2x2" {
Image(systemName: "square.grid.2x2")
.font(.title2)
} else {
Image("4x4")
.font(.title2)
}
}
.contentShape(Rectangle())
.onTapGesture {
if selectedSession.count >= 1 {
if session.selected == true {
return
} else {
withAnimation {
selectedSession[0].selected = false
usleep(100000)
session.selected = true
}
}
} else {
withAnimation {
session.selected?.toggle()
}
}
}
}
.navigationTitle("Sessions")
.toolbar {
ToolbarItemGroup(placement: .bottomBar) {
Spacer()
NavigationLink {
AddSessionView()
} label: {
Image(systemName: "plus")
}
}
}
(Remember that this is only occurring on watches) The body of the file that the plus button goes to:
ScrollView {
VStack {
TextField("Name", text: $name)
.font(.caption)
.frame(maxHeight: 50)
Picker("Cube", selection: $cube) {
ForEach(cubes, id: \.self) { cube in
Text(cube)
}
}
.onChange(of: cube) {
getImage()
}
.frame(minHeight: 50)
Button("Create") {
if name != "" {
if cube == "Playground" {
playground = true
cube = "3x3"
}
let session = Session(name: name, cube: cube, image: image, pinned: false, selected: false, playground: playground)
modelContext.insert(session)
if playground {
playground = false
}
dismiss()
}
}
}
}
The getImage()
function that the onChange
calls:
private func getImage() {
switch cube {
case "3x3":
image = "square.grid.3x3"
case "2x2":
image = "square.grid.2x2"
case "4x4":
image = "4x4"
default:
print("this will never execute")
image = "square.grid.3x3"
}
}
Any help appreciated.