Is it unnecessary to subclass NSManagedObject in Swift 3? - ios

I know previously you would have to "Editor" > "Create NSManagedObject Subclass" in order to reference your Core Data's entity names in your classes. However I'm given several errors after creating these automatic subclasses.
My project runs fine without these subclass files, so does Swift 3 not require subclassing to reference entities anymore?

In Swift 3 you don't need to manually create subclasses for NSManagedObjects.
By default they are created automatically. But if you want manually create files, set Codegen to Manual/None in Utilities area for your testCD.xcdatamodeld.
From Apple's What's new in Core Data:
Xcode automatic subclass generation
Xcode now supports automatic generation of NSManagedObject subclasses in the modeling tool. In the entity inspector:
Manual/None is the default, and previous behavior; in this case you
should implement your own subclass or use NSManagedObject.
Category/Extension generates a class extension in a file named like
ClassName+CoreDataGeneratedProperties. You need to declare/implement
the main class (if in Obj-C, via a header the extension can import
named ClassName.h).
Class Definition generates subclass files named like ClassName+CoreDataClass as well as the files generated for Category/Extension.
The generated files are placed in DerivedData and rebuilt on the first build after the model is saved. They are also indexed by Xcode, so command-clicking on references and fast-opening by filename works.

Related

Adding a method to an Xcode 10 Core Data generated file

This question probably has an answer elsewhere, but I've only found answers for outdated versions of Xcode or projects that use Swift.
I am using Xcode 10 and reading iOS Programming The Big Nerd Ranch Guide, 4th Edition. I am using such an old version because this is the resource that my work provided to me.
Currently I am trying to add a method to a CoreData generated class for Objective-C.
With CodeGen set to Category/Extension with my entity selected in CoreData the generated class files are:
BNRItem+CoreDataProperties.h/m
BNRItem+CoreDataClass.h/m
BNRItem+CoreDataClass.h includes BNRItem+CoreDataProperties.h, and BNRItem+CoreDataProperties.h includes BNRItem.h (which does not exist). I assume that I need to create BNRItem.h but I don't know what file to import into BNRItem.h since either BNRItem+CoreDataProperties.h or BNRItem+CoreDataClass.h would seem to create a circular include cycle.
In which file do I add an instance method to a CoreData generated class for Objective-C in Xcode 10?
The convention is to use #class in the .h file and #import in the .m file, except when #import is necessary in the .h file. The latter occurs when referring to a superclass or protocol.
The idea is to speed up recompiles. If ClassA.h imports ClassB.m, and you change only ClassB.m during development, then because ClassA.m imports ClassA.h which imports ClassB.m, ClassA.m will need to be recompiled during the next build, even though it is unchanged.
Of course, all of this goes away in Swift :)
This is likely not the actual answer, but I fixed this by changing the CodeGen to Manual/None and editing the files that it generated.
What about leaving the code generation option to Class Definition and create an extension (a category in Objective-C) of your entity?
The #import statement was introduced to resolve the cyclic dependencies created by #include.
So it doesn’t matter much if you are using #import, but if you’re still concerned you can also use #class forward declaration
This has always been my struggle, but just now I ran into this Apple article.
The second way, is the way you are trying to use. The unexpected step is to move the properties file to the trash. And actually it seems the <class>+CoreDataClass files have to be renamed to just <class>.h and .m. After that you can use those files to extend your class and the property files keep being generated.
So the steps to create your managed object class are:
Choose Category/Extension in the data model inspector for your entity.
Generate your class with the Editor > Create NSManagedObject Subclass... menu.
Move the created <class>+CoreDataProperties.h and .m files.
Additional step: rename the data class files as just described.

Custom methods for CoreData classes

I'm trying to conform to the MVC paradigm in my iOS app. My model consists of entities stored in coreData which I have set up using the xcdatamodel file.
I want to add some custom methods to these entities in order to keep the Model part separate from the Controller.
In previous versions of Xcode the autogenerated managedObject classes were added automatically to my project and I could add custom methods to these classes. Now I no longer see these auto genterated classes.
I have selected 'Class Definition' for the codegen.
Do I need to create an additional class for each entity to enable custom methods on those entities? Or is there a better way to go about this.
This is a rather new Xcode feature. Xcode generates the files for you and holds a reference to the generated files. Even the files do not show up in the project, you still can write extensions for the generated classes.
You can find more detailed information in this answer.

core data invalid redeclaration of class

So, I have a got a problem…
when I intend to create a NSManagedObject Subclass.
As you can see this problem is really spread widely. Many people propose a solution by changing codegen block into Manual/None. But this did not help me, furthermore Class Definition and Category/Extension did not resolve too.
When I delete two files which were created by tapping in Product/Create NSManagedObject, the code is really works. I didn't why but I could use a NSManObject classes like they are lying somewhere I found a path where they are existing.
I thought If I delete them then I can recreate subclass again and use it successfully. But it is not. When I create again a subclass files these two files that were lying in unknown directory were recreated again! I ask the people who encountered to this problem and I need their help or solution
There's an annoying bug in the core data codegen settings, which means that updated settings aren't stored correctly.
If you change the codegen settings and then Build or Run, your changes will not be saved. For example, if you changed from Category/Extension to None and deleted the generated file, it will be recreated.
To solve this problem…
Change your codegen settings
Save the .xcdatamodel file.
Close all project windows.
Re-open the project.
I tested for different Core Data data model class codegen settings. When it's set to Class Definition or Category/Extension. The builder will generate subclass files automatically. So we don't need to add these files by ourselves. The following is files generated by builder.

Duplicate Symbol Error in NSManagedObject Subclass

I just simply created a demo project with Core Data.
I created an entity Userinfo in my data model. Now I created a NSManagedObject subclass of this entity.
Xcode autogenerated these 4 classes.
Now when I build the project it throws this error:
I have done everything I know to remove the error of duplicacy but nothing helped.
I think its a Xcode bug. Please help.
You are generating files which have already been generated for you by Xcode and thus get duplicate declarations. Details about this feature (new in Xcode 8) can be found in this WWDC video.
Two possible fixes:
1) Use the Xcode generated ManagedObject subclasses (the recommended, modern approach)
Delete all generated NSManagedObject subclasses from your project, if exists.
Set Codegento Class Definition in your .xcdatamodel for all entities
Make sure Module is empty ("Global Namespace" in light gray) (workaround an Apple bug, see this answer)
Clean project
Clean DerivedData folder (Optional. To be on the save side)
build
Note:
Never add the automatically generated files to your project. Even you do not see the generated files in your project, Xcode has a reference to it, so you are able to write extensions and such. For instance:
extension MyEntity {
func doSomething() {
//
}
}
Also, you can command+click to the generated file within Xcode.
2) Trigger subclass generation manually (a rather paranoid but bullet-prove approach, ignoring the new Xcode features)
Delete all generated NSManagedObject subclasses from your project, if exists.
Set Codegento Manual/None in your .xcdatamodel for all entities
Clean project
Clean DerivedData folder
Restart Xcode
Manually generate NSManagedObject subclasses (in "Editor" menu)
Make sure those files are added to your project
build

can not create subclasses of managed objects

from documentation (What's New In Core Data)
Xcode automatic subclass generation
Xcode now supports automatic generation of NSManagedObject subclasses in the modeling tool. In the entity inspector:
Manual/None is the default, and previous behavior; in this case you should implement your own subclass or use NSManagedObject.
Category/Extension generates a class extension in a file named like ClassName+CoreDataGeneratedProperties. You need to declare/implement the main class (if in Obj-C, via a header the extension can import named ClassName.h). -
Class Definition generates subclass files named like ClassName+CoreDataClass as well as the files generated for Category/Extension.
The generated files are placed in DerivedData and rebuilt on the first build after the model is saved. They are also indexed by Xcode, so command-clicking on references and fast-opening by filename works.
and no matter what i chose it doesn't get generated.
i'm probably doing something wrong or incomplete, aren't i?
If you set "Codegen" to "Class Definition", like in your example, Xcode does generate the NSManagedObject subclasses, but you do not actually see the in your project. Like stated in your posted quote, the files are generated in
~/Library/Developer/Xcode/DerivedData/...
You do not see them in your project, only the files in Derived Data, which you should not have to care about. Xcode does hold a reference though, so command+clicking in code jumps to the implementation as expected plus you are able to write extensions and such.
Find details in this answer.

Resources