I created a simple data model with a 1-many relationship in XCode 4.1 on Lion.
The type of the property generated for this relationship is NSOrderedSet, which fails to compile because the type is unknown.
I searched the documentation to learn that this is a new kind of collection classes added for Mac OS 10.7 (Lion), especially useful in managed objects (I'm just getting used to the way Apple works: something as basic as a collection type in the language is bound to an OS release... interesting)
This makes sense, NdOrderedSet is apparently a combination of the features of NSSet and NSArray - that is, it has an indexed order like an array, with each element unique like a set. Nice. But, my questions are:
- Why won't it compile?
Why is XCode generating something that won't compile?
I'm going to take a swag at #1 myself: My SDK is iOS 4.3, which predates Lion (and is not Mac OS but iOS) and simply does not have this new collection class.
okay, fair enough, but #2 stands: why did XCode generate it for me? Why not detect my SDK and generate something that works? Why not give me a choice?
This brings me to #3 and #4
What's the workaround? Should I change it to NSSet or NSArray? How did XCode generate these things before 4.0?
If I were to use NSOrderedSet (ie get it to work somehow) would it be backward compatible with prior iOS versions?
Core Data ordered relationships are only available on iOS 5, not iOS 4.3.
You need the iOS 5 SDK which is only available on Xcode 4.2. Switch from Xcode 4.1 to Xcode 4.2 and you should be fine.
3: the workaround is to use Xcode 4.2 and to target iOS 5. If you still want to target iOS 4.x and have ordered relationship, read on.
4: you are unlikely to be able to get NSOrderedSet to work in iOS 4.3. The class is simply missing from Cocoa Touch. So you would need to reeimplement it from scratch, which is definitely doable. What is not doable, is to then get Core Data to use it. So forget it.
Now, it may be worth mentioning that it is possible to define ordered relationships with the "old" Core Data. It requires a bit more work, but it's definitely doable. Here is an example:
Imagine a Meal
and a Course
entities. A meal has an ordered relationship to courses, as courses during a meal come up in a specific order. You don't want to eat your dessert before the main course!
The idea is to define a third helper entity that represents the course membership in the meal. Let's call that entity CourseInMeal
. Now set up the following relationships:
Course <--------->> CourseInMeal <<----------> Meal
Where the double arrow represents the "to-many" end of the relationships.
These relationships basically says that a Course can be present in several meals, and that a Meal can have several courses.
The only remaining this is to represent the ordered relationship. To do so, simply add an attribute to the CourseInMeal
entity, perhaps called position
.
Now when you want to define a new meal you create a new instance of CourseInMeal
for each course in the meal, with something like:
CourseInMeal *newMealMembership = [CourseInMeal insertInManagedObjectContext:self.moc];
newMealMembership.course = myDessert;
newMealMembership.meal = myBirthdayMeal;
newMealMembership.position = 3; // or whatever
[self.moc save:NULL];
Voilà, you have an ordered relationship in plain old Core Data.
I just tried it out. Mine comes out as a NSSet
, not NSOrderedSet
.
Perhaps you should check your project settings, specifically the items under the heading Architecture. (Select Project, Build Settings, Architectures and Base SDK, as well as Supported Platforms).