Xcode 8 generates broken NSManagedObject subclasses for iOS 10

Core DataNsmanagedobjectIos10Xcode8

Core Data Problem Overview


I updated my iOS app project recently to iOS 10. Now I'm trying to change the Core Data Model of my app but the new NSManagedObject subclasses which Xcode generates are broken. I also tried to fix the subclasses manual but this doesn't work.

The minimum tools version for the Core Data Model is set to Xcode 7.0 and code generation language is set to Swift.

This is the code which Xcode generates:

import Foundation
import CoreData
import




extension Group {



@nonobjc public class func fetchRequest() -> NSFetchRequest<Group> {
    return NSFetchRequest<Group>(entityName: "Group");
}

@NSManaged public var name: String?
@NSManaged public var platform: NSNumber?
@NSManaged public var profiles: NSOrderedSet?




}




// MARK: Generated accessors for profiles
extension Group {



@objc(insertObject:inProfilesAtIndex:)
@NSManaged public func insertIntoProfiles(_ value: SavedProfile, at idx: Int)

@objc(removeObjectFromProfilesAtIndex:)
@NSManaged public func removeFromProfiles(at idx: Int)

@objc(insertProfiles:atIndexes:)
@NSManaged public func insertIntoProfiles(_ values: [SavedProfile], at indexes: NSIndexSet)

@objc(removeProfilesAtIndexes:)
@NSManaged public func removeFromProfiles(at indexes: NSIndexSet)

@objc(replaceObjectInProfilesAtIndex:withObject:)
@NSManaged public func replaceProfiles(at idx: Int, with value: SavedProfile)

@objc(replaceProfilesAtIndexes:withProfiles:)
@NSManaged public func replaceProfiles(at indexes: NSIndexSet, with values: [SavedProfile])

@objc(addProfilesObject:)
@NSManaged public func addToProfiles(_ value: SavedProfile)

@objc(removeProfilesObject:)
@NSManaged public func removeFromProfiles(_ value: SavedProfile)

@objc(addProfiles:)
@NSManaged public func addToProfiles(_ values: NSOrderedSet)

@objc(removeProfiles:)
@NSManaged public func removeFromProfiles(_ values: NSOrderedSet)




}

}

Edit: These are the specific errors which Xcode gives:

1. Group+CoreDataProperties.swift:13:1: Expected identifier in import declaration (the empty import)




Group+CoreDataProperties.swift:13:11: 'Group' is ambiguous for type lookup in this context
Group+CoreDataProperties.swift:15:16: Cannot specialize non-generic type 'NSFetchRequest'
Group+CoreDataProperties.swift:26:11: 'Group' is ambiguous for type lookup in this context
Group+CoreDataProperties.swift:43:82: 'SavedProfile' is ambiguous for type lookup in this context
  1. Group+CoreDataProperties.swift:13:11: 'Group' is ambiguous for type lookup in this context
  2. Group+CoreDataProperties.swift:15:16: Cannot specialize non-generic type 'NSFetchRequest'
  3. Group+CoreDataProperties.swift:26:11: 'Group' is ambiguous for type lookup in this context
  4. Group+CoreDataProperties.swift:43:82: 'SavedProfile' is ambiguous for type lookup in this context

Core Data Solutions


Solution 1 - Core Data

I finally got mine to work. Here is what I did. (Flights is one of my entities)

I setup the xcdatamodeld as follows

enter image description here

And then the entity as

enter image description here

Then I used Editor -> Create NSManagedObject Subclass

This creates two files for my flights entity

Flights+CoreDataProperties.swift

Flights+CoreDataClass.swift

I renamed Flights+CoreDataClass.swift to Flights.swift

Flights.swift is just

import Foundation
import CoreData

@objc(Flights)
public class Flights: NSManagedObject {

}

Flights+CoreDataProperties.swift is

import Foundation
import CoreData


extension Flights {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Flights> {
        return NSFetchRequest<Flights>(entityName: "Flights");
    }

    @NSManaged public var ...
}

This appears to work for me.I could not get Codegen to work in any other way, even though I tried many of the suggestions that were out there.

Also this had me scratching my head for a while and I add it as an assist. Don't forget with the new Generics version of the FetchRequest you can do this

let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Flights")

Solution 2 - Core Data

I believe the reason you encountered those errors after generating the NSManagedObject subclass files may be related to the Codegen option that was selected at the time your data model changed.

I do not think this is a bug. At least not in Xcode 8.1 (8B62).

I encountered a similar issue and fixed it by changing the Codegen option to "Manual/None" and leaving the Module option as "Global Namespace". I then generated my NSManagedObject subclass files. However, depending on your situation, you may not even need to generate the NSManagedObject subclasses.

Below are more details on the entity Codegen options based my review of Apple's documentation, the Apple developer's forum and testing with my own project.

Option 1: "Class Definition"

  • Think of this as the "plug and play" option

  • Use the model editor to create the entities and associated attributes that you want Core Data to manage.

  • Do not use the NSMangagedObject subclass generator. The required files are automatically generated for you by Xcode (however they do not show up in your project navigator).

  • If you do generate the NSManagedObject files, Apple tells you that these files should not be edited in the header comments of said files. If you do need to edit these files, then this is good sign that you need to use another Codegen option.

  • Leave the default Class options for your entity (Module = Global Namespace and Codegen = Class Definition)

  • If you need to override methods of the NSManagedObject, you can create an extension using the Name under the Class option.

    // Optional extension in Entity.swift extension Entity { // Override NSManagedObject methods }

Options 2: "Manual/None"

  • Similar to Option 1, except that you can see and edit the NSManagedObject subclass files.

  • Use the model editor to create the entities and associated attributes that you want Core Data to manage.

  • Before using the NSManagedObject subclass generator, set the Codgen option to "Manual/None" for the entity. The Module option should be Global Namespace.

  • After you add/remove/update an attribute, you have two choices: (1) Manually update the NSManagedObject files that were generated for you OR (2) Use the NSManagedObject subclass generator again (this will only update the Entity+CoreDataProperties.swift file).

  • Again, if you need to override and methods from NSManagedObject, you can create an extension. The extension should be created in the Entity+CoreDataClass.swift file and not the Entity+CoreDataProperties.swift file (this file could be updated due to model editor changes).

    // Optional extension in Entity+CoreDataClass.swift extension Entity { // Override NSManagedObject methods }

Option 3: "Category/Extension"

  • Use this option if you have custom properties that do not need to be managed by Core Data.

  • Use the model editor to create the entities and associated attributes that you want Core Data to manage.

  • Ensure the Module option is set to Current Product Module and the Codegen option is set to "Category/Extension".

  • Create your own NSManagedObject subclass with the properties that you will self manage.

  • Do not use the NSMangagedObject subclass generator. The required files are automatically generated for you by Xcode (however they do not show up in your project navigator).

    // Subclass NSManagedObject in Entity.swift class Entity: NSManagedObject { // Self managed properties }

    // Optional extension in Entity.swift extension Entity { // Override NSManagedObject methods }

Solution 3 - Core Data

  1. To solve this problem delete the derived data of the app.

  2. Then change the Module to Current Product Module and also make changes in Codegen to Manual/None.

  3. List item

Solution 4 - Core Data

Try to set CodeGen: Manual/None Module: Current Product Module

It worked for me well, when I faced with the same problem.

enter image description here

Solution 5 - Core Data

You can try these steps

  1. Select the .xcdatamodeld file in Xocde Project Navigator
  2. In the Data Modul Inspector, make sure Codegen : Manual/None
  3. Then Edit -> Create NSManagedObject Subclass
  4. Clean product and rebuild

Is that work? If not

Make sure you all class has not the same name with Entities. You can find these class in Build Phases -> Compile Sources. Rename the class or Entities if they duplicated

Or

You can run this command to in your project folder to get more error info

xcodebuild -verbose

I got this message when i have this problem

> duplicate symbol OBJC_CLASS$_RandomList in:

>xxxx/RandomList.o

>xxxx/RandomList+CoreDataClass.o

RandomList.h and RandomList+CoreDataClass.h have a same symbol when compiling

I think that why Xcode did not warn you, but Compiler will throw error

Hope this will help you

Solution 6 - Core Data

If you have a legacy app and you wish to keep adding managed object classes manually

  1. Make sure your core data model codegen is set to Manual/None
  2. Select your core data model file
  3. Create managed object subclass

screenshot of editor

Solution 7 - Core Data

Delete the 3rd import statement because it's empty.

Note: I don't know why this happens but I guess it's a bug in Xcode 8. Just delete it and it will work fine.

Solution 8 - Core Data

On Xcode 8.2.1, I made it the way: (thanks for Daniel Chepenko)

enter image description here

But Xcode 8.2.1 will add a stupid . into the generated files:

enter image description here

Just delete the . and it will run right.

Solution 9 - Core Data

I just had a problem where I just added a Person entity in my model to the Core Data template. Then generated the NSManagedObject subclass for for that and it won't compile, giving me a Linker Error. Turns out I am supposed to change the Codegen option to Manual/None to make it work (see bottom-right part of the picture).enter image description here

Solution 10 - Core Data

I think it is a xcode issue, where xcode generates wrong syntax for core data category class. I am creating a nsmanageobjectsubclass for one entity AgentDetails It is creating the following classes

Here xcode create wrong code structure in AgentDetails+CoreDataClass.h and AgentDetails+CoreDataClass.m. Those have a code structure like:

enter image description here

And

enter image description here

So it is having duplicate interface issue as AgentDetails.h have same interface.

Now to fix this you have to change the code in AgentDetails+CoreDataClass.h

enter image description here

and AgentDetails+CoreDataClass.m like this:

enter image description here

Solution 11 - Core Data

In Data Model Inspector select Current Product Module under 'Module' and Manual/None under 'Codegen'. (This allows you to edit subclass files and to regenerate CoreDataProperties.swift when you modify your attributes under the same entity.)

enter image description here

You can then choose Create NSManagedObjectSubclass under Editor menu. Xcode will create 2 files for you YourEntity+CoreDataClass.swift and YourEntity+CoreDataProperties.swift. Notice if you don't have the latest Xcode (8.2.1), any optional/nonoptional properties that you set in your Model Inspector will not show up correctly. You can edit in YourEntity +CoreDataProperties.swift file.

Solution 12 - Core Data

I solved it like an example given below

Create CurrentcyPair.xcdatamodeld

select CurrentcyPair.xcdatamodeld and select Default -> Entity (CurrencyPair) , rename the class as (.ManagedCurrencyPair)

Select Entity and open Inspector. Set code gen at data model as Manual/None

enter image description here

enter image description here

Solution 13 - Core Data

Xcode 8.1 seems to be generating Model Class internally. Just delete the 2 classes created and you will still be able to use the entities in your code.

Here's the error message I was receiving

<unknown>:0: error: filename "Recipe+CoreDataProperties.swift" used twice: '/Users/Rick/Desktop/Devslop/Rick Recipe/Recipe+CoreDataProperties.swift' and '/Users/Rick/Library/Developer/Xcode/DerivedData/Rick_Recipe-cctgjudvqobxlwetbcwmzrgxigwg/Build/Intermediates/Rick Recipe.build/Debug-iphonesimulator/Rick Recipe.build/DerivedSources/CoreDataGenerated/Rick_Recipe/Recipe+CoreDataProperties.swift'
<unknown>:0: note: filenames are used to distinguish private declarations with the same name
Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc failed with exit code 1

Solution 14 - Core Data

Also, if you add NSManagedObject subclass yourself, don't forget to follow the following step: Go to '.xcdatamodeld' -> Choose the entity -> Show data model inspector -> Codegen -> Choose 'Manual/None'

This worked for me.

Solution 15 - Core Data

I found this Post from David Atkinson which is helpful in some way. If I generate the code the way David described. I just get the code with some Syntax errors and if I fix the errors everything works like before. There are no missing files starting with '.' any more.

The syntax errors i Have to correct are

  • the unnecessary import

  • and some public properties which are not intended to be public in my code

Solution 16 - Core Data

I am running the latest Xcode 8.1 beta (8T47) build.

According to the error log (see below), two copies of the autogenerated files are created. One copy is put in your Xcode project folder (the one visible in your directory on the left hand side toolbar of Xcode), and a second copy is created in your DerivedData folder for your project:

/Users/<your name>/Library/Developer/Xcode/DerivedData/<your app>-axhtnodotznxnrenefflktnxfeal/Build/Intermediates/<your app>.build/Debug-iphonesimulator/<your app>.build/DerivedSources/CoreDataGenerated/<your app>/<class name>+CoreDataProperties.swift
/Users/<your name>/Library/Developer/Xcode/DerivedData/<your app>-axhtnodotznxnrenefflktnxfeal/Build/Intermediates/<your app>.build/Debug-iphonesimulator/<your app>.build/DerivedSources/CoreDataGenerated/<your app>/<class name>+CoreDataClass.swift

Deleting the copies in your Xcode project directory will fix all issues, but proves pointless as you can no longer edit these files...

I wouldn't say this is a solution, rather just a half-assed way to get the project to build. Hopefully this bug will be addressed soon.

Error Log

Solution 17 - Core Data

For me, I created CocoaTouch classes by subclassing of NSManagedObject manually. I set the module as Current Product Module and Codegen as Category/Extension and it works well.

Solution 18 - Core Data

In my particular case, I had added CoreData to an existing project which already had a Model class by the same name as my entity. Deleting the old Model class fixed the problem, as its type was colliding with the new CoreData Entity class.

Solution 19 - Core Data

I'm putting my grain of salt given that I can see a lot of answers that solve the problem but are lacking the real reason behind what's really happening here.

I stumbled upon this very same issue and by doing a quick research I was able to find that:

  • Until Xcode 7, the default behavior for a Core Data entity was that the developer had to manually create and maintain the changes of the corresponding NSManagedObject subclasses. (This could, and still can be accomplished by making use of the editor menu selecting the "Create NSManagedObject subclass.." option).

  • Starting from Xcode 8, Apple has included a new setting right in the Data Model Inspector named Codegen to manage and maintain the NSManagedObject subclasses. The default value for this setting is "Class Definition" which tells Xcode to generate the NSManagedObject subclasses based on our defined entities in compile time and put them in the derived data folder.

Having our NSManagedObject subclasses within the project + the ones Xcode automatically generates lead us to the real reason behind the "Multiple commands produce..." compiling time error as we now have duplicated managed objects models!!!

The solution then is to use either one or another, not both! I personally prefer to have my managed object models within the project so I have changed this "Codegen" setting to "Manual/None". If you are not adding logic to the models I bet you could opt by removing your project's managed object models and let Xcode do its thing based on the "Class Definition" value for the mentioned setting. This is the right way to deal with this issue.

You can find a great article explaining all of this in detail here:

https://medium.com/@kahseng.lee123/core-data-codegen-explained-462c30341041

Solution 20 - Core Data

What you need to do is set the CodeGen to Category/Extension before you execute the Create NSManagedObject subclasses.

Solution 21 - Core Data

I have a Flights Entity and these settings in the Data Model Inspector worked for me :

  1. Set the Name to nothing(You will see some grayed out text of "NSManagedObject"). The default will be written as "Flights" just remove that.

  2. Nothing in the module."Global Namespace" greyed out is what you will see.

  3. Codegen to Manual/None.

  4. Then Goto Editor -> Create NSManagedObject Subclass to create the swift files

  5. Rename the Flights+CoreDataClass.swift to just Flights.swift

Here's the link to the Screenshot(For some reason imgur was rejecting it :( ) https://drive.google.com/file/d/0B8a3rG93GTRedkhvbWc5Ujl4Unc/view?usp=sharing

Solution 22 - Core Data

After I renamed the following:

From: YourEntity+CoreDataClass.swift To: YourEntity.swift

and

From: YourEntity+CoreDataProperties.swift To: YourEntityCoreDataProperties.swift

then it works. It looks like "+" is causing the problem.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRemco BeugelsView Question on Stackoverflow
Solution 1 - Core DataLongmangView Answer on Stackoverflow
Solution 2 - Core DataRyan H.View Answer on Stackoverflow
Solution 3 - Core DataakshayView Answer on Stackoverflow
Solution 4 - Core DataDaniel ChepenkoView Answer on Stackoverflow
Solution 5 - Core DataSamBundyView Answer on Stackoverflow
Solution 6 - Core DataNeil JaphthaView Answer on Stackoverflow
Solution 7 - Core DataLawrence413View Answer on Stackoverflow
Solution 8 - Core DataAlpha LiuView Answer on Stackoverflow
Solution 9 - Core DatappalancicaView Answer on Stackoverflow
Solution 10 - Core DatasouvickcseView Answer on Stackoverflow
Solution 11 - Core DataOhmyView Answer on Stackoverflow
Solution 12 - Core DataWasimView Answer on Stackoverflow
Solution 13 - Core Datauser1988055View Answer on Stackoverflow
Solution 14 - Core DataSoumalya BanerjeeView Answer on Stackoverflow
Solution 15 - Core DatatetanussView Answer on Stackoverflow
Solution 16 - Core DataMikeView Answer on Stackoverflow
Solution 17 - Core DataalitosunerView Answer on Stackoverflow
Solution 18 - Core DatajonbauerView Answer on Stackoverflow
Solution 19 - Core DataMiguel Rojas CortésView Answer on Stackoverflow
Solution 20 - Core DataMichal BedryView Answer on Stackoverflow
Solution 21 - Core DataManiSView Answer on Stackoverflow
Solution 22 - Core DataHLieView Answer on Stackoverflow