Reputation: 648
I have created a document-based app that uses Core Data. I created the mac version first, and now that it's working properly, I am moving on to create an iOS version of it.
I just can't get my head around how to maximize code reuse between the iOS/mac versions, with respect to the Core data bit, since they don't use the same classes.
My document class that handles saving and such is a subclass of NSPersistentDocument
. My intention is that a well-designed model class should work in both environments, especially since I don't do all that much fancy stuff with regards to Core data.
Now, since NSPersistentDocument
isn't available in iOS, I hit a wall. I tried to get around this by using #if TARGET_OS_MAC and TARGET_OS_IPHONE
and in that manner make it a subclass of UIManagedDocument
in the iOS version. That obviously would have been convenient, but I can't seem to make it work like that. And it's really looks quite messy, since there are a lot of other stuff that has to be conditionalized as well.
I also tried building the classes atop of NSDocument
/UIDocument
instead, implementing the Core data hooks myself, but it also looks quite messy, leaving me thinking it's not the right way to go.
The question:
To me, it seems like a good idea to reuse the same document class between the iOS/mac versions, but maybe I'm being naive.
What's the best way to do this?
Should I forget about the code sharing and create a separate document class for the iOS version that emulates all the methods present in the mac version?
Upvotes: 4
Views: 905
Reputation: 126117
(Bringing this over from my comment.)
In general, the situation where you have two classes which must inherit from different superclasses but which also want to share a lot of code is composition. Put the shared code in a separate class; your NSDocument
and UIDocument
subclasses can each keep an instance of that class, and message it whenever they need to invoke that shared code. (Though as @noa mentions, you might want to consider whether all of that code belongs in your document class to begin with.)
Of course, then you might end up writing a bunch of methods that read like:
- (id)doSomething {
return [sharedController doSomething]
}
That can get to be a pain... so you might want to look into Objective-C's message forwarding system.
Upvotes: 2
Reputation: 17208
Am I right that the code you're wanting to share is model-related? I suggest refactoring that code to a separate object, which both an NSDocument
and UIDocument
contain (as rickster suggested above).
I use a DocumentRoot
Core Data entity with its own NSManagedObject
subclass, but if there are no properties you want to manage using Core Data, you can just subclass NSObject
.
This may sound strange, but NSDocument
and UIDocument
are actually controller classes. (To be specific, they're part of the model-controller.) Their jobs are to load the model, set up windows, and save the model. If you need to provide an interface for higher-level access to model objects, it could be in a document root or model helper class instead.
Similarly NSPersistentDocument
's job is to configure the managed object context and the persistent store and handle loading and saving. It doesn't necessarily need to provide a complete interface for accessing the model.
Upvotes: 3