2

In Xcode, when I create a new file extends NSManagedObjectContext class, add methods in this extension file, compile the project and there is no problem.

NSManagedObjectContext+BaseModel.swift

import Foundation
import CoreData
import CoreDataStack

extension NSManagedObjectContext {

    public func insertObject<T: NSManagedObject>() -> T {
        guard let object = NSEntityDescription.insertNewObjectForEntityForName(T.modelName(), inManagedObjectContext: self) as? T
        else {
                fatalError("Invalid Core Data Model")
        }

        return object
    }

}

However, when I use it in the ViewController.swift, like context.insertObject(), the compiler reports an error saying:

Value of type 'NSManagedObjectContext' has no member 'insertObject'

After searching in StackOverflow, I found a post "Using extensions in separate .swift file". As the post author said, the above problem disappeared when I put the extension NSManagedObjectContext code in my custom CoreDataStack.swift. But why?? Should not extension Apple's class be in a separate file??

Community
  • 1
  • 1
Alfy
  • 889
  • 1
  • 7
  • 17
  • Shouldn't insertObject have a parameter? – Andrew Nov 25 '15 at 04:49
  • @SantaClaus. No. You can replace it with addObject to differentiate it with the Apple's 'insertObject(object:NSManagedObject)'. – Alfy Nov 25 '15 at 05:25
  • I cannot reproduce the problem, your extension (in a separate Swift file) works just fine for me. Perhaps the "Target Membership" checkbox is not set for the file? – Martin R Nov 25 '15 at 07:04
  • @MartinR, yes, there is no problem not using the extension function. You can test it by the following steps: 1. In a ViewController.swift declare a variable `let context: NSManagedObjectContext!` 2. Then call the extension method defined in the extension file `context.insertObject()` Compile the project, Xcode will report an error this time. – Alfy Nov 25 '15 at 07:27
  • That is essentially what I did: `let context = self.managedObjectContext` followed by `let e : Event = context.insertObject()`. `Event` is the Core Data entity. Compiles, runs and works as expected. – Martin R Nov 25 '15 at 07:50
  • ⊙﹏⊙b汗...that is impossible...do you copy the code I paste above in your NSManagedObjectContext extension separate file? (╯-╰)/ – Alfy Nov 25 '15 at 08:04
  • Yes, I did. To make it compile in a boilerplate Core Data app, I removed the `import CoreDataStack` statement and replaced `T.modelName()` by `String(T)`. – Martin R Nov 25 '15 at 08:20
  • (Unrelated to your concrete problem here, but you might be interested in http://stackoverflow.com/questions/27109268/how-can-i-create-instances-of-managed-object-subclasses-in-a-nsmanagedobject-swi, where generic extension methods of `NSManagedObject` are shown to create instances.) – Martin R Nov 25 '15 at 08:23
  • Is it convenient to share your test code? My code is our company's project, so it is not convenient to share...<( ̄▽ ̄)> Thanks in advance for your warm-heartedness. – Alfy Nov 25 '15 at 08:27
  • I have just created a standard Master-Detail Application in Xcode (with Core Data selected), and then added your code with the modifications mentioned in above comments ... – Martin R Nov 25 '15 at 08:31
  • yeah, I understand what you mean. Thank you sincerely!Just now I searched the Google and found [an article](https://www.andrewcbancroft.com/2015/04/22/3-nuances-of-swift-extensions/), and I suspected whether it was the access control of my extension ? – Alfy Nov 25 '15 at 08:39

0 Answers0