8

When I run the following code:

    let saveAction = UIAlertAction(title: "Save",
                                   style: .default) {
    [unowned self] action in
    guard let textField = alert.textFields?.first,
    let mapName = textField.text else {
    return
    }
    var newCoordinate = NSEntityDescription.insertNewObject(forEntityName: "Coordinates", into: managedObjectContext)

    var newMap = NSEntityDescription.insertNewObject(forEntityName: "MapNames", into: managedObjectContext)

    newCoordinate.setValue(23, forKey: "latitude")
    newCoordinate.setValue(21, forKey: "longitude")
    newMap.setValue(mapName, forKey: "mapname")

    do
    {
    try self.appDelegate.saveContext()
    print("SAVED")
    }
    catch
    {
    }

    var request = NSFetchRequest<NSFetchRequestResult>(entityName: "Coordinates")
    request.returnsObjectsAsFaults = false

    do
    {
    var results = try managedObjectContext.fetch(request)

        if results.count > 0 {
        for result in results as! [NSManagedObject]
        {
            if let latitude = result.value(forKey: "latitude") as? Double
            {
            print(latitude)
            }
            if let longitude = result.value(forKey: "longitude") as? Double{
            print(longitude)}
            if let map = result.value(forKey: "mapname") as? String {
            print(map)}

        }
    }
    }
    catch
    {
    }

I get the following error:

Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ valueForUndefinedKey:]: the entity Coordinates is not key value coding-compliant for the key "mapname".'

This is weird because I do have an attribute called mapname, although it is in the MapNames entity. The error says Coordinates, why is that?

Is that because it is not possible to have 2 references to managedObjectContext in the same scope? How could I insert values to different entities then?

1
  • if let map = result.value(forKey: "mapname") as? String is obviously trying to read property mapname on an instance of Coordinates because that's what your request is fetching. That should be obvious if you applied the generic types correctly. Your request should be NSFetchRequest<Coordinate>. Commented Apr 8, 2017 at 12:40

2 Answers 2

5

There is no problem with your insertion code. However, let's look at your fetching code:

var request = NSFetchRequest<NSFetchRequestResult>(entityName: "Coordinates")

Here you are creating a request to fetch coordinates.

On the result of that request (which is a Coordinates) you are calling:

if let map = result.value(forKey: "mapname") as? String {
   print(map)
}

which is obviously incorrect.

Ideally, instead of using the dangerous KVC, you should use the Coordinates subclass of NSManagedObject and directly use the properties:

var request = NSFetchRequest<Coordinates>(entityName: "Coordinates")

... 

for result in results as! [Coordinates] {
   print(result.latitude)
   print(result.longitude)
}
Sign up to request clarification or add additional context in comments.

Comments

5

I got this same error after upgrading to Swift 4.

I had to add @objcMembers to my Entity class (or @objc to each property of the class).

1 Comment

I got the same error and used the below code to get it working in sectionNameKeyPath. @objc public var modifiedMonth: String? { return modified?.monthMedium }

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.