Chapter 2: Error 'Bowtie' is ambiguous for type lookup in this context

Under XCode 8.1, I get this error and I can’t even compile the application anymore. I think this is the same issue as here 'Dog' is ambiguous for type lookup in this context.

Any pointers?

The short answer: Change the default Codegen option for the Bowtie entity from “Class Definition” to “Manual/None”. You may have to clean your project before you build it again. The Codegen option can be found in the Data Model inspector when you select an entity.

The long answer: I encountered the same issue while working through Chapter 2. After reviewing Apple’s documentation, Apple’s developer forum and testing with my own project, I think I have better understanding of the Codegen options that are offered.

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 }

Hey all! Thanks for letting us know about this problem and for helping others out.

We’ve updated Chapters 2 and 3 of the book to help avoid this issue under Xcode 8.1:

https://www.raywenderlich.com/148554/core-data-tutorials-updated

All Core Data by Tutorials PDF customers get this as a free update!

In version 3.1 of the book (updated on the 22 of November), there seems to be an error in Chapter 2(page 45).

Make sure you still have Bow_Ties.xcdatamodeld open, select the Bowties entity
and open the Data Model inspector. Set the Codegen dropdown to Manual/None,
as shown below:

The above paragraph fails to mention to set the module option to Current Product Module. Without doing this, Xcode 8.1 says that Bowtie is ambiguous and the project doesn’t compile.

Bowtie also suddenly becomes Bowties in the both the above paragraph and in the screenshot in the book.

This is how it should look to work, like in the final version of this project :slight_smile:
The project compiles for me after fixing this error.

The same error still happens in Chapter 3 and is fixed in the same way. Dog and Walk’s module should be set to Current Product Module.

I also had the same “ambiguous” error etc. However it turned out that when I went back to Bow_Ties.xcdatamodeld the “Codgen” dropdown was back to Class Definition even though I had set it to Manual/None. This happened several times - whenever I would click on the core data class and then come back to the data model. It was resolved for me by hitting command-S (save). I didn’t have to set Module to Current Product Module - maybe when you changed that dropdown it automatically saved the file for you. It seems like a bug in Xcode - this isn’t typically how the other files behave (they autosave when you navigate away from them usually).

1 Like

agree about the typo “Bowties” in the screen shot and text as per @drstz
Do we need to file a separate comment under the errata section?

Thanks. I didn’t notice this.

However, in the final Xcode projects for both chapter 2 and 3 that are provided with the book (version 3.1), module is set to Current Project Module.

I reproduced the bug following the instructions in the book (version 3.1)

The bug

Here are my steps.

  1. I forced quit Xcode.
  2. I downloaded a copy of the book
  3. I followed the instructions in the book until the subclass generation

I get the following errors in Xcode:

Bowtie+CoreDataClass :

  • Invalid redeclartion of Bowtie

Bowtie+CoreDataProperties:

  • ‘Bowtie’ is ambiguous for type lookup in this context,
  • Extensions may not contain stored properties,
  • @NSManaged only allowed on an instance property or method

The code page 46 is not generated with the instructions in the book

Furthemore,

Bowtie+CoreDataClass.swift generates the following code on my machine:

@objc(Bowtie)
public class Bowtie: NSManagedObject {

}

but in the book, page 46, the code shown is this, without the @objc(Bowtie):

public class Bowtie: NSManagedObject {

}

Solution

The final version of the project in both chapter 2 and 3 have set module of the class in the identity inspector to Current Product Module.

The generated Bowtie+CoreDataClass corresponds with the code on page 46 of the book.

By deduction, the instructions are complete, and the final version of the project uses the correct way to generate the subclasses.

Testing with a custom project

Unfortunately, I do not understand why this works.

When I create a custom project (New Project - Single View Application - Use Core Data and include Unit Tests), then the steps in the book work.

Xcode detects no errors and allows me to build the project.

Conclusion

Clearly the instructions in the book are incomplete:

  • The final project sets the module of the class to Current Product Module
  • The code shown page 46 doesn’t correspond with the code generated when using the current instructions

However, this error doesn’t appear in a brand new project(in my case).

How to fix the bug in the project is clear, but the correct way to generate subclasses is not.

Looks like I’m not the first one to get stumped by following the book. It appears the issue comes from inconsistencies in the class/entity name. On one page it’s Bowties (plural) and on other pages it’s Bowtie (singular). Turns out the compiler is picky about these things. :wink:

My solution was to change the Entity name from Bowtie (as seen on page 39) to Bowties. Then, on page 45, the screen shot has Class Name = Bowties, Module = Global namespace. I changed Class Name to CDBowties (CD=CoreData) and I set the module to Current Product Module. Changing the class name to CDBowties was my way of ensuring that the generated class names did not conflict with anything else. So, when you generate the classes, it will generate them with the name CDBowties so the code on page 46 will have different names.

Then, the next thing is to ensure anywhere the book refers to the Entity Bowtie (ie: starts bottom pg 47/top of pg 48) you have to change it to Bowties. Anywhere it refers to the class named Bowtie, you have to use CDBowties. Then it worked fine.

Hope this helps.