i'm refactoring my app. Currently, I store objects in a .plist for further processing. It works fine, but I thought it was about time to dive into CoreData.
My app fetches data from a web service. This data I parse into individual objects.
I use the properties of these objects to fill Tableviews.
While refactoring, I could just bluntly store the whole object as a transformable with CoreData, as far as I understand.
I could also define an entity with attributes similar to the properties of my object.
Is there any Best Practice here? I think the first approach makes it easier to do the refactoring, but I somehow think I'm missing out on advantages of CoraData in that case. Like maybe performance?
Do not store objects as transformable. You will get just DB where it is not possible to fetch some separated objects based on some criteria. You will need to fetch all DB in memory and than work with it. So it will be the same as plist file and you will waste the effort. Just use entities with proper attributes. CoreData is fast, you don't need to worry about performance.
Transformables are generally a good idea only for attributes that Core Data doesn't know how to represent. They let you use a binary data blob as a fallback, but they're never ideal. They can also be used if you absolutely, definitely, will never ever need to filter or sort a fetch request based on the attribute value. In that case they're still not great, because there's extra unnecessary work.
If you need to (or might possibly someday need to) filter or sort a fetch request based on attribute values, don't use a transformable. They can't be used for either purpose beyond extremely basic stuff like checking to see if the value is nil.
OK, I owe you.
I asked a question without investigating things properly.
The real answer is to understand NSManagedObjects.
Sorry for bothering you
Related
There is no shortage of tutorials on coredata, or questions here on SO about how to get started with coredata, or how to use specific parts.
My question is higher level - how should a larger project be architected with coredata?
Should the project keep most of the functions that deal with managed
objects in a single class?
Should the functions that deal with the
methods be static (I suppose they are called 'class methods') or
instance methods?
Is it ok to pass managed objects into class
methods from different threads? what about if I also supply a
context to the method?
Should I only be doing a single fetch for each entity when the app starts, then doing all of my searches and inserts against the context, or grabbing smaller sets of data from a fetch request as I need it?
As far as the blogosphere goes, it seems like the coredata architectures are the wild west - every man for themselves. Any good design patterns here to follow?
True, although some of you questions are really based on personal preference. I for one will never use a sigleton.
NO and YES. Yes on class to keep the connection to the context and no every controller will request its own data.
Using class methods requires you to either pass the context around or store it in a static. Using a static can cause problems if you need to change the context.
No, each thread should have it's now context. Core Data is not thread save.
To save memory only fetch what is needed, no sense in fetching everything at once.
I would suggest using NSFecthResultsController for filling things like table views.
If you are fetching data and storing it in core data I can really suggest using a separate context for inserting. Cocoanetics has a great article about multiple context setup.
Typically I use Core Data in my applications, but for my current project I don't need data to persist launch to launch.
Because of that, I'm wondering how I should store my data. It's not going to be tens of thousands of items or anything, hundreds at the high end most likely.
I'm still going to create an NSObject subclass to represent each "entry" in the database, but what should I store that in? A simple NSMutableArray that's a property? Should I have a distinct model class? Should I still be using Core Data somehow?
What's the accepted/best practice for a situation like this?
The persistence aspect is only one part of core data. The fetch requests, object graph maintenance and entity modeller are arguably just as important.
If you don't want to persist your data, use the in-memory store type when creating your core data stack.
I would say that if you are familiar with Core Data why dont use it?
But alternatively of course you can stick with NSUserDefault. Atm i'm using the NSCache class.
Good explanation of NSCache and how to use it
Apple's Doc
I would give it a shot if you dont like to use CD for your current Project..
Since you're not worried about persistence, it seems simplest to just use a wrapper around an NSMutableArray (or NSMutableDictionary if indexing is more important that ordering) Since you can apply NSPredicates to arrays you've still got the ability to do very dynamic database style sorting and searching without some of the drawbacks of core data.
Use a wrapper instead of just using an array because that gives you a convenient place to put sorting and searching options, as well as possibly giving you better access to KVO operations.
I have become a great fan of the powerful type system in F# and how it allows you to create some very tight restraints on your domain models (for those interested, see this). I have also become a great fan of RavenDB and how it makes database work very simple in most of the cases I run into. However, there seems to be issues getting the two to play nicely together - at least if you insist on immutable types.
As long as you don't ever have to update your entities, all you need to do is make the id property mutable. While I'm certainly not happy that this is necessary, I can live with it. However, it seems that change tracking is handled in such a way that you must mutate the original object retrieved from the database and it is not possible to attach a new object to the database to represent an updated version of an existing entity. It does seem to be possible to do what I want using the patching API, but the documentation clearly warns against this type of general usage.
Am I missing a part of the RavenDB API that will let me do this without too much fuss or must I abandon the idea of immutable domain models (or perhaps make a feature request for it)?
The problem with immutable in that scenario is that you are actually dealing with mutable data.
The document is being mutated. The fact that you don't mutate it in user space is of little matter here.
What you can do is wrap calls to Advanced.Evict & Store in a StoreUpdated or something like that extension method. But I would call into question the usage of immutable data to represent mutable state.
browsing in some core data pages online i found a tutorial that use an interesting technique, i never seen nor used it before, but actually looks pretty smart.
Instead of working with long methods, with FRC, and so on, they place the results of the fetchResultController in an array, so they can use it to do all the work.
here is the link.
http://www.appcoda.com/introduction-to-core-data/
What do you think are the errors of using this approach? it's a valid one?
It works, but it completely defeats the purpose of the NSFetchedResultsController. The FRC is meant to fetch objects from Core Data in batches, which is much more efficient. If you create an array from all the fetched objects, you will load all those objects into memory at once (if you have a gazillion entities, then this will be a problem). Also if any of your data ever changes (you get notified by the delegate), then you will need to perform the fetch again, then recreate the array yourself.
sorry if the question sounds so weird, but I don' really know how else to put it.
Essentially, my application will a bunch of objects. Each objects has somekind of post/comment structure, the unique thing though is, that it is more or less static, so i figure out it would make no sense to put in every single post and comment into my database, because that would cause more database load? Instead of this, I was thinking about putting the JSON representation of the post with its comments, thus only causing one database access per object. I would then render the JSON object in the controller or view or something. Is this a valid solution?
No!
You loose all ability to query that data at no benefit unless you are at massive scale. The database's job is to pull that stuff out for you efficiently, and if you create the proper indexes and implement the proper caching strategies, you shouldn't have any issues with database load. You want to replace all the goodness of the Rails ORM with your own decidedly less useful version in the interest of a speed gain, waaay before you need it.
What if later you want to do a most popular comments sidebar widget? Or you want to page through the comments, regardless of the post they are associated with, in a table for moderation? What if you want your data to be searchable?
Don't sacrifice your ability to easily query and manipulate the data for premature optimization.
Though it sounds a good idea but I don't think that it will work in the long run thinking of what is going to happen when you have many comments on your posts. You will have to get the long string from the database and then add the new comment to it and then update it in the data. This will be very inefficient compared to just inserting one more comment in the table.
Also, just think what is going to happen, if at some point, you will have to give user the option to update the comment. Getting the particular comment from that long string and then update it will be a nightmare, don't you think?
In general you want to use JSON and the like as a bit of a last resort. Storing JSON in the db makes sense if your information isn't necessarily known ahead of time. It is not a substitute for proper data modelling and is not a win performance-wise.
To give you an idea where I am looking at using it in a project, in LedgerSMB we want to be able to have consultants track additional information on some db objects. Because we don't know what it will be in advance JSON makes a lot of sense. We don't expect to be searching on the data or support searches on the data but if we did that could be arranged using plv8js.