SwiftData delete isn't working, when I attempt to delete a model, my app crashes and I get the following error:
SwiftData/PersistentModel.swift:359: Fatal error: Cannot remove My_App.Model2 from relationship Relationship - name: model2, options: [], valueType: Model2, destination: Model2, inverseName: models3, inverseKeypath: Optional(\Model2.models3) on My_App.Model3 because an appropriate default value is not configured.
I get that it's saying I don't have a default value, but why do I need one? Isn't @Relationship .cascade automatically deleting the associated models?
And onto of that, why is the error occurring within the do block, shouldn't it be caught by the catch, and printed?
I have put together a sample project below.
import SwiftUI
import SwiftData
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.modelContainer(for: Model3.self)
}
}
}
@Model
class Model1 {
var name: String
@Relationship(deleteRule: .cascade, inverse: \Model2.model1) var models2: [Model2] = []
init(name: String) {
self.name = name
}
}
@Model
class Model2 {
var name: String
var model1: Model1
@Relationship(deleteRule: .cascade, inverse: \Model3.model2) var models3: [Model3] = []
init(name: String, model1: Model1) {
self.name = name
self.model1 = model1
}
}
@Model
class Model3 {
var name: String
var model2: Model2
init(name: String, model2: Model2) {
self.name = name
self.model2 = model2
}
}
struct ContentView: View {
@Query var models1: [Model1]
@Environment(\.modelContext) var modelContext
var body: some View {
NavigationStack {
List(models1) { model1 in
Text(model1.name)
.swipeActions {
Button("Delete", systemImage: "trash", role: .destructive) {
modelContext.delete(model1)
do {
try modelContext.save()
//SwiftData/PersistentModel.swift:359: Fatal error: Cannot remove My_App.Model2 from relationship Relationship - name: model2, options: [], valueType: Model2, destination: Model2, inverseName: models3, inverseKeypath: Optional(\Model2.models3) on My_App.Model3 because an appropriate default value is not configured.
} catch {
print(error.localizedDescription)
}
}
}
}
.toolbar {
Button("Insert", systemImage: "plus") {
modelContext.insert(Model3(name: "model3", model2: Model2(name: "model2", model1: Model1(name: "model1"))))
}
}
}
}
}
Post
Replies
Boosts
Views
Activity
I get the following fatal error when the user clicks Save in AddProductionView.
Fatal error: Duplicate keys of type 'AnyHashable' were found in a Dictionary. This usually means either that the type violates Hashable's requirements, or that members of such a dictionary were mutated after insertion.
As far as I’m aware, SwiftData automatically makes its models conform to Hashable, so this shouldn’t be a problem.
I think it has something to do with the picker, but for the life of me I can’t see what.
This error occurs about 75% of the time when Save is clicked.
I'm using Xcode 16.2 and iPhone SE 2nd Gen. Any help would be greatly appreciated…
Here is my code:
import SwiftUI
import SwiftData
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.modelContainer(for: Character.self, isAutosaveEnabled: false)
}
}
}
@Model
final class Character {
var name: String
var production: Production
var myCharacter: Bool
init(name: String, production: Production, myCharacter: Bool = false) {
self.name = name
self.production = production
self.myCharacter = myCharacter
}
}
@Model
final class Production {
var name: String
init(name: String) {
self.name = name
}
}
struct ContentView: View {
@State private var showingSheet = false
var body: some View {
Button("Add", systemImage: "plus") {
showingSheet.toggle()
}
.sheet(isPresented: $showingSheet) {
AddProductionView()
}
}
}
struct AddProductionView: View {
@Environment(\.dismiss) private var dismiss
@Environment(\.modelContext) var modelContext
@State var production = Production(name: "")
@Query var characters: [Character]
@State private var characterName: String = ""
@State private var selectedCharacter: Character?
var filteredCharacters: [Character] {
characters.filter { $0.production == production }
}
var body: some View {
NavigationStack {
Form {
Section("Details") {
TextField("Title", text: $production.name)
}
Section("Characters") {
List(filteredCharacters) { character in
Text(character.name)
}
HStack {
TextField("Character", text: $characterName)
Button("Add") {
let newCharacter = Character(name: characterName, production: production)
modelContext.insert(newCharacter)
characterName = ""
}
.disabled(characterName.isEmpty)
}
if !filteredCharacters.isEmpty {
Picker("Select your role", selection: $selectedCharacter) {
Text("Select")
.tag(nil as Character?)
ForEach(filteredCharacters) { character in
Text(character.name)
.tag(character as Character?)
}
}
.pickerStyle(.menu)
}
}
}
.toolbar {
Button("Save") { //Fatal error: Duplicate keys of type 'AnyHashable' were found in a Dictionary. This usually means either that the type violates Hashable's requirements, or that members of such a dictionary were mutated after insertion.
if let selectedCharacter = selectedCharacter {
selectedCharacter.myCharacter = true
}
modelContext.insert(production)
do {
try modelContext.save()
} catch {
print("Failed to save context: \(error)")
}
dismiss()
}
.disabled(production.name.isEmpty || selectedCharacter == nil)
}
}
}
}
So I only recently uncovered the Contacts Framework through this video: https://youtu.be/sHKir2ZMk5Q. As such I'm not yet accustomed to the API. Basically my main problem is that I can't seem to find a way to access the name of the group a CNContact is in. The only support I can find is in Apple's own documentation, which isn't very helpful.
if someone could point me in the right direction towards how to print the group name, I would be very grateful.
My code is below,
Cheers
// ModelData.swift
// B-Day
import Foundation
import Contacts
import SwiftUI
struct Contact: Identifiable {
let id = UUID()
let category: String
let firstName: String
let lastName: String
let birthday: DateComponents?
}
func fetchAllContacts() async -> [Contact] {
var contacts = [Contact]()
let store = CNContactStore()
let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactBirthdayKey, CNContactIdentifierKey, CNGroupNameKey] as [CNKeyDescriptor]
let fetchRequest = CNContactFetchRequest (keysToFetch: keys)
do {
try store.enumerateContacts(with: fetchRequest, usingBlock: { contact, result in
//this should print the name of the contact's group
print(contact.groupName)
contacts.append(Contact(category: contact.groupName, firstName: contact.givenName, lastName: contact.familyName, birthday: contact.birthday))
})
}
catch {
print("Error")
}
return contacts
}
Hi All,
I'm quite new to swift and am wondering why I am receiving a "Trailing closure passed to parameter of type 'Visibility' that does not accept a closure"
error on the .toolbar{ line
I Have Supplied My Code Below
Thanks in Advance,
Josh
struct HomeView: View {
var body: some View {
Text("Home")
.toolbar{
ToolbarItem(placement: .navigationBarLeading)
Button(action: NavigationLink(destination: AccountView()), label: Image(systemName: "gearshape"))
ToolbarItem(placement: .principal) { Text("Welcome").font(.title)
}
ToolbarItem(placement: .navigationBarTrailing)
Button(action: NavigationLink(destination: AccountView()), label: Image(systemName: "person.circle"))
}
.navigationBarTitleDisplayMode(.inline)
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}```