About usage framework coreData - ios

What is the best way to use CoreData:
1 - The first time I load all items from the store in the array, in the future, when I have to get one item (or more,meet certain properties), I just do filtering array (filteredArrayUsingPredicate)
OR
2 - Every time when I need to get the items (one item or several or all items) I load those games all from the repository?
When I am asking what is the best way, I actually mean what is the most efficient and most common way (quickest response time)?

Use MagicalRecord library. It has convienience methods like:
MR_findAll
MR_findFirst
MR_findFirstByAttribute and many, many others.

Don't use data arrays, and don't use 3rd party libraries.
Rather, read up on NSFetchedResultsController and discover how simple and scalable core data can be.

Related

How to use NSCache appropriately in iOS application?

I am building an application and want to use NSCache to store data for caching.
There will be approx 5 API for which I need to cache data. Should I user NSCache? I did research for NSCache but I have some doubts regarding this.
I did go through below link.
https://developer.apple.com/library/content/documentation/Performance/Conceptual/ManagingMemory/Articles/CachingandPurgeableMemory.html
I found some interesting things there.
NSCache provides two other useful "limit" features: limiting the number of cached elements and limiting the total cost of all elements in the cache. To limit the number of elements that the cache is allowed to have, call the method setCountLimit:. For example, if you try to add 11 items to a cache whose countLimit is set to 10, the cache could automatically discard one of the elements.
If we set limit to 10 and if we try to add 11th item then which particular item it will discard that is 1st one or 10th one? Or it can be a random item.
If I want to store 5 different NSCache object for all APIs then how can I do it?
I should make 5 different NSCache objects or I should store 5 different dictionary in single NSCache object?
Please let me know the best way to deal with it.
NSCache works basically as an NSMutableDictionary, the main difference is that even if is mutable is thread safe (usually mutable NSFoundation objects are not thread safe). So you get and set objects using keys.
Yes, the documentation is not clear, but I remember (and it makes sense) that is written that you should always detect if an object is cache and if not reload it from your primary source or manage that particular case. So it is not very important which one is removed, just make sure that at some point an object can not be there anymore and you are managing that situation.
I usually create different caches based on different context, but most of the time one would suffice.
I have few advices:
Your answer is tagged as Swift, thus pay attention that NSCache (in swift 2, don't know in 3) works only with objects and not struct or enumerations (value types unless thay can be bridged).
Remember that http protocol has its own cache system and communication, do not reinvent the wheel

Realm for iOS. Lazy data loading?

I am trying to use Realm in my new project.
But am interested in:
I have 10k objects of MyType.
And I want to filter and display only most recent 10 of them.
Will all of them be moved to RAM to operate/filter them?
'realm.objects(MyType).filter(...)' - I'm just worried about 10k objects and their data would litter the app memory in case of query like above.
No? It's OK?
When you filter objects, your query is constructed in a C++ DSL, which is efficiently evaluated, bringing in some optimizations to run it fast depending on the concrete property types.
Accessor objects are instantiated by the binding lazily when you retrieve each object out of your results. So in your case only for the first 10 objects.

NSKeyedArchiver vs Core Data

I am building an app with Objective-C and I would like to persist data. I am hesitating between NSKeyedArchiver and core Data. I am aware there are plenty of ressources about this on the web (including Objective-C best choice for saving data) but I am still doubtful about the one I should use. Here are the two things that make me wonder :
(1) I am assuming I will have around 1000-10000 objects to handle for a data volume of 1-10 Mb. I will do standard database queries on these objects. I would like to be able to load all these objects on launching and to save them from time to time -- a 1 second processing time for loading or saving would be fine by me.
(2) For the moment my model is rather intricate : for instance classA contains among other properties an array of classB which is itself formed by (among other) a property of type classC and a property of type classD. And class D itself contains properties of type classE.
Am I right to assume that (1) means that NSKeyedArchiver will still work fine and that (2) means that using core Data may not be very simple ? I have tried to look for cases where core Data was used with complex object graph structure like my case (2) on the web but haven't found that many ressources. This is for the moment what refrains me the most from using it.
The two things you identify both make me lean towards using CoreData rather than NSKeyedArchiver:
CoreData is well able to cope with 10,000 objects (if not considerably more), and it can support relatively straight-forward "database-like" queries of the data (sorting with NSSortDescriptors, filtering with NSPredicate). There are limitations on what can be achieved, but worst case you can load all the data into memory - which is what you would have to do with the NSKeyedArchiver solution.
Loading in sub-second times should be achievable (I've just tested with 10,000 objects, totalling 14Mb, in 0.17 secs in the simulator), particularly if you optimise to load only essential data initially, and let CoreData's faulting process bring in the additional data when necessary. Again, this will be better than NSKeyedArchiver.
Although most demos/tutorials opt for relatively straight forward data models (enough to demonstrate attributes and relationships), CoreData can cope with much more sophisticated data models. Below is a mock-up of the relationships that you describe, which took a few minutes to put together:
If you generate subclasses for all those entities, then traversing those relationships is simple (both forwards and backwards - inverse relationships are managed automatically for you). Again, there are limitations (CoreData does the SQL work for you, but in so doing it is less flexible than using a relational database directly).
Hope that helps.

ios UITableView with fetchedresultscontroller - add custom rows

I have a UITableView with data coming from NSFetchedResultsController.
Here is my tablewView:
I need to add a row "All types". It also needs to be:
Sortable with all other items
Selectable (Design is now selected)
Selecting "All types" should deselect other rows
Give something to understand that it's an "All types" row when selected
I've read Add extra row to a UITableView managed by NSFetchedResultsController and NSFetchedResultsController prepend a row or section. Given approaches makes impossible to sort data or will look so hacky and produce so much hard-maintailable code, that it will be impossible to change logic and maintain code.
Are there any other good options?
PS. I understand, that my question may sound "broad" and doesn't containt code, but I think it's very common problem.
I do not think this is a very common problem at all. I can see it seems natural to do what you are trying but lets analyse your situation: What you generally have are 2 arrays of objects which you wish to sort as a single array. Now that is quite a common situation and I believe everyone knows how to solve this issue. You need to create a single array of objects and then sort it.
The way I see it you have 3 options:
Fetch all the items, merge the 2 arrays, sort and present them. This is not a very good idea since your memory consumption can be a bit too large if there are a lot of items in the database.
Put the extra data into the database and use a fetch result controller as you would normally. This should work good but you will probably need to mark these items so they are later removed or keep it in the database but ignore them where you wish not to display them.
Create a temporary database combined with what needs to be fetched from the database and your additional data. This approach is great if your data are meant for read-only in this list (which actually seems to be the case in what you posted). Still it is best if you create some kind of link between the objects. For instance some kind of ID would be great, this way when user selects an object from the second database you simply read the ID and fetch the object from the original database.

Is it ever preferable to sort GUI elements instead of sorting the data and have the GUI show the sorted data?

A related question about sorting may be relevant to answering this one. I've realized that VirtualTreeView offers a sorting method of it's own, but it seems to work slower than just sorting through the data itself, and letting the GUI refresh.
Is it ever "good practice" to manipulate GUI elements instead of the data that they display, and why?
Typically you want to maintain a separation between the underlying data and the visual representation of that data. With that in mind, one would typically prefer to implement sorting at the GUI level rather than lower down at the data level.
For example, this allows you to show multiple views of the same data, differently sorted. That's the sort of benefit you reap from maintaining clear separation between model and view.
In your case your implementations of the two options have shown a performance difference. What I would take from that is that it is possible to optimise your sorting when implemented at the GUI level. That's how I would approach the problem.
I would not sort the data, just an index. You say you collect data in lists and these lists are then grouped in a grouplist. Instead of sorting the data, I would leave the data as they are and generate a simple list (or lists) with references to the data and sort that. Use that list to populate the virtual listview.
That would be the kind of intermediate layer David mentions. By keeping several indices, you can sort on different criteria without having to sort the underlying data.

Resources