I've been dealing with Core Data for the first time and I wanted to know what the best practices are for extending the classes that Xcode generates for my NSManagedObject entities.
I saw mogenerator and I've been also using a similar approach to that as suggested in SUPER HAPPY EASY FETCHING IN CORE DATA.
So I had three kinds of classes:
The EasyFetching category (only one class);
A generated NSManagedObject subclass (i.e.: _Entity);
A custom subclass with some custom methods like finding all the inactive objects, clearing the cache for an object, etc. (i.e.: Entity).
This approach let me do some custom code while I could refactor my Core Data entity and generate it as many times as I needed. But I've also run into some problems like not being able to declare object level methods for my entities (because the NSManagedObjectContext only knew my _Entity classes).
Now I'm using categories to extend my entities functionalities. And this works a lot better because I can have custom object level methods. I now have three kinds of classes:
The EasyFetching category (as it has a lot of methods that all my custom code uses);
A generated NSManagedObject subclass (i.e.: Entity);
A custom category for my NSManagedObject entity (i.e.: Entity+Custom.h).
My question is: what would you recommend?
Thanks in advance for your answers
Now that you have posted your question as an answer on my question,
I thought I should answer your question :)
Mogenerator doesn't look bad, give it a try.
Also the way you suggested with categories is also a fine option.
Infact here is a link that exactly explains How to do so.
Related
I would like to know if anyone knows if it is possible to subclass a Core Data Model.
In my case I am developing a library that I would like to use in 2 projects. Both projects have nearly the same Data Objects that i would like to outsource into the library, because there are some classes and methods in this library which requires to know about the existence of these Entities.
Some ideas on that?
It would probably be more stable through future releases to add a Category on NSManagedObjectModel, instead of subclassing it.
I need to serialize a Core Data class (Questionnaire) which has a to-many relationship (questions) to an abstract entity (Question).
Question is the parent entity for a number of concrete subclasses (BooleanQuestion, ClosedQuestion…), each of which has an RKManagedObjectMapping.
How can I set up the Questionnaire mapping to serialize this polymorphic relationship?
If it was not polymorphic, I would do:
[questionnaireMapping mapRelationShip:#"questions" withMapping:[questionMapping inverseMapping]];
But I can't do that: questions will not be of any single class, so there isn't a single mapping to pass.
Moreover, Question being abstract, doesn't even have a mapping (though I could define one).
How can I handle that with RestKit version 0.10.3?
Note that I am very close to releasing my product, and I am really reluctant to migrate to RestKit 0.20 this late in my product cycle.
I guess I could aggregate all concrete Question subclasses into Question, making it concrete and monomorphic (and monolithic). That would be ugly (though I believe this is precisely what Core Data does with SQLite behind the scene).
Anything more elegant?
Thanks
JD
Upgrading to 0.20 wouldn't help anyway as I don't believe this situation is covered there either.
I would recommend you to implement a method (or just use KVC) on each of the classes in the hierarchy which returns a dictionary of the keys and values. This can be done efficiently using KVC -dictionaryWithValuesForKeys:. The list of keys should be the union of all keys for all classes. Now you can build an array of dictionaries which can be mapped. You would also need to implement KVC -valueForUndefinedKey: to prevent exceptions during this process.
Now, on your Questionnaire class you can implement a method to loop over the questions relation contents and build the list of dictionaries. Say the method was called encodedQuestions, your mapping would be something like:
[questionnaireMapping mapRelationShip:#"encodedQuestions" withMapping:questionDictMapping];
I haven't actually tried doing this so there is a question about the reflection RestKit uses on Core Data objects and how happy it will be taking your relation mapping.
I've recently discovered categories and was wondering when it might be appropriate to use them in a user defined class/new class. For example, I can see the benefits of adding a category to an existing class like NSString, but when creating a new class what would be the advantage of adding a category to this rather than just implementing a normal method?
Hope this makes sense.
Many thanks
Jules
The answer isn't really any different for your own classes than it is for framework classes. If you have multiple projects, you'll likely end up sharing some classes between them. However, you may want to extend some of your classes so that they work more easily with a specific project, but not want to include those extra methods in your other projects, where they might not make sense. You can use a category to extend your class without needing to subclass.
If I understand your question correctly, creating a "new class" is always "subclassing" because you're subclassing NSObject at the very least.
You could use categories on a new class to separate out sections of responsibility of a complex class. For example, all the basic functionality (instance variables, accessors, description, etc.) can go in one file (the "main" class file) while all methods to support a protocol (such as NSTableViewDataSource) can go in another.
Some take this approach to keep things "neat". I'm a firm believer in "if it's my own custom class, all its code should be in one file" so I do not personally do this. I demarcate different logical aspects of the class' code with "#pragma mark Some Section Name" to help navigation and readability. Your mileage may vary.
Adding a Category on NSString is useful when you want to call a method on every single NSString instance you will encounter. This is a real improvement over inheritance for this kind of object because they are used by the core framework and you don't have to convert a NSString object to your subclass when you want to call your custom method.
On the other hand, you can just put methods in, no instance variables.
In the book Refactoring by Martin Fowler, he has a section titled "Introduce Foreign Method" (A server class you are using needs an additional method, but you can't modify the class.) That's what categories are good for.
That said, there are times when using a category, instead of changing the class, is appropriate. A good example on using a category, even though you could change the server class, is how Apple handled the UIViewController MediaPlayer Additions. They could have put these two methods in UIViewController itself but since the only people who would ever use them are people who are using the Media Player framework, it made more sense to keep the methods there.
I had a bunch of objects which were responsible for their own construction (get properties from network message, then build). By construction I mean setting frame sizes, colours, that sort of thing, not literal object construction.
The code got really bloated and messy when I started adding conditions to control the building algorithm, so I decided to separate the algorithm to into a "Builder" class, which essentially gets the properties of the object, works out what needs to be done and then applies the changes to the object.
The advantage to having the builder algorithm separate is that I can wrap/decorate it, or override it completely. The object itself doesn't need to worry about how it is built, it just creates a builder and 'decorates' the builder with extra the functionality that it needs to get the job done.
I am quite happy with this approach except for one thing... Because my Builder does not inherit from the object itself (object is large and I want run-time customisation), I have to expose a lot of internal properties of the object.
It's like employing a builder to rebuild your house. He isn't a house himself but he needs access to the internal details, he can't do anything by looking through the windows. I don't want to open my house up to everyone, just the builder.
I know objects are supposed to look after themselves, and in an ideal world my object (house) would build itself, but I am refactoring the build portion of this object only, and I need a way to apply building algorithms dynamically, and I hate opening up my objects with getters and setters just for the sake of the Builder.
I should mention I'm working in Obj-C++ so lack friend classes or internal classes. If the explanation was too abstract I'd be happy to clarify with something a little more concrete. Mostly just looking for ideas or advice about what to do in this kind of situation.
Cheers folks,
Sam
EDIT: is it a good approach to declare a
interface House(StuffTheBuilderNeedsAccessTo)
category inside Builder.h ? That way I suppose I could declare the properties the builder needs and put synthesizers inside House.mm. Nobody would have access to the properties unless they included the Builder header....
That's all I can think of!
I would suggest using Factory pattern to build the object.
You can search for "Factory" on SO and you'll a get a no. of questions related to it.
Also see the Builder pattern.
You might want to consider using a delegate. Add a delegate method (and a protocol for the supported methods) to your class. The objects of the Builder class can be used as delegates.
The delegate can implement methods like calculateFrameSize (which returns a frame size) etc. The returned value of the delegate can be stored as an ivar. This way the implementation details of your class remain hidden. You are just outsourcing part the logic.
There is in fact a design pattern called, suitable enough, Builder which does tries to solve the problem with creating different configurations for a certain class. Check that out. Maybe it can give you some ideas?
But the underlying problem is still there; the builder needs to have access to the properties of the object it is building.
I don't know Obj-C++, so I don't know if this is possible, but this sounds like a problem for Categories. Expose only the necessary methods to your house in the declaration of the house itself, create a category that contains all the private methods you want to keep hidden.
What about the other way around, using multiple inheritance, so your class is also a Builder? That would mean that the bulk of the algorithms could be in the base class, and be extended to fit the neads of you specific House. It is not very beautiful, but it should let you abstract most of the functionality.
I'm creating an app that has a master-detail interface, similar to iTunes. It has the same data hierarchy as iTunes' playlists (except that I'm not allowing groups of "playlists" to keep things simple). In other words, there are normal playlists where their only items are added manually by the user. There are smart playlists, which show all items that match a user-defined predicate. Finally, there are some "playlists" that are not editable at all by the user (I call these DefaultFolders), but are in essence nothing more than fancy smart playlists in that their predicate is to show everything. These are like the "Library" and "Movies" sections in iTunes.
In my attempt to recreate this structure, I've come up with the following hierarchy (in Core Data): http://gallery.me.com/davedelong#100084/Screen%20shot%202009-11-07%20at%207.17.53%20PM&bgcolor=black (hopefully it is self-explanatory)
However, as I've gotten further into this app, this structure has become a little cumbersome. For example, I defined an accessor on the AbstractFolder class called -(NSSet *)items, so that all concrete folder types (DefaultFolder, SmartFolder, and Folder) can easily retrieve their contents. This coincides with the relationship that the Folder entity has with the Item entity. However, I can't implement the items accessor in AbstractFolder, because that would override the generated accessor provided by Core Data for the Folder entity. I've thought about making it part of a protocol that all concrete folders would implement, but that seems to defeat the purpose of inheritance.
So I open this up to the collective wisdom of the mailing list. Is there a better way I could model this structure? Have any of you worked on apps with similar structures? What did you find helpful?
Sorry, I haven’t used Core Data that much, but it’s not clear to me why you need to implement the items accessor in AbstractFolder? Can’t you just stick it in a category in the header and not bother to implement it? This is the standard approach for abstract methods.
For example, in AbstractFolder.h, you’d have:
#interface AbstractFolder (Abstract)
NSSet *items;
#end
and then you don’t bother to implement it anywhere—which will force the subclasses implementation to be used.
I've come up with a structure, which I detail in this answer: https://stackoverflow.com/questions/1812311#1812924