jjatie
jjatie

Reputation: 5332

Swift Managed Object Context Save failure

Simple app starts with a table view in a navigation controller with an add button. Add button brings a new view with text fields, clicking save brings you back to the (updated) table view. My problem is when I try to save the MOC, nothing happens and the app crashes to this in the debugger:

First name is: John
Last name is: Doe
Phone number is: 123456789
Before Save
(lldb) 

and (**** is the line it crashes on)

libswiftCore.dylib`swift_dynamicCastClassUnconditional:
0x10c385860:  pushq  %rbp
0x10c385861:  movq   %rsp, %rbp
0x10c385864:  testq  %rdi, %rdi
0x10c385867:  je     0x10c38589e               ; swift_dynamicCastClassUnconditional + 62
0x10c385869:  movabsq $-0x7fffffffffffffff, %rax
0x10c385873:  testq  %rax, %rdi
0x10c385876:  jne    0x10c38589e               ; swift_dynamicCastClassUnconditional + 62
0x10c385878:  leaq   0xb52e9(%rip), %rax
0x10c38587f:  movq   (%rax), %rax
0x10c385882:  andq   (%rdi), %rax
0x10c385885:  nopw   %cs:(%rax,%rax)
0x10c385890:  cmpq   %rsi, %rax
0x10c385893:  je     0x10c3858ad               ; swift_dynamicCastClassUnconditional + 77
0x10c385895:  movq   0x8(%rax), %rax
0x10c385899:  testq  %rax, %rax
0x10c38589c:  jne    0x10c385890               ; swift_dynamicCastClassUnconditional + 48
0x10c38589e:  leaq   0x36b7d(%rip), %rax       ; "Swift dynamic cast failed"
0x10c3858a5:  movq   %rax, 0xb4c0c(%rip)       ; gCRAnnotations + 8
0x10c3858ac:  int3   
****0x10c3858ad:  movq   %rdi, %rax
0x10c3858b0:  popq   %rbp
0x10c3858b1:  retq   
0x10c3858b2:  nopw   %cs:(%rax,%rax)

Here is my save function:

    @IBAction func save() {

    if let moc = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext {

        employee = NSEntityDescription.insertNewObjectForEntityForName("Employee", inManagedObjectContext: moc) as Employee
        contact = NSEntityDescription.insertNewObjectForEntityForName("Contact", inManagedObjectContext: moc) as Contact
        employee.contact = contact

        //println("First name is: " + employee.contact.firstName)
        employee.contact.firstName = firstNameTextField.text
        println("First name is: " + employee.contact.firstName)

        employee.contact.lastName = lastNameTextField.text
        println("Last name is: " + employee.contact.lastName)

        employee.contact.phoneNumber = phoneNumberTextField.text
        println("Phone number is: " + employee.contact.phoneNumber)

        var e: NSError?
        println("Before Save")
        if moc.save(&e) != true {
            println("After Save")
            println("insert error: \(e!.localizedDescription)")
            return
        }
        println("After Save")

    // Execute the unwind segue and go back to the home screen
    performSegueWithIdentifier("unwindToHomeScreen", sender: self)

}

UPDATE

Employee Class:

import Foundation
import CoreData

class Employee: NSManagedObject {

    @NSManaged var wage: NSNumber
    @NSManaged var socialInsuranceNumber: NSNumber
    @NSManaged var contact: Contact

}

Contact class:

import Foundation
import CoreData

class Contact: NSManagedObject {

    @NSManaged var firstName: String
    @NSManaged var lastName: String
    @NSManaged var phoneNumber: String
    @NSManaged var employee: NSManagedObject

}

Upvotes: 2

Views: 2488

Answers (2)

Imanou Petit
Imanou Petit

Reputation: 92419

I was able to reproduce your error message. You get this message because you didn't set correctly your entity class name in the Core Data Model Editor.

Define your entity class name fields in the Core Data Model Editor as <MyAppName>.Employee and <MyAppName>.Contact.

See this previous answer for more details. You can also learn more about Core Data and namespaces here.

Upvotes: 3

Christian
Christian

Reputation: 22343

You can't cast an NSManagedObject to your class.

You have to do it like that:

 employee = NSEntityDescription.insertNewObjectForEntityForName("Employee", inManagedObjectContext: moc) as NSManagedObject

Then, you can access the attributes with the valueForKey-method.

Also you could make a NSManagedObject-class. That way it would be possible to cast it to this class.

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@interface Employee: NSManagedObject

@property (nonatomic, retain) NSString* firstName;
@property (nonatomic, retain) NSString* lastName;
@property (nonatomic, retain) NSString* phoneNumber;

@end

Access:

 employee = NSEntityDescription.insertNewObjectForEntityForName("Employee", inManagedObjectContext: moc) as Employee

Upvotes: 0

Related Questions