Model Object From Both Core Data & External Source - objective-c

I am building an app where my primary model objects can either be fetched from a Core Data store or from an external source (public API via internet - > JSON - > object). I'm new to Core Data so my question is can I just take my model object as it stands now and make its superclass NSManagedObject? I'd guess that I'd need to make sure my model's properties match the names and types of the data model entities for this to happen. I don't want to have to use two different model objects in the app - one when I fetch from the core data store and one when I fetch from the internet API.
Is there anything else I'd need to do to make my already built model objects compatible for use with core data?
Any guidance or advice would be much appreciated.
Regards,
Craig

You can add some business logic to your object (subclass of NSManagedObject) to enable to creation of such an object from data (ie an NSDictionary of values to be used). The crux will be deciding whether you want those objects managed/saved to your local datastore or not.
I highly recommend becoming familiar with NSManagedObjectContext: http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/CoreDataFramework/Classes/NSManagedObjectContext_Class/NSManagedObjectContext.html

What I have done in a couple of products is just deal with core data objects, and initialize them from data that I pull from the web service. That way you only have apples. Another option would be to make a protocol that defines the behavior of the analogous classes. You would be tempted to make one the subclass of the other, but that could get complicated, depending on your persistence requirements.

Related

Bidirectional communication between model objects in Objective C

I have a question regarding programming concepts rather than a specific question relating to some specific code.
I have two model objects, one relating to Core Data and one relating to Twitter.
They need to interact with each other. The Twitter object might want some tweets from the database, whereas the Core Data object might want to write some tweets into the database.
I could write public methods on each of the classes and have each class call those methods.
However, I feel that this is quite a tight coupling and I want to some other method of communication between the objects.
Would a protocol-delegate system be more appropriate in this scenario?
For example, with the Twitter class declaring a TwitterDataSource protocol and the Core Data class acting as the delegate for that protocol. And vica-versa.
Thanks very much,
Vazzyb
You are correct, that coupling would be tight. If you would like to loosen the coupling consider using a Mediator design pattern. As things change you need to only change how the mediator handles the communication between the two objects but not the two individual objects themselves.
(source: devlake.com)
They need to interact with each other. The Twitter object might want some tweets from the database, whereas the Core Data object might want to write some tweets into the database.
Let me stop you right there. That is a terrible design pattern no matter who you are. Your separation of powers, instead of making your life easier, has created a divide in your project that you now have to remedy by making each object reference each other. Both of the activities of these objects falls under the concept of a controller, anyhow. The first can be refactored out into an asynchronous operation, especially if it requires informing the database controller that it's finished. Instead of considering a delegate, write an NSOperation subclass that writes to the database (serially, of course), and make the database controller mediate both the result of the operation, and the tweets that come in from the other object that get written into the database. No more mutual references (this is not bidirectionality), no more dual-controller objects, no more hassle.

What common methods are employed to separate data storage from algorithms?

Say you store all your data in a class, likeKittenStorage. You then have a class that wants to find a specific color kitten, probably called KittenFinder. Obviously, you have designed your object oriented program to separate these two distinctly different classed, but now KittenFinder needs to directly interact with KittenStorage. How do you connect these two different classes?
You need to use layers. First of all, you need a Data Access Layer. This layer will contain classes which support direct data storage commands. Next, you need a Business Layer. This Layer performs anything needed to be performed in your business logic. This layer will use the data storage via the Data Access Layer. Optionally you can create an Engine Layer where some more complex algorithms might be implemented, which will communicate with the data storage via the business layer. Finally, you have the UI, which will communicate with your data storage through the Engine Layer or the Business Layer. In real-life your storage is a database and your Data Access Layer communicates with the database. I hope this was helpful.
Depends, some would put a Find Method on KittenStorage that returned a kitten.
Assuming KittenStorage is a Store for Kittens
And KittenFinder is a Finder for a Kittens or Kittens(s) in a KittenStorage
And that Kitten is a Storable and Findable Item
That also has some behaviours e.g. Scratch, that are nothing todo with it being storable and Findable, then Kitten would be linked to KittenStorage by IStorable, and KittenFinder to KittenStorage by IFindable
There's also a good reason to have a DTO (Data Transfer Object). Which would be simply Kitten's state, ie what you are finding and storing aren't Kitten's that scratch
Basically all the above is making the assumption that there's also a PuppyStorage and PuppyFinder etc, and that you want to be as decoupled as you can.
Lets evolve your example a bit - lets say that KittenStorage gives you a indexed access to the kittens in the form of storage.get(0) or storage[0], and that it also has a count or size property toknow how many kittens it stores.
This way KittenFinder can be implemented to do forward search i.e.
for (int i = 0; i < storege.size; i++)
{
//return kitten if matches
}
or it can do a BinarySearch
Also the KittenStorage class may include an persistence mechanism (like saving kittens to DB, or file). Maybe it can contain a perisitance strategy - a different class so that persistence mechanism could be swapped.
This is called Separation of Concerns - A class should do only one thing and only in one way - this way it's easy to maintain code.
In general terms, KittenFinder has a "dependency" on KittenStorage. Your question is how to set (inject) this dependency. That goes to your choice of application framework. Spring framework is one popular way of doing this.

Should we create Model Classes when we use Core Data?

I am working on an iPad application, that requires me to store data locally if the user doesn't have internet access and later on sync with the back-end database.
For local storage, I am planning to use Core Data with SQLite.
I am using Core Data for the first time and it seems, it retrieves entity and store entity in the form of a dictionary.
So should I be creating Model classes at all ?
What is a good design for such application.
I have a DataEngine class whose responsibility is to store entity on a server or local DB based on connectivity.
Now I am little confused If I need to create a Model class and ask individual model classes to save themselves using NSMangaedObjectContext with a dictionary representation Or just directly save data instead of creating a model object and asking it to do it ?
Should I be using a Moel class for each entity and that will server as interface between JSON representation that coms/goes from/to server.
and the representation I get from managedObjectContext.
Or shall I compeletely rely on the entity and relation ships that Core Data creates ?
I'll do this backwards: first some things for you to check and then some ideas.
Check my own question.
I'd say that on your custom categories you can do the interface between the JSON representation and your classes.
You should also check RestKit which can do already much of what you need.
You're talking about two separate problems as far as I can understand:
Syncing local data to the server based on connectivity;
Using model classes.
Problem 1
I think you should have a class with the common code and each of your model classes should have its own mapping (to map between model and JSON) and saving methods.
Another class, that may be your DataEngine class, takes care of saving the right objects at the right time.
Take a look at RestKit as it helps with the mapping and the saving. I'm not sure about the syncing though.
Problem 2
I think you should have model classes. It helps a lot to work with objects and you have then a place to save methods for finding different kinds of data.
For this my question might be useful for you because you can create a CoreData model with generated class files and update it whenever you want while keeping your custom code.

Model View Controller: Does the Controller or Model fetch data off the server?

For example: Let's say I'm grabbing a list of names and saving it to an NSMutableArray. Do I implement the method of actually calling the server to fetch the data in the controller (UIViewController) or the model(Friends object)?
It's a design decision that depends on what you're trying to accomplish. If your model only makes sense in the context of a single service, or if you want your model to provide access to all the data on the server, then build the connection to the server into your data model. This might make sense if you are, for example, building a client for a service like Twitter or Flickr.
On the other hand, if you're just grabbing a file from a server and that's the end of it, it may make sense to do the communication in the controller. Controllers tend to be less reusable and more customized for the particular behavior of the application. Keeping the specifics about where the data comes from out of the model makes the model more reusable. It also makes it easy to test -- you can write test code that just reads a local file and stores the data in the model.
That's a good question. I think the best way is through a controller because it decouples your model from requiring the other model to be present for it to work properly. Although I don't think you violate "proper mvc" by doing it in the model either.
I think you want to put it in the model. What you'll do is interrogate the model for the data and then the model will handle how to populate itself whether it's from an internal data store or an external one (like a server).
One approach is to use the repository pattern. To do this, you create Repository objects in your Model folder and you place all of you database-related methods in them. Your controllers call the repository classes to get the data. This allows you to separate the real model objects from the database accessing methods.
I use the MVCS pattern (Model-View-Controller-Store), which I discovered in Aaron Hillegass's book "IOS Programming: The Big Nerd Ranch Guide" (http://www.bignerdranch.com/book/ios_programming_the_big_nerd_ranch_guide_rd_edition_)
The store is specifically designed to fetch the data, whether it comes from a server, a local file, a persisted collection, a database, etc.
It allows to build very evolutive applications. For example, you can build your application based on a web service, and the day you want to persist your data, you juste have to modify the store, without having to modify a single line of code in your controller.
It's a lot like the Repository Pattern (http://msdn.microsoft.com/en-us/library/ff649690.aspx) (cf BobTurbo's answer)
I'd personally make a DAO, or data helper class. It's very hard to follow the strict MVC in objective C when things get more complicated. However, putting it in the model or the VC is not wrong as well.

How can I serialize Petrel Property in my Custom DataSource and load it back?

I am not very "fluent" with Ocean serialization .
Can I serialize an entire Petrel Property (Properties, Grids or any other Petrel/Ocean's objects) into my custom DataSource? Will I be able to load it back?
Is there any good practice/pattern to do that?
Some code sample would be welcome!
Do you have an established DataSource already? The persistence back end (SQL? XML?) used by your DataSource dictates how data is stored. Any data you want to persist through the DataSource must be converted to your back-end's format.
Note that there is no such thing as "Ocean serialization" with DataSources - you (and only you) are in complete control of the DataSource. Usually, you are actually providing it as a service to Ocean, so that it, given a Droid, can resolve one of your objects (be they e.g. custom domain objects, workstep argument packages or seismic attribute argument packages).
Now, from your question, it sounds like you are seeking to store deep copies of the Petrel data you mention. Is this really the case? If so, I'm afraid you'll need to make your own data structures representing this data, mirroring what you can read out through Ocean's APIs.
If what you really want to store is a weak reference to the Petrel data (implementing IIdentifiable), you'll want to persist the contents of each object's Droid - a much simpler task.
Then, when your persisted data is resolved from your DataSource, you'd rebuild the Droid(s), which can then be resolved themselves (using some other DataSource but your own), resulting in a regular strong .NET reference to the object - assuming of course that this data is present in the currently loaded project.
The SimpleDataSourceExample in the Ocean SDK demonstrates a simple DataSource backed by a .dat file using BinaryFormatter. This is relatively trivial to modify to other back-ends. I strongly recommend XML over BinaryFormatter, but if you intend to store considerable amounts of bulk data, you should consider a database. At Blueback Reservoir, XML has served our needs very well.
A minor caveat: make sure that the objects you store in your DataSource implement IDisposable (as well as IIdentifiable), to free resources in the DataSource.