16

The class name for entity models in the Core Data model has to have the app name prepended to it. So for an entity named User the class name in the model editor has to be MyAppName.User. This works fine until I added a second target to my project.

The new project expects the entity class names to be SecondAppTargetName.User. How do we support two targets using the same core data model? I tried prepending ${PRODUCT_NAME}.User instead, not expecting it to work. And it doesn't work.

Any ideas on how to share one core data model between targets and satisfy the need of Swift projects to have the PRODUCT_NAME prepended to the class in the model editor?

EDIT: It appears from the Apple documentation here that adding the module name as a prefix to the class name in the model entity inspector is the preferred behavior. If so this seems like a gaping hole since it precludes multiple targets using the same data model. I still have found no workaround for this yet. Some posts here on SO have indicated that using @objc(ClassName) in front of the Swift class definition for the managed object will do the trick, but I haven't been able to verify that yet.

davidethell
  • 11,708
  • 6
  • 43
  • 63
  • 1
    Have you tried to omit the appname from the classname? I have no appname in front of my Core Data classes and it works fine. In fact, I can not get it to work with the app name! My app name contains a space and I have tried all possible combinations to prepend the class with the app name to no avail. I have no problems without the appname. – zisoft Aug 11 '14 at 11:49
  • Yes, I removed the app name as I've seen some example projects without it. It won't work. I'm not sure if it's because I use RestKit, but I've seen other posts where the user mentioned they had to prepend the product name. – davidethell Aug 11 '14 at 11:50
  • In what way doesn't it work? RestKit should have no impact. Why do you need to prepend the project name (what expects it)? Can you not prepend some other text? – Wain Aug 11 '14 at 12:55
  • Clearly the solution here is to add a space to your app name, then it's not required! ;] – Chris Wagner Aug 11 '14 at 19:41
  • I don't know why I have to prepend the name. Without it I get errors when RestKit sets up the Entity object mapping. For most Core Data projects you wouldn't use it. I've seen other Swift Core Data tutorials that mention needing that product name there and that is why I started using it. – davidethell Aug 11 '14 at 21:09
  • Still no progress here. I'm having to use a frustrating workaround where I replace all the PRODUCT_NAME prepend on all my entities whenever I want to build the other target. – davidethell Aug 12 '14 at 12:51
  • Using underscores to represent the spaces worked for me – Ali Gangji Apr 23 '15 at 19:19
  • Anyone has a solution for Objective-c ? I have two targets . Both are different purpose apps with same code base. If i install both apps , it uses same db , all data from both apps is inside same db.I want it to be seperate. – Ankish Jain Sep 20 '15 at 06:35
  • @Moritz While I agree with your [rejection](https://stackoverflow.com/review/suggested-edits/21540019) - *"Also, "behavior" is correct. Look in a dictionary."* <- this isn't correct, both "behavior" and "behaviour" are correct and indeed if I were to look in a dictionary I would find "behaviour", not "behavior", it depends on where you are from. – Nick is tired Nov 28 '18 at 14:35

2 Answers2

14

It turns out that the answer does appear to be adding the @objc(ClassName) directive above the class definition in the Swift file as noted in this StackOverflow answer about a related problem. At least it is the answer at this stage with XCode 6 beta 5.

So for an entity class called User you would need:

@objc(User)
class User: NSManagedObject {
    ...

I have tested this in a two-target project and removed all the prefixes from the model entity inspector and it works. I'm wondering why Apple would include the prefix requirement in their documentation since it imposes a restraint on multiple targets using the same core data model. It appears the @objc fix is the proper solution or maybe just a temporary solution during this beta stage.

Community
  • 1
  • 1
davidethell
  • 11,708
  • 6
  • 43
  • 63
  • 1
    Can confirm this works. Very frustrating to find the prelaunch API guide recommend something that didn't work. Thanks – Andy Tsen Sep 13 '14 at 04:34
  • Anyone has a solution for Objective-c ? I have two targets . Both are different purpose apps with same code base. If i install both apps , it uses same db , all data from both apps is inside same db.I want it to be seperate. Will i have to create 2 entities of same model ? – Ankish Jain Sep 19 '15 at 07:48
  • not work for me, same error: unable to load class names "entity.model" – Vasil Valchev Mar 14 '16 at 12:33
  • Did you remove all the prefixes from the class names in the model? If you class is "Attendee" make sure you remove the target name from in front. And be sure you have the @objc() notation in the class file. – davidethell Mar 15 '16 at 14:20
0

I fixed it by using target this way. I am not sure if this is the correct way. I would appreciate corrections. This way it created two different stores and corresponding files.Both app can be on the same device using two different stores.

if(currentTarget==XXX){
    storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Partner.sqlite"];
}
else{
     storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"PartnerNew.sqlite"];
}
Ankish Jain
  • 11,305
  • 5
  • 36
  • 34