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 ?? ""
}
}
}
}