Search code examples
swiftswiftuicore-data

Accessing CoreData Attribute causes Unrecognized selector sent to instance


I have a project where CoreData stores the user info on-device. The problem is that whenever I try to retrieve an attribute, it sends me an error. It only crashes whenever I access fName in the SwiftUI View, everything and everywhere else works. I have tested and can confirm that the student object from the ForEach does in-fact contain the fName variable/attribute.

How do I fix it so I can access from the View.

Here is my code and CoreData and everything else below. I apologize if the solution if somewhat obvious, but this is my first time using CoreData.

The error message

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Student fName]: unrecognized selector sent to instance 0x60000211b200'
*** First throw call stack:
(
    0   CoreFoundation                      0x00000001804ae0f8 __exceptionPreprocess + 172
    1   libobjc.A.dylib                     0x0000000180087db4 objc_exception_throw + 56
    2   CoreFoundation                      0x00000001804c2f48 +[NSObject(NSObject) instanceMethodSignatureForSelector:] + 0
    3   CoreFoundation                      0x00000001804b2248 ___forwarding___ + 1280
    4   CoreFoundation                      0x00000001804b456c _CF_forwarding_prep_0 + 92
    5   now                                 0x0000000102cb2c68 $s3now9GradeRootV4bodyQrvg7SwiftUI9TupleViewVyAE0H0PAEE7opacityyQrSdFQOyAiEE6zIndexyQrSdFQOyAE6VStackVyAE19_ConditionalContentVyAGyAE6SpacerV_AiEE10fontWeightyQrAE4FontV0P0VSgFQOyAiEE0O0yQrATSgFQ  6   SwiftUI                             0x00000001cc750988 OUTLINED_FUNCTION_169 + 72
    7   now                                 0x0000000102cb2598 $s3now9GradeRootV4bodyQrvg7SwiftUI9TupleViewVyAE0H0PAEE7opacityyQrSdFQOyAiEE6zIndexyQrSdFQOyAE6VStackVyAE19_ConditionalContentVyAGyAE6SpacerV_AiEE10fontWeightyQrAE4FontV0P0VSgFQOyAiEE0O0yQrATSgFQ  8   SwiftUI                             0x00000001cc750988 OUTLINED_FUNCTION_169 + 72
    9   now                                 0x0000000102cb2008 $s3now9GradeRootV4bodyQrvg7SwiftUI9TupleViewVyAE0H0PAEE7opacityyQrSdFQOyAiEE6zIndexyQrSdFQOyAE6VStackVyAE19_ConditionalContentVyAGyAE6SpacerV_AiEE10fontWeightyQrAE4FontV0P0VSgFQOyAiEE0O0yQrATSgFQ  10  SwiftUI                             0x00000001cd049cf8 OUTLINED_FUNCTION_30 + 14540
    11  SwiftUI                             0x00000001cd051ed0 OUTLINED_FUNCTION_30 + 47780
    12  SwiftUI                             0x00000001cc9bd2d0 OUTLINED_FUNCTION_76 + 84
    13  SwiftUI                             0x00000001cd051eec OUTLINED_FUNCTION_30 + 47808
    14  libswiftCore.dylib                  0x00000001930e4f48 $ss17withUnsafePointer2to_q_xz_q_SPyxGKXEtKr0_lF + 20
    15  libswiftCore.dylib                  0x000000019328c3a8 $ss24withUnsafeMutablePointer2to_q_xz_q_SpyxGKXEtKr0_lF + 12
    16  SwiftUI                             0x00000001cd049428 OUTLINED_FUNCTION_30 + 12284
    17  SwiftUI                             0x00000001cd04b180 OUTLINED_FUNCTION_30 + 19796
    18  SwiftUI                             0x00000001cd04c5dc OUTLINED_FUNCTION_30 + 25008
    19  SwiftUI                             0x00000001cd04fd84 OUTLINED_FUNCTION_30 + 39256
    20  SwiftUI                             0x00000001cd05014c OUTLINED_FUNCTION_30 + 40224
    21  SwiftUI                             0x00000001cd7602f4 OUTLINED_FUNCTION_2 + 8476
    22  SwiftUI                             0x00000001cd75ee6c OUTLINED_FUNCTION_2 + 3220
    23  SwiftUI                             0x00000001cc484264 OUTLINED_FUNCTION_44 + 832428
    24  SwiftUI                             0x00000001cc48312c OUTLINED_FUNCTION_44 + 828020
    25  SwiftUI                             0x00000001cc610ba8 OUTLINED_FUNCTION_44 + 2456816
    26  AttributeGraph                      0x00000001b9d4f5c4 _ZN2AG5Graph11UpdateStack6updateEv + 504
    27  AttributeGraph                      0x00000001b9d4fd54 _ZN2AG5Graph16update_attributeENS_4data3ptrINS_4NodeEEEj + 432
    28  AttributeGraph                      0x00000001b9d57d2c _ZN2AG5Graph20input_value_ref_slowENS_4data3ptrINS_4NodeEEENS_11AttributeIDEjjPK15AGSwiftMetadataRhl + 716
    29  AttributeGraph                      0x00000001b9d6ee24 AGGraphGetValue + 232
    30  SwiftUI                             0x00000001cc3f12e4 OUTLINED_FUNCTION_44 + 230444
    31  SwiftUI                             0x00000001cc3f16d8 OUTLINED_FUNCTION_44 + 231456
    32  SwiftUI                             0x00000001cc611274 OUTLINED_FUNCTION_44 + 2458556
    33  AttributeGraph                      0x00000001b9d4f5c4 _ZN2AG5Graph11UpdateStack6updateEv + 504
    34  AttributeGraph                      0x00000001b9d4fd54 _ZN2AG5Graph16update_attributeENS_4data3ptrINS_4NodeEEEj + 432
    35  AttributeGraph                      0x00000001b9d57d2c _ZN2AG5Graph20input_value_ref_slowENS_4data3ptrINS_4NodeEEENS_11AttributeIDEjjPK15AGSwiftMetadataRhl + 716
    36  AttributeGraph                      0x00000001b9d6ee24 AGGraphGetValue + 232
    37  SwiftUI                             0x00000001cd6d6b8c OUTLINED_FUNCTION_16 + 21304
    38  SwiftUI                             0x00000001cd6d6c78 OUTLINED_FUNCTION_16 + 21540
    39  SwiftUI                             0x00000001cc61d8e4 OUTLINED_FUNCTION_44 + 2509356
    40  AttributeGraph                      0x00000001b9d4f5c4 _ZN2AG5Graph11UpdateStack6updateEv + 504
    41  AttributeGraph                      0x00000001b9d4fd54 _ZN2AG5Graph16update_attributeENS_4data3ptrINS_4NodeEEEj + 432
    42  AttributeGraph                      0x00000001b9d57b4c _ZN2AG5Graph20input_value_ref_slowENS_4data3ptrINS_4NodeEEENS_11AttributeIDEjjPK15AGSwiftMetadataRhl + 236
    43  AttributeGraph                      0x00000001b9d6ebd0 AGGraphGetInputValue + 244
    44  SwiftUI                             0x00000001cca62abc OUTLINED_FUNCTION_8 + 204
    45  SwiftUI                             0x00000001ccb9b494 OUTLINED_FUNCTION_48 + 1704
    46  SwiftUI                             0x00000001ccb9b8cc OUTLINED_FUNCTION_48 + 2784
    47  SwiftUI                             0x00000001cd60419c OUTLINED_FUNCTION_23 + 6896
    48  SwiftUI                             0x00000001ccb9b4d4 OUTLINED_FUNCTION_48 + 1768
    49  SwiftUI                             0x00000001ccb9b8cc OUTLINED_FUNCTION_48 + 2784
    50  SwiftUI                             0x00000001cd60419c OUTLINED_FUNCTION_23 + 6896
    51  SwiftUI                             0x00000001ccc4da00 OUTLINED_FUNCTION_7 + 3148
    52  SwiftUI                             0x00000001cc4df510 OUTLINED_FUNCTION_44 + 1205848
    53  SwiftUI                             0x00000001cc4de9a4 OUTLINED_FUNCTION_44 + 1202924
    54  SwiftUI                             0x00000001cc630dfc objectdestroy.67Tm + 12676
    55  SwiftUI                             0x00000001cc4e40a8 OUTLINED_FUNCTION_44 + 1225200
    56  SwiftUI                             0x00000001cc3f17e0 OUTLINED_FUNCTION_44 + 231720
    57  SwiftUI                             0x00000001cc611274 OUTLINED_FUNCTION_44 + 2458556
    58  AttributeGraph                      0x00000001b9d4f5c4 _ZN2AG5Graph11UpdateStack6updateEv + 504
    59  AttributeGraph                      0x00000001b9d4fd54 _ZN2AG5Graph16update_attributeENS_4data3ptrINS_4NodeEEEj + 432
    60  AttributeGraph                      0x00000001b9d5d8d0 _ZN2AG8Subgraph6updateEj + 828
    61  SwiftUI                             0x00000001cd42b714 OUTLINED_FUNCTION_0 + 10564
    62  SwiftUI                             0x00000001cd42c960 OUTLINED_FUNCTION_0 + 15248
    63  SwiftUI                             0x00000001ccbfcb4c OUTLINED_FUNCTION_0 + 37912
    64  SwiftUI                             0x00000001cd4d8d74 OUTLINED_FUNCTION_16 + 11040
    65  SwiftUI                             0x00000001cd4d7a10 OUTLINED_FUNCTION_16 + 6076
    66  SwiftUI                             0x00000001ccbf45b8 OUTLINED_FUNCTION_0 + 3716
    67  SwiftUI                             0x00000001cd42c92c OUTLINED_FUNCTION_0 + 15196
    68  SwiftUI                             0x00000001cd42c864 OUTLINED_FUNCTION_0 + 14996
    69  SwiftUI                             0x00000001ccf0b1a8 OUTLINED_FUNCTION_14 + 28
    70  SwiftUI                             0x00000001cc6f50d8 OUTLINED_FUNCTION_2 + 25448
    71  SwiftUI                             0x00000001cc6f5040 OUTLINED_FUNCTION_2 + 25296
    72  SwiftUI                             0x00000001cc6f5160 OUTLINED_FUNCTION_2 + 25584
    73  CoreFoundation                      0x000000018040ddf4 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
    74  CoreFoundation                      0x00000001804087f8 __CFRunLoopDoObservers + 528
    75  CoreFoundation                      0x0000000180408cb0 __CFRunLoopRun + 968
    76  CoreFoundation                      0x00000001804084d4 CFRunLoopRunSpecific + 572
    77  GraphicsServices                    0x000000018ef2aae4 GSEventRunModal + 160
    78  UIKitCore                           0x00000001853d0a28 -[UIApplication _r
libc++abi: terminating due to uncaught exception of type NSException

CoreData CoreDataModel Image

CoreData Manager

class CoreDataManager {
    
    let dataBaseVersion = "1.0.0"
    
    let persistentContainer: NSPersistentContainer
    
    init() {
        persistentContainer = NSPersistentContainer(name: "CoreDataModel")
        persistentContainer.loadPersistentStores { description, error in
            if let error = error {
                fatalError("CoreData init failed. \(error.localizedDescription)")
            }
        }
    }
    
    func getSavedStudents() -> [Student] {
        let fetchRequest: NSFetchRequest<Student> = Student.fetchRequest()
        
        do {
            return try persistentContainer.viewContext.fetch(fetchRequest)
        } catch {
            return []
        }
    }
    
    func updateStudent() {
        saveModel()
    }
    
    func saveStudent(id: String, pass: String) {
        let student = Student(context: persistentContainer.viewContext)
        
        student.fName = ""
        student.id = id
        student.password = pass
        
        student.databaseVersion = dataBaseVersion
        
        student.bioLockEnabled = false
        
        student.isCurrentUser = true
        
        saveModel()
    }
    
    func deleteStudent(student: Student) {
        persistentContainer.viewContext.delete(student)
        
        saveModel()
    }
    
    private func saveModel() {
        do {
            try persistentContainer.viewContext.save()
        } catch {
            persistentContainer.viewContext.rollback()
            print("saveModel() failed with \(error)")
        }
    }
}

My SwiftUI View accessing the fName attribute

HStack {
  ScrollView(.vertical, showsIndicators: false) {
    ForEach(students) { student in
      VStack {
        VStack {
          Text(student.fName ?? "!") //Right here is where I access fName
            .padding()
        }
        .background(.orange)
        .clipShape(Circle())
        .matchedGeometryEffect(id: student.id, in: accountSelectorAnimation)

        Text(student.id ?? "******")
      }
      .padding()
      .clipShape(RoundedRectangle(cornerRadius: 20))
      .background(.green)
    }
  }
  .padding()
  .background(.red)
}
.onAppear {
  populateStudents()
}
.background(.blue)
.padding()

And the array which stores all the students retrieved from CoreData and how the "access point" of CoreData

let coreDataManager: CoreDataManager
@State var students: [Student] = []

which gets loaded by this function

private func populateStudents() {
    students = coreDataManager.getSavedStudents()
}

Solution

  • I think I solved the problem. It was because somehow a non-related variable inside a Task{} bricked a variable from changing which caused my CoreData to go haywire? It was part of my auto-login feature.

    Original code

    @State var currentStudent: Student?
    
    ...
    populateStudents()
    
    for student in students {
      if student.isCurrentUser {
        disableLogin = true
        loggingIn = true
        isNewUser = false
        Task {
          id = student.id!
          pass = student.password!
          currentStudent = student //This line was the problem
          await getSessionToken()
        }
        return
      }
    }
    
    ...
    

    New Code

    @State var currentStudent: Student?
    
    ...
    populateStudents()
    
    for student in students {
      if student.isCurrentUser {
        disableLogin = true
        loggingIn = true
        isNewUser = false
        currentStudent = student //Moved outside of Task and the problem is gone
        Task {
          id = student.id!
          pass = student.password!
          await getSessionToken()
        }
        return
      }
    }
    
    ...
    

    This was the only line in my code I changed. I don't even know how this affected it but after I changed the variable outside of the Task{}, it magically got fixed.

    I want to sincerely apologize if you worked on this problem, but thank you for trying and I am extremely sorry for wasting your time.