Running the following code aborts in the return line
Type is not Workout
Could not cast value of type
'NSManagedObject_Workout_' (0x7fcca20620f0) to
'AppName.Workout' (0x100ea5f40)).
The part inside if let... is never executed.
func createWorkoutWithName (name: String) -> Workout? {
let entityName = NSStringFromClass(Workout.classForCoder())
let newEntity = NSEntityDescription.insertNewObjectForEntityForName(entityName, inManagedObjectContext: managedObjectContext)
if let newEntity = newEntity as? Workout {
newEntity.name = name
}
NSLog("createWorkoutWithName: Type is not Workout")
return (newEntity as! Workout)
}
I had this problem in the past and I solved it in XCode 6.x by going in the entity inspector and setting Class = AppName.Workout
One of several answers that suggests this solution is
How come I can cast to NSManagedObject but not to my entity's type?
XCode 7 adds a new twist to this problem:
When I set
Class = AppName.Workout
in the entity inspector, XCode 7 changes the class name automagically to
Class = AppNameWorkout
by removing the dot between AppName and ClassName.
So how can I do this in XCode 7 when I can't set a dot between AppName and ClassName?
Go to your cdatamodel..where you declared your entity..There is a Default Configuration below the Entity. Check the Class column against your entity. By default this will have a dot prefixed. Remove the dot prefix .And it should work. And from what i see is you do not have to prefix your entity class name with the module name in Xcode 7. Hence you cannot use a dot in the class name.I am a newbie in iOS development. So i might not be totally right. But removing the dot prefix solved my issue in Xcode 7.
You need two fixes:
First: Set your entity class name as your entity name. For example:
Entity name = Entity
Class name = Entity
Second: add this code above your entity class file:
#obj(Entity name)
For example:
#obj(Entity)
Class Entity: NSManagedObject {
...
}
The combination of these solutions and the link you provided got me to the solution, but it took me a while to piece it all together. This is what I came up with (and it was basically just an oversight):
Click on .xcdatamodelId file in your file structure/project
navigator pane (far left).
Select the entity that you are having issues with.
In the Utilities pane (far right), look for the icon that looks like a 1997 cell phone, the Data Model Inspector.
Under the entity settings, you should see two fields, "Name" and "Class" - set up "Class" with the name of the class you are using (typically the same as "Name").
Thats where I messed up, even though all my other entities had this set, I had forgotten to set this on this particular entity. You'll even notice before you follow these steps that the default "class" is NSObject, reflecting the error message. Some of the other solutions here likely ultimately do the same thing, but I found this the simplest/quickest solution.
I should note that I already had some of the other items noted set, like the #objc(Entity) interoperability reference.
Related
Using Xcode 12, and starting with the default XIB-based swift desktop app, I add a Model class, descended from NSObject with a single stringValue property. In the XIB file I instantiate the Model class, and add a text field to the default window, and bind the value of the text field to the stringValue property of my Model instance. The project builds and runs, and any value I set in the initializer of the Model class displays in the text field.
Here is my Model class:
import Foundation
#objc public class Model : NSObject {
#objc dynamic public var stringValue: NSString
override init() {
stringValue = "some string"
}
}
The full project is available here:
https://github.com/thomasmarschall/KvoLab2023
I started with a bit more complicated setup involving a separate library and framework, but my current setup seems to be super straightforward.
Having done all of this, Xcode displays a grey flag in the Model Key Path field of the text field value binding, and the tool tip for the flag reads "xcode cannot resolve the entered keypath". Also, the autocomplete in the key path field does not work. How can I resolve these issues? Any help would be appreciated.
I'm getting a "Table name too long" error after moving some code into a framework. After going through the stack trace, breaking to get the table names on schema creation, then manually trying to create the longer table names. I've determined the name that's problematic. The table name that's problematic is a linking table, is there a way in Realm to force the name of that table using className() or something else for a linking table?
Screenshot of the Realm error being thrown.
After further investigation it turns out the way to resolve this was to create a subclass of the type in my app. Due to the how my code was structured, Realm was creating the table name using the class name, package name and the generic type handed in. This made the name way too long. When you subclass the type with it's explicit generic type in the actual app, Realm no longer needs to worry about package names or the generic name. Below should help illustrate the problem and solution.
class PackageA.One<I>: RealmSwift.Object {
var List<I> = List<I>()
}
class App.Two: RealmSwift.Object {
}
let realmObjectsToRegister = [Package.One<App.Two>.self]
The above lead to Realm creating a Table name of "TtGC11PackageA9OneC9App18Two" except the real names in my app made this over 57 characters (the max table name length).
By doing the following, i shortened the name and fixed the problem
class PackageA.One<I>: RealmSwift.Object {
var List<I> = List<I>()
}
class App.Two: RealmSwift.Object {
}
class App.AppOne: PackageA.One<App.Two> {}
let realmObjectsToRegister = [App.AppOne.self]
The solution then lead to realm naming the table "AppOne" instead and fixed the long name issue.
I'm working with Swift in Xcode and I receive the following error: -- Value of type 'Category' (aka 'OpaquePointer') has no member 'name' -- and I've looked everywhere but I can't find a solution.
Does someone know what to do?
Here is a screenshot:
Thanks for your help!
I also had this occur when attempting the exercise in the Angela Yu course where Category is a core data entity. I was using Xcode 11.3.1. After several attempts of setting the Module to Current Product Module and Codegen to Class Definition followed by Ctrl-B's to rebuild, I still received the error. However, restarting Xcode solved the problem and code completion was then able to suggest the name attribute/property.
I had same issue while been going through Angela Yu course and I had tried all of the available solution which I could find, but only this one has helped to me:
while your project is opened:
press Product on the top pane
press Clean Build Folder
do not use hotkey combination - just press it with your mouse!
only this method help to me to get rid of this error.
I had the same problem. In my DataModel file, I changed entity name and the class name from "Category" to different one, such as "TodoListCategory." Then in my CategoryViewController, I changed all the Category objects to "TodoListCategory" and rebuild. It solved my problem.
After that, you might have error "Command CompileSwift failed with a nonzero exit code." Now, try to clean your project by using Shift + Command + K & Option + Shift + Command + K
If you are following Angela Yu's course, I found that by selecting Manual/None and then Class Definition for the Category Entity under Codegen, the classes are auto-generated.
Also run cmd + b afterwards.
Also in Angela's class. I found that by removing the core data models and reinitiating them as independent entities with no relationship, setting up the save and load functions, running the app, and then going back to link the relationship solved the issue. I think it has to do with saving the entities as NSManagedObject before being able to reference the attributes. I am guessing that without initiating them as an NSManagedObject the default type is Opaque Pointer. Best of luck!
I'm following the same lesson.
In my case was just an Xcode bug and "Category" was not recognized as a class.
I just close and re-open it and work fine.
Category did not provide name property
Change the 'categories' variable form 'var' to 'let'.
From,
var categories = [Category]()
to
let categories = [Category]()
Just re-build it and this is working.
If [Category]() is not recognized as a NSManagedOject, just put the term Category between two single reversed quotation marks inside the brackets.
link to example
While declaring a array of the type Category, do it like :
var categories = [[`Category`]]()
(if you have the name of the entity as "Category")
note: There is just a single back tick to the left of category.
Good day!
Please make sure you did not choose Opaque Pointer instead of your Class.
See below:
Screenshot
if you did, replace Category with 'Category'
We need to change the class Module to "Current Product Module" in inspector on the right
enter image description here
I have an Objective-C model class MyType. This class is used in Swift code:
NSEntityDescription.insertNewObjectForEntityForName("MyType", inManagedObjectContext: context) as! MyType
The as! cast results in the error message
Core Data: Could not cast value of type 'MyType_MyType_2' (0x7be99a30) to MyType (0xf33db74).
If I cast it as NSManagedObject it works. When I print the result, I can nevertheless see, that it is an actual instance of MyType:
<MyType: 0x7ae06d50> (entity: MyType; id: 0x7aeba6d0 <x-coredata:///MyType/t957F2860-85F8-46E0-B6D6-4D1DF6C4EC613> ; data: {
...the fields...
})
What is happening here? And where does the name MyType_MyType_2 come from?
When I had this issue, it was because I had forgotten to set the "class" on the entity. This is what I came up with:
Click on .xcdatamodelId file in your file structure/project
navigator pane (far left).
Select the entity that you are having issues with.
In the Utilities pane (far right), look for the icon that looks like a 1997 cell phone, the Data Model Inspector.
Under the entity settings, you should see two fields, "Name" and "Class" - set up "Class" with the name of the class you are using (typically the same as "Name").
You'll even notice before you follow these steps that the default "class" is NSObject, reflecting the error message. I found some programatic ways to do this too, but this seemed like the simplest/quickest solution.
I should note that my model WAS written in Swift, so I did have to add the #objc(Entity) interoperability reference mentioned by #zellb. But that shouldn't make a difference in the solution as long as you are doing that part properly (and that would cause a different unrelated error from my understanding).
Set Entity Class Name
Set Module "Current Product Module" like below
just try this:
#objc(MyType)
public class MyType: NSManagedObject {
// your class
}
instead of this:
class MyType: NSManagedObject {
// your class
}
I had mistakenly set a "parent entity" in one of my entities in the data model inspector in the entity section. I mistakenly thought that referred to the destination of a one-to-many relationship.
Setting it back to "no parent entity" fixed the problem, although I did have to delete and reinstall the app in the simulator to deal with the messed up core data database.
I'm having trouble working out the implications of this note from Apple's "Using Swift with Cocoa and Objective-C":
Swift classes are namespaced—they’re scoped to the module (typically, the project) they are compiled in. To use a Swift subclass of the NSManagedObject class with your Core Data model, prefix the class name in the Class field in the model entity inspector with the name of your module.
I've done that, using my own application and just the stock master-detail template, so my entity's name is "Event" and its class is "Stock_Master_Detail.Event". When I then choose Create NSManagedObject Subclass from the Editor menu, and ask it to create a Swift subclass, it doesn't name the class right. Xcode creates a file called "Stock_Master_Detail.swift" with that's for a class called Stock_Master_Detail. And if I create multiple entities, all with the module name prefixed, Xcode can't generate more than one subclass since they'll all wind up having the same name.
I'll add that everything works fine in my limited testing if I just omit the module name entirely, counter to Apple's documentation. My question, then, is, what are the implications of not adding the module name to my class?
One way I got around this is to leave the data model file alone, so in this case the class would be "Event". Then in the code where the NSManagedObjectModel is created (AppDelegate if you used Apple's project template) I changed it to:
lazy var managedObjectModel: NSManagedObjectModel = {
// The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model.
let modelURL = NSBundle(forClass: self.classForCoder).URLForResource("Model", withExtension: "momd")!
var bundleModel = NSManagedObjectModel(contentsOfURL: modelURL)!
var objectModel = NSManagedObjectModel()
objectModel.entities = bundleModel.entities.map { ( entity ) -> NSEntityDescription in
var entityCopy = entity.copy() as NSEntityDescription
entityCopy.managedObjectClassName = "Stock_Master_Detail." + entity.managedObjectClassName
return entityCopy
}
return objectModel
}()
One improvement, I would like to figure out is how to find the module name dynamically. I know I could parse the current class's name, but that feels a weirder than I want.
I believe that it could be a bug with Swift/Core Data. First, generate your managed object without the module name(prefix). After it is generated, then go back and add the prefix in core data.