Terminating app due to uncaught exception 'NSInvalidArgumentException', only happens in iOS 16 and not older versions

Viewed 44

I'm getting the debug console error:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Language name]: unrecognized selector sent to instance 0x11c6f8920'

but only when running app in iOS 16, iOS 15.7 does not crash.

Something in my code was acceptable pre iOS 16, and it's not acceptable in iOS 16.

The line the crash happens on is:

Button(language.name ?? "", action: {

Here is the relevant code:

import SwiftUI
import Foundation
import CoreData

struct CategoriesRevisionView: View {

@State private var selectedLanguage: String = ""
@State private var selectedLanguageSection: String = ""
@State var languagesWithSectionThingHomework: [Language] = []
    
@FetchRequest(entity: Language.entity(), sortDescriptors: []) var languages: FetchedResults<Language>
@FetchRequest(entity: LanguageSection.entity(), sortDescriptors: []) var languageSections: FetchedResults<LanguageSection>
@FetchRequest(entity: SectionThing.entity(), sortDescriptors: [NSSortDescriptor(key: "native", ascending: true)]) var sectionThings: FetchedResults<SectionThing>
@FetchRequest(entity: CommonWordThing.entity(), sortDescriptors: []) var commonWords: FetchedResults<CommonWordThing>

let tintColour = TintColour()

var revisionThings: [SectionThing] {
    if self.selectedLanguageSection == "" {
        return sectionThings.filter{ $0.setAsRevision == true && $0.languageSection?.language?.name == selectedLanguage }
    } else {
        return sectionThings.filter{ $0.setAsRevision == true && $0.languageSection?.name == selectedLanguageSection && $0.languageSection?.language?.name == selectedLanguage}
    }
}

var languagesToAddHomework: [Language] {
    var languagesWithoutHomework: [Language] = []

    for languageSection in languageSections {
        if languageSection.setAsRevision == false {
            if !languagesWithoutHomework.contains(languageSection.language ?? Language()) {
                languagesWithoutHomework.append(languageSection.language ?? Language())
            }
        }
    }
    return languagesWithoutHomework
}

var languagesToRemoveHomework: [Language] {
    var languagesWithHomework: [Language] = []

    for languageSection in languageSections {
        if languageSection.setAsRevision == true {
            if !languagesWithHomework.contains(languageSection.language ?? Language()) {
                languagesWithHomework.append(languageSection.language ?? Language())
            }
        }
    }
    return languagesWithHomework
}

var languageSectionsToAddHomework: [LanguageSection] {
    var languageSectionsWithoutHomework: [LanguageSection] = []
    
    for languageSection in languageSections {
        if languageSection.setAsRevision == false {
            if !languageSectionsWithoutHomework.contains(languageSection) {
                languageSectionsWithoutHomework.append(languageSection)
            }
        }
    }
    
    return languageSectionsWithoutHomework
}

var languageSectionsToRemoveHomework: [LanguageSection] {
    var languageSectionsWithHomework: [LanguageSection] = []
    
    for languageSection in languageSections {
        if languageSection.setAsRevision == true {
            if !languageSectionsWithHomework.contains(languageSection) {
                languageSectionsWithHomework.append(languageSection)
            }
        }
    }
    
    return languageSectionsWithHomework
}

var languageCategories: [LanguageSection] {
    return languageSections.filter { $0.setAsRevision == true }
}

var body: some View {
    List {
        ForEach(revisionThings ?? [], id: \.self) { revisionThing in
            ThingRowView(thing: revisionThing, commonWords: Array(commonWords), resizedImage: UIImage())
            .swipeActions(edge: .trailing, allowsFullSwipe: false) {
                Button {
                    setRevision.unsetFilteredHomeworkThingRevision(sectionThings: [revisionThing], languageSections: Array(languageSections), commonWordThings: Array(commonWords))
                    computeLanguagesWithSectionHomework()
                    selectLanguageAndSection()
                    
                    PersistenceController.shared.saveDB()
                    dataSetIsEmpty()
                } label: {
                    Image("removeHomework")
                }
                .tint(tintColour.SetRevisionSectionThing(sectionThing: revisionThing))
            }
        }
    }
    .listStyle(InsetGroupedListStyle())
    .background(Color.init(.systemGroupedBackground))
    .navigationBarTitle("Revision", displayMode: .inline).opacity(0.8)
    .toolbar {
        ToolbarItemGroup(placement: .navigationBarLeading) {
            Menu {
                ForEach(languagesWithSectionThingHomework, id: \.self) { language in
                    Button("\(language.name ?? "")", action: {
                        self.selectedLanguage = language.name ?? ""
                        self.selectedLanguageSection = ""
                   })
                    Menu("Categories") {
                        ForEach(languageCategories, id: \.self) { languageSection in
                            if languageSection.language == language {
                                Button("\(languageSection.name ?? "")", action: {
                                    self.selectedLanguage = language.name ?? ""
                                    self.selectedLanguageSection = languageSection.name ?? ""
                                })
                            }
                        }
                    }
                    Divider()
                }
            } label: {
                if languageSections.filter{ $0.setAsRevision == true }.count <= 1 {
                    Label("Choose Homework Language", image: "menu")
                } else {
                    Label("Choose Homework Language", image: "menu").foregroundColor(Color.systemBlue)
                }
            }
            .disabled(languageSections.filter{ $0.setAsRevision == true }.count <= 1)
            
            Menu {
                ForEach(languagesToAddHomework, id: \.self) { language in
                    Button(language.name ?? "", action: {
                        setRevision.setSectionThingRevision(sectionThings: sectionThings.filter { $0.languageSection?.language == language }, commonWordThings: Array(commonWords), languageSections: Array(languageSections))
                        computeLanguagesWithSectionHomework()
                        self.selectedLanguage = language.name ?? ""
                        self.selectedLanguageSection = ""
                    })
                    Menu("Categories") {
                        ForEach(languageSectionsToAddHomework.filter { $0.language == language }, id: \.self) { languageSection in
                            Button(languageSection.name ?? "", action: {
                                setRevision.setSectionThingRevision(sectionThings: sectionThings.filter { $0.languageSection?.language == language && $0.languageSection == languageSection }, commonWordThings: Array(commonWords), languageSections: Array(languageSections))
                                computeLanguagesWithSectionHomework()
                                self.selectedLanguage = language.name ?? ""
                                self.selectedLanguageSection = languageSection.name ?? ""
                            })
                        }
                    }
                    Divider()
                }
            } label: {
                if sectionThings.filter{ $0.setAsRevision == true }.count == sectionThings.count {
                    Image("revisionAdd")
                } else {
                    Image("revisionAdd").foregroundColor(.green)
                }
            }
            .disabled(sectionThings.filter{ $0.setAsRevision == true }.count == sectionThings.count)
            
            Menu {
                ForEach(languagesToRemoveHomework, id: \.self) { language in
                    Button(language.name ?? "", action: {
                        setRevision.unsetFilteredHomeworkThingRevision(sectionThings: sectionThings.filter { $0.languageSection?.language == language }, languageSections: Array(languageSections), commonWordThings: Array(commonWords))
                        
                        computeLanguagesWithSectionHomework()
                        selectLanguageAndSection()
                        dataSetIsEmpty()
                    })
                    Menu("Categories") {
                        ForEach(languageSectionsToRemoveHomework.filter { $0.language == language }, id: \.self) { languageSection in
                            Button(languageSection.name ?? "", action: {
                                setRevision.unsetFilteredHomeworkThingRevision(sectionThings: languageSection.sectionThing?.allObjects as? [SectionThing] ?? [], languageSections: Array(languageSections), commonWordThings: Array(commonWords))
                                
                                computeLanguagesWithSectionHomework()
                                selectLanguageAndSection()
                                dataSetIsEmpty()
                            })
                        }
                    }
                    Divider()
                }
            } label: {
                if sectionThings.filter{ $0.setAsRevision == true }.count == 0 {
                    Image("revisionRemove")
                } else {
                    Image("revisionRemove").foregroundColor(.yellow)
                }
            }
            .disabled(sectionThings.filter{ $0.setAsRevision == true }.count == 0)
        }
    }
    .onAppear(perform: initialize)
}

func initialize() {
outerloop: for language in languages {
        if let languageSections = language.languageSection?.allObjects as? [LanguageSection] {
            for languageSection in languageSections {
                if let languageSectionThings = languageSection.sectionThing?.allObjects as? [SectionThing] {
                    if languageSectionThings.filter({ $0.setAsRevision == true }).count > 0 {
                        self.selectedLanguage = language.name ?? ""
                        self.selectedLanguageSection = languageSection.name ?? ""
                        break outerloop
                    }
                }
            }
        }
    }
    
    dataSetIsEmpty()
    
    computeLanguagesWithSectionHomework()
}

func computeLanguagesWithSectionHomework() {
    var sectionThingLanguages: [Language] = []
    
    for language in languages {
        if languageSections.filter({ $0.language == language && $0.setAsRevision == true }).count > 0 {
            if !sectionThingLanguages.contains(language) {
                sectionThingLanguages.append(language)
            }
        }
    }
    
    self.languagesWithSectionThingHomework = sectionThingLanguages
}

func selectLanguageAndSection() {
    if revisionThings?.count == 0 {
        if languageSections.filter({ $0.sectionThing?.allObjects.count ?? 0 > 0 && $0.setAsRevision == true }).count > 0 {
            selectedLanguageSection = languageSections.filter{ $0.sectionThing?.allObjects.count ?? 0 > 0 && $0.setAsRevision == true }[0].name ?? ""
            selectedLanguage = languageSections.filter{ $0.sectionThing?.allObjects.count ?? 0 > 0 && $0.setAsRevision == true }[0].language?.name ?? ""
        }
    }
}

}

0 Answers
Related