List of Items vs. Data Source - ios

When building a view for an iPhone app, one must consider how variable data will be determined by the view. Two design options jump readily to mind:
An NSArray of items
A dataSource property, which implements a protocol and returns the items.
The former is used by views such as UITabBar, while the latter is used by UITableView. What are the pros and cons of these options? Is there a reason for the two distinct paradigms, or is one universally superior?

It's mostly about the amount of data and limited amount of memory in relation to simplicity.
Simpler is always better if you can get away with it. A tab bar probably have less than 10 items which is no problem to hold in memory at once so the simplest solution is the best.
A table view however may have thousands of rows that may contain expensive data like images. Therefor it has a more complex design to be able to keep only the necessary data in memory.

Related

How much memory does one ViewController take?

I would like to know how much memory does a single ViewController take , because when I'm developing some apps I'm still not sure if it is better to create more ViewControllers , or if I should create less ViewControllers and change things in code , instead of UserInterface.
Example of what I mean: Let's say that I have two types of data and I want to see them on presented ViewController, but these two types are almost the same. So should I have only one ViewController and change things in code or I can just create ViewController for every type?
I know that it depends on how much code and how much things are in the UI but let's say that it is a few lines of code and just a very basic ViewController
I have looked into The Role of View Controllers
by Apple but I could not find the answer.
https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/index.html#//apple_ref/doc/uid/TP40007457-CH2-SW1
I know that it's a bit weird , but I'm really curious.
Thanks.
An uninstantiated view controller doesn't use any memory. It's takes a trivial amount of disk space as part of the app, but no memory at runtime until it is created and displayed.
You are currently guilty of premature optimization. Write your code properly so it is easy to write, easy to maintain, and easy to debug. Don't worry about things like memory usage and performance until you have a problem that needs to be addressed.
If you have two different screens with two different types of data, then create two different view controllers.
Once it is working, then run it through Instruments and confirm you have no leaks or reference cycles wasting memory.
The size of extra view controller classes in your code is negligible, so unless you're talking about some extreme number of them, I wouldn't worry about that. The governing principle here is more likely to be DRY. If you've got a bunch of objects that differ in very small ways (e.g. the names on labels, etc.), then perhaps you can create a common protocol to which all of these objects conform, and then you can write a view controller designed for that protocol, rather than any particular object. But if you find yourself adding a bunch of unwieldy if statements and programmatically adding controls, simply to avoid having multiple scenes in your storyboard, then you may have gone too far.

Does it ever make sense to split UITableDelegate and UITableDataSource?

This has bugged me for a long time. There are two delegate protocols defined for UITableView: the actual delegate and the data source. However, given the way the methods are distributed between the two, I'm yet to see a situation when it is practical to implement the protocols in two separate objects. Could anyone give me an example when it actually makes sense to do so?
Short answer: Yes it does.
Long answer:
They are split in 2 different protocols, because they serve different purposes.
The delegate is responsible for managing aspects of the table itself like selection, reordering and deletion of rows, ... UITableViewDelegate Protocol Reference
In contrast to that UITableViewDatasource is responsible for adapting your data model so that it fits the needs of the table. It provides the cells for the table, tells the table how many sections there are, how many rows per section there are, ... UITableViewDatasource Protocol Reference
Depending on your data and what you want to do with the table, that code can become arbitrarily large. If it's getting too large, you can split it up for better navigation and overview. That would be one case I can think of where this distinction can improve code quality.
IMO you don't get any benefits by doing so, as the datasource just provides methods to interact with data, same as the delegate. If your store is big and clumsy, separating the datasource won't solve the issue.
No added value
You can get some unpredictable behavior when forcing the separation:
UITableView issue when using separate delegate/dataSource
How to avoid big and clumsy UITableViewController on iOS?
It depends on the specifics of the app
On the other hand, depending on the app design it may be required to separate the datasource from the delegate:
Lighter View Controllers
UITableView delegate and datasource in a separate class after parsing

Display a medium sized dataset from one table in UITableView

For an app I am creating I am looking for the correct way to display a medium sized records set (around 130 records, with about 13 columns). The data is now in a sqlite database, which I want to use to display in a UITableView. With this quantity of records and columns I think an array is way too memory intensive?
From looking around (and previous experiences) I think I best go for Core Data and use an NSFetchedResultsController, but I am not sure about this. There is no need for the data to be changed or added. So using this might be overkill?
If this is the way to go though, I would love to know what components to use, as I cannot really find an answer to this sort of question.
If this is not the way to go, please point me in the right direction in which I should go.
Core Data is a good match. It can also be used with sqlite as a datastore however you would probably have to reimport your data. The NSFetchedResultsController makes it fairly easy to use a core data collection as a datasource for the table-view. The modeling tools in XCode make it also pretty convenient to create your data structure and creating the NSManagedObject subclasses from it. I would also take into consideration that you might want to extend your dataset or structure in the future and core data has battle tested facilities to assist you with these tasks.
There is a little trick, you needn't select all data from this table and transform into an array, just select data like this:
SELECT `recordid` FROM `yourtable`;
in the delegate method "tableView:cellForRowAtIndexPath:", you can now load all rest data from this record:
SELECT * FROM `yourtable` WHERE `recordid` = [indexPath row];
If your database records is still growing, you can fetch your data by paging query:
SELECT * FROM `yourtable` LIMIT 10 OFFSET 0;
The answer depends on what you need. In particular, if you have to release the application in a day or so, well, refactoring to Core Data would be an obstacle. It has a very steep learning curve so it cannot be digested in a day. On the contrary if you have more time to spend, yes go with Core Data and reuse the know-how in the future.
So, stick with two options here. Stay with plain SQL or just migrate to Core Data. Well, if you have chosen the second, the master component you need is the NSFetchedResultsController.
This class works in combination with UITableView offering a lot of functionalities. One of the most important is to maintain a small memory footprint. In fact, if you work with batch sizes you can take advantage of lazy loading mechanism. Say for example, you want a batch of 20 items. The NSFetchedResultsController will load the first 20 items, if you scroll down, it will load other 20 and so on.
The main problem will be not how to organize your internal data structures, but how effectively present 13 columns of to the user, taking into account very little screen real estate you have on iPhone. Have you thought about that?
There are few options here
you can present just some kind of brief information into main table view and for each cell have detail view with the rest of the information
you can dynamically generate bunch of labels inside each cell and populate them with your data, but now you're really facing space limitation, since you probably won't fit that much of a data in one row. And you also need to create custom headers in your table view (if you need to show header)
or you can invent something else. When I had to deal with very similar issue I went and implemented something similar to Excel "freeze columns" functionality - where header columns is fixed and stays on the screen always and all data columns can be scrolled horizontally and basically go underneath the header. See screenshot attached (note scroll bars around columns with stat data):

Using deep index paths in UICollectionView data source

I am trying to back my UICollectionView's data source with a data structure that (for good reasons) is more than two layers deep. In other words, my data can be broken into sections, but not all of those sections simply contain items. Some contain arrays of items (or "nested sections", so to speak). These items can be easily be referenced with an index path three indices long (3.2.4, for instance), but UICollectionView's data source methods only seem to support index paths up to two indices long.
All of the UICollectionView APIs use NSIndexPaths to reference collection view items, so in theory they should work with any number of indices. The challenge is getting the collection view to "know" to ask for cells, layout attributes, etc. for items at these deeper indices when the data source protocol only provides collectionView:numberOfItemsInSection: and
numberOfSectionsInCollectionView: to specify the indices it needs to ask for.
Is there any way around this that doesn't require me to (a) subclass UICollectionView, which Apple explicitly discourages (second point under "Tips for Implementing Your Custom Layouts") or (b) flatten my data structure, which would be less than ideal, and which seems unnecessarily limited given the APIs UICollectionView already provides?
It doesn't make logical sense in the scheme of a standard collectionView (or tableView) to have a three tier index. I've seen some cool tableviews that have "expanding" cells that work in the same way you're describing. It's just that the object representing the expanding cell tells the table that it has multiple items available.
I can't understand how your collectionView is supposed to look as an end product. If you are encountering arrays at some index paths, what are you trying to represent? I don't want to inform your design but why not just show one item at that particular index, and when a user selects it, expand or show another view with those subsequent items?

Two Tablew in One Screen

I want to have two tables and a webview in one iPad screen from the following:
The first table will parse items from an RSS feed, and will have an option for a
checkmark
The second table will be comprised of all checked items
The webview will be the content from didSelectRowAtIndexPath from the first table (so basically the first table gives the opportunity to display content from didSelectRow, AND check a box (or whatever) to create the secondary table.
I am told for the second table, I should have the checks write to a plist with NSMutableDictionary, and then the second table will just be a table of the plist...but really, what's the code for this?...where do I put it?...etc etc etc. And if the user unchecks the items, the line in the plist will be cleared, right???
I PRESUME I can show all three classes in one screen with something like
[viewController.view addSubview:someOtherViewControler.view];
Is there any reason why I should not do this??
Thanks so much!
XOXO
There is no reason you shouldn't do this, and you will be happier with your proposed approach than you would be if you tried to do it all with one view controller.
Organizing with design patterns is done to simplify design and maintenance of your software. What you have described is clearly three independent data sources each with their own independent views. You can use the MVC design pattern independently on each one of them. This independence lends itself to having separate view controllers that are easy to design and maintain.
The fact that they are collected into one main view for your application is outweighed by the simplification in maintainability that you will obtain with separate view controllers.

Resources