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

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.

Related

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.

How much does Core Data store?

Just a small question I can't find an answer to.
If I add a data model, including all attributes for each class, and generate core data classes for these, I can of course get everything to persist.
But I can also add non-core data attributes to a class. Will these persist also? Simply by virtue of belonging to a stored object? Will it be any different for basic data types vs objects?
I would assume these will not be saved, but thought it was worth checking.
No. Core Data only saves modeled properties. It's perfectly fine, and often desired, to add additional properties to your NSManagedObject subclass, but they'll behave just like properties on any other object and will not be saved to disk.

Save MKOverlay objects in Core Data

I have a large MKOverlay that I would like to be saved in Core Data so that I don't have to create it later. Since this isn't one of the types that you can choose in Core Data, how do I go about saving it?
Do I need to somehow encode it first?
Do I then need to decode it when using?
What kind of object do I select in core data when creating a new property?
Thanks guys.
If you do not need to query for different overlays and you're not using core data elsewhere in your project, then you're probably better off caching the overlay on disk as an encoded NSArray.
However, if you're already using Core Data or you're caching multiple overlays then you can encode/decode the overlay in a field of type NSData. Add additional fields to the entity so you can query for the specific overlay you're looking for.
In iOS 5, you can enable optional storage of NSData fields in an external file by selecting the "Allows External Storage" option. Core Data will apply a size-based heuristic to determine if a blob or external file will result in better performance.
MKOverlay conforms to NSCoding, so you can encode and decode an entire array of MKOverlay objects using an encode method of NSKeyedArchiver and store the result in a binary field in your entity. You'll likely want + (NSData *)archivedDataWithRootObject:(id)rootObject on NSKeyedArchiver and + (id)unarchiveObjectWithData:(NSData *)data on NSKeyedUnarchiver
See the Archives section in the Archives and Serializations Programming guide for details of creating a keyed archive at: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Archiving/Articles/archives.html
You can write a custom accessor for the entity's binary field that encodes and decodes the overlay array for you. Another option is to create a value transformer that encapsulates the encoding and decoding operations. The end result would be an overlays array property that you can set and read via entity.overlays.
I believe you can use Apple's NSCoding libraries to convert the object to and from a serialized state. However, Core Data may support saving objects, but NSCoding lets you save any class that implements it anywhere, including a string sent to a server, a file written to disk, or if you're as bad a programmer as me, an NSUserDefaults entry.
edit- You may have to implement NSCoding into your own class based on MKOverlay by adding read and write methods, I'm uncertain.
Why not instead save the properties (size, color, coordinates, etc can all be described with NSNumbers and those can be stored in Core Data natively) and recreate the MKOverlay when needed. I think that's a much more efficient approach to be honest. I'm not sure how much of an impact creating an object has, so prove me wrong if I'm wrong.
You need to take the large dataset that composes the overlay and turn those individual data nodes into NSManagedObjects to be stored in CoreData.
I mean, you probably COULD just NSCoder the entire thing into one giant datablob, but at that point, you might as well just write the thing to a flat file (which frankly might be better if all you want to do is read/write it without changing it).
Don't use Core Data unless you're going to be doing legit querying or piecemeal changes to the dataset.

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.

Model Object From Both Core Data & External Source

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.