10

This is for XCode 6 and Swift...

I'm trying to make a fetch request to the managed object context but it's not returning the correct subclass.

I have already set the subclass in the data model data modeler configuration to the name of my custom subclass and in the code, it is extending the NSManagedObject class.

Any ideas?

enter image description here enter image description here enter image description here

vutran
  • 887
  • 8
  • 19
  • 2
    Please show us some code you tried and the error you get for us to help you! – Jack Jun 06 '14 at 01:55
  • It works for me if I use the "as" keyword: var tasks = managedObjectContext.executeFetchRequest(fetchRequest, error: err) as [Task] – Mark Knopper Oct 08 '14 at 21:37

3 Answers3

23

Just figured out the solution.

I had to add the @objc attribute to allow the class to be compatible with Objective-C.

Now the fetch request is returning a correct result of Tasks[]

import Foundation
import CoreData

@objc(Task) // make compatible with objective-c
class Task : NSManagedObject
{
    @NSManaged var note: String!
    @NSManaged var completed: Bool
}

Reference: https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html#//apple_ref/doc/uid/TP40014216-CH4-XID_36

Cœur
  • 37,241
  • 25
  • 195
  • 267
vutran
  • 887
  • 8
  • 19
  • Oh wow, thank you so much! I had been missing this, and my code _seemed_ to work by subclassing NSManagedObject, but I wasn't ending up with instances of the real class. – anisoptera Jun 06 '14 at 16:55
  • 1
    Importantly, you need the explicit class name in parentheses, rather than just putting `@objc` which I believe is usually OK if you are not sending a different class name to Objective-C. – tobygriffin Jun 10 '14 at 00:04
  • 1
    It works, but the funny part is: *When you define a Swift class that inherits from NSObject or any other Objective-C class, the class is automatically compatible with Objective-C.* That means it should work without it when subclassing `NSManagedObject`, but doesn't. Thanks for giving the hint. – Binarian Jun 25 '14 at 10:01
  • @ViktorLexington I think that's a typo, I've just had the same problem and the class has to inherit from NSManagedObject. vutran, hope this edit is OK. – jrturton Jul 18 '14 at 06:14
8

Using @objc(Task) seems to be working but you could also just edit the data model data modeler configuration to the name ToDoList.Task instead of just Task. That will work too and avoid Class conflicts if Task is used anywhere else in the Objective-C code.

Fabien Penso
  • 341
  • 2
  • 8
  • I don't understand it. Do you mean in the `xcdatamodeld` file the **configuration** tab? There I have a table for every entity. Should I change the name in the column `Entity` or `Class`? – Binarian Jun 25 '14 at 10:07
  • 2
    You should replace the class field as `Project.Object` like `ToDoList.Task`. Swift generate unique classes and it won't find it if you use `Task` only. – Fabien Penso Jun 30 '14 at 15:34
  • 2
    Cool it worked, using the project name is comprehensible since Swift uses Namespaces. This should be the correct answer. – Binarian Jul 18 '14 at 08:54
1

Check to make sure that in the "Entity" inspector (right side of the screen, Utilities pane) when Task is selected in your Model that its Class field is properly filled in with "Task" (it's blank by default).

Ben Gottlieb
  • 85,404
  • 22
  • 176
  • 172
  • Just checked and the "Class" as set to "Task"... Name: Task Class: Task Abstract Entity: unchecked Parent Entity: No Parent Entity – vutran Jun 06 '14 at 04:02