UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: Something wrong with SwiftData

Forums > Swift

I have made the following code to basically play around with haptics:

LibraryView.swift

import SwiftUI
import SwiftData

struct LibraryView: View {

    @Environment(\.modelContext) var modelContext
    @Query/*(sort: \CustomHaptic.dateMade)*/ var customHapticArray: [CustomHaptic]
    @Query/*(sort: \DefaultHaptic.dateMade)*/ var defaultHapticArray: [DefaultHaptic]

    @State private var showingAddCustomHaptic = false
    @State private var showingAddDefaultHaptic = false

    var body: some View {
        NavigationStack {
            VStack {
                List {
                    ForEach(customHapticArray) { customHaptic in
                        HStack {
                            VStack {
                                Text("\(customHaptic.sharpness)")
                                Text("")
                                Text("\(customHaptic.intensity)")
                            }

                            Spacer()

                            VStack {
                                Text("\(customHaptic.repeats)")
                            }
                        }
                    }
                }
            }
            .sheet(isPresented: $showingAddCustomHaptic, content: {
                NewCustomHaptic()
            })
            .toolbar {
                Button("New Custom Haptic", systemImage: "plus") {

                    showingAddCustomHaptic = true
                }
            }
            .navigationTitle("Haptikiser")
        }
    }
}

And NewCustomHaptic.swift, which is a sheet to add a new class CustomHaptic:

@Model
class CustomHaptic: Identifiable {

    var id = UUID()

    var dateMade = Date.now

    var repeats: Int

    var sharpness: Float
    var intensity: Float

    init(repeats: Int, sharpness: Float, intensity: Float) {
        self.repeats = repeats
        self.sharpness = sharpness
        self.intensity = intensity
    }
}

and

import SwiftUI
import SwiftData

struct NewCustomHaptic: View {

    @Environment(\.dismiss) var dismiss

    @Environment(\.modelContext) var modelContext
    @Query(sort: \CustomHaptic.dateMade) var customHapticArray: [CustomHaptic]

    @State var sharpness: Float = 1
    @State var intensity: Float = 1
    @State var repeats: Int = 3

    let array0to1: [Float] = [0.2, 0.4, 0.6, 0.8, 1.0]

    var body: some View {
        VStack {
            Form {
                Section("Sharpness") {
                    Picker(selection: $sharpness, label: Label("Sharpness", systemImage: "bolt.horizontal")) {
                        ForEach(array0to1, id: \.self) { i in
                            Text("\(Int(i * 10))")

                        }

                    }

                    .pickerStyle(.segmented)

                }

                Section("Intensity") {
                    Picker(selection: $intensity, label: Label("Intensity", systemImage: "42.circle")) {
                        ForEach(array0to1, id: \.self) { i in
                            Text("\(Int(i * 10))")

                        }

                    }
                    .pickerStyle(.segmented)

                }

                Section("Repeats") {
                    Stepper(value: $repeats, in: 1...10) {
                        Label("\(repeats)", systemImage: "repeat")
                    }
                }
            }

            Button("Done") {

                let newCustomHaptic = CustomHaptic(repeats: repeats, sharpness: sharpness, intensity: intensity)
                modelContext.insert(newCustomHaptic)

                dismiss()
            }
            .buttonStyle(.borderedProminent)
            .font(.title)

            Spacer()
        }

    }
}

every single time i run it, i get " Query encountered an error: Error Domain=NSCocoaErrorDomain Code=256 "The file “default.store” couldn’t be opened." " in the console.

And when I press done on the sheet, i get the same error.

Thank you for helping

1      

The issue appears to lay in the Query for DefaultHaptic:

  @Query/*(sort: \DefaultHaptic.dateMade)*/ var defaultHapticArray: [DefaultHaptic]

you didn't provide code for this model so when trying to recreate your issue I temporarily disabled it.

With it disabled, and with the content view as shown below, I was unable to recreate the issue you've identified in a simulator.

import SwiftUI
import SwiftData

struct ContentView: View {
    var body: some View {
        LibraryView()
    }
}

If you share the additional model details I'm happy to try and reproduce it again.

Hope this at least gives you some direction in the meantime.

2      

It's just a normal SwiftData as far as i know:

WindowGroup {

            TabView {
                LibraryView()
                    .tabItem {
                        Label("Library", image: "custom.waveform.rectangle.stack")
                    }
                ContentView()
                    .tabItem {
                        Label("Default", image: "custom.waveform.badge.ellipsis")
                    }
                CustomHapticView()
                    .tabItem {
                        Label("Custom", image: "custom.waveform.badge.gearshape.fill")
                    }

            }

        }
        .modelContainer(for: CustomHaptic.self)
        .modelContainer(for: DefaultHaptic.self)

1      

I also changed a few things:

NewCustomHaptic.swift

import SwiftUI
import SwiftData

struct NewCustomHaptic: View {

    @Environment(\.dismiss) var dismiss

    @Environment(\.modelContext) var modelContext
    @Query(sort: \CustomHaptic.dateMade) var customHapticArray: [CustomHaptic]

    @Binding var tempCustomHaptic: CustomHaptic

    @State var sharpness: Float = 1
    @State var intensity: Float = 1
    @State var repeats: Int = 3

    let array0to1: [Float] = [0.2, 0.4, 0.6, 0.8, 1.0]

    var body: some View {
        VStack {
            Form {
                Section("Sharpness") {
                    Picker(selection: $sharpness, label: Label("Sharpness", systemImage: "bolt.horizontal")) {
                        ForEach(array0to1, id: \.self) { i in
                            Text("\(Int(i * 10))")

                        }

                    }

                    .pickerStyle(.segmented)

                }

                Section("Intensity") {
                    Picker(selection: $intensity, label: Label("Intensity", systemImage: "42.circle")) {
                        ForEach(array0to1, id: \.self) { i in
                            Text("\(Int(i * 10))")

                        }

                    }
                    .pickerStyle(.segmented)

                }

                Section("Repeats") {
                    Stepper(value: $repeats, in: 1...10) {
                        Label("\(repeats)", systemImage: "repeat")
                    }
                }
            }

            Button("Done") {

                let newCustomHaptic = CustomHaptic(repeats: repeats, sharpness: sharpness, intensity: intensity)
                modelContext.insert(newCustomHaptic)

                dismiss()
            }
            .buttonStyle(.borderedProminent)
            .font(.title)

            Spacer()
        }

    }
}

and

LibraryView.swift

import SwiftUI
import SwiftData

struct LibraryView: View {

    @Environment(\.modelContext) var modelContext
    @Query(sort: \CustomHaptic.dateMade) var customHapticArray: [CustomHaptic]
    @Query(sort: \DefaultHaptic.dateMade) var defaultHapticArray: [DefaultHaptic]

    @State private var showingAddCustomHaptic = false
    @State private var showingAddDefaultHaptic = false

    @State var temporaryCustomHaptic = CustomHaptic(repeats: 3, sharpness: 0.4, intensity: 0.6)

    var body: some View {
        NavigationStack {
            VStack {
                List {
                    ForEach(customHapticArray, id: \.id) { customHaptic in
                        HStack {
                            VStack {
                                Text("\(customHaptic.sharpness)")
                                Text("")
                                Text("\(customHaptic.intensity)")
                            }

                            Spacer()

                            VStack {
                                Text("\(customHaptic.repeats)")
                            }
                        }
                    }
                }
            }
            .sheet(isPresented: $showingAddCustomHaptic, content: {
                NewCustomHaptic(tempCustomHaptic: $temporaryCustomHaptic)

            })
            .toolbar {
                Button("New Custom Haptic", systemImage: "plus") {

                    showingAddCustomHaptic = true

                    modelContext.insert(temporaryCustomHaptic)

                    temporaryCustomHaptic = CustomHaptic(repeats: 3, sharpness: 0.4, intensity: 0.6)
                }
            }
            .navigationTitle("Haptikiser")
        }
    }
}

I basically changed logic to make a new variable of the class, pass it in as a @Binding, then take it back and insert that in to the model.

However upon running on a real iPhone, the console said "SwiftData/ModelContainer.swift:144: Fatal error: failed to find a currently active container for CustomHaptic"

This issue seems fixable.

Apart from this, are there any better ways to use SwiftData?

1      

your new issue is likely from the code in your tab view here:

 .modelContainer(for: CustomHaptic.self)
        .modelContainer(for: DefaultHaptic.self)

the items should go together in a single instance of modelcontainer

     .modelContainer(for: [CustomHaptic.self, DefaultHaptic.self])

also if you've made any changes to your data model in between running your build on device (simulator or real) it can cause a similar crash.

To avoid it you can use versioning or alternatively delete the app, and therefore any conflicting data, from the device.

2      

Oh wow thank you so much

i literally spent three hours trying to see what was wrong and this was it? i would never have thought that.

Thank you

1      

happy to hear it worked!

I'm new to swift/coding in general so I've done similar and spent hours troubleshooting only to discover a hidden error in one line of seemingly inconsequential code. Done it a lot of this while learning SwiftData these past few months 😅

Happy coding!

1      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.