Model NSArray mutable or immutable? - ios

I never realised this dichotomy before so I need to ask you.
Let's say we have some kind of model manager class that will expose an NSArray of objects via public property. This is our model.
Now I also have a view controller that shows members of this array in tableview cells.
I set this NSArray as a datasource for tableview. But what if I want my model change data in time?
I have two options.
1) Make the array mutable.
2) Replace the instance NSArray with a different instance containing new data.
The issue with option 1 is anybody can change array's content which seems wrong.
The issue with option 2 is the tableViewController will happily keep pointing to the original array instance and ignore that the manager class is now pointing to a new instance (since it replaced it's property array instance with one having updated data.).
To sum it up, I want an array instance that can only be mutated from the model manager, but would be immutable to outside world. Which is impossible right?
Any ideas how to solve this problem?

Either the object managing the array should also be the table view's data source or the table view's data source should always make sure to get a fresh copy of the array from the object managing the array just before the table view reloads its data.
Either way, the array that the table view's datasource is working with should, in the end, be an immutable array, and any time this array is changed, a call to reloadData should immediately be made.
This will prevent the data in the array being modified in the middle of the table view displaying data. It's very problematic if the contents of the array change after numberOfRowsInSection: has been called, for example.

Related

Any way to group items by property in UITableView in runtime?

I have a UITableView which I populate by a list of objects I'm getting from a Realm database. What I want to do is to create sections and group items in the list by a property value in runtime.
All of the examples of grouping items in UITableView I see online are operating with it a prearranged dictionaries.
Is it possible to do?
You can set up your table view data source any way you want. You could write code that decides on the fly which items belong in which sections, but I would advise against it.
I would suggest setting up a method that takes your list of Realm objects as input, and builds an array of sections containing sub-arrays of the rows. Then your cellForRowAtIndexPath method can simply index into your model data like normal.

xcode = I sended data from one view to the other, with prepareForSegue, but can't send it to another view in prepareForSegue

I have a problem. First I sended information from textfield with prepareForSegue. I sended from WelkomViewController to TableViewController. There I put the data in a NSMutableDictionary. It's a person and his values. Then I put the person in another NSMutableDictionary for multiple persons. In the tableview I create a list with only the full name of all the persons. And with a click on the row I want to give a new view with the details of the person that the client clicked on. But I can't send the data with prepareForSegue it seems.(see image)
What do I do wrong? Thx for every reply!
project
You're trying to use a dictionary like an array, which doesn't work (obviously). You should not count on a fixed order for [self.personen allKeys], it can change at any point during runtime, which would result in the wrong person being passed along.
You need to use a mutable array as your storage vessel for people names, then address them by the row of the index path.
First of all you need to use NSmutablearray to save data of people so make sure that self.personen is an NSmutablearray then you need just to use ObjectAtindex function to get the selected row .
vcGevensView.persoon=[self.personen objectAtIndex:indexPath.row];

iOS Swift How to Extract Strings from All Selected Rows in a TableView

I want to loop through a TableView and extract the text from all the selected rows. I suppose I "could" create and maintain a special array that is updated every time a row is selected/deselected using the didSelect/didDeselectRowAtIndexPath methods. But creating a separate array seems like an extra step. Is there no way to let the TableView itself serve as the array and then simply loop through it and get the selected rows? What would the code look like? I'm new to Swift, so this might be a silly question.
Part of the problem is that cells are supposed to be reused, and when used this way it is not possible to loop through them all. You could get around this by using a unique reuse identifier for each cell, such as the indexPath itself or some underlying unique id in your model. Then, you could indeed loop through all cells and retrieve whatever state you desired from each.
You would, however, find your application crushed under the weight of too many cells being instantiated and kept in memory. If you don't have many cells you won't be killed, but try it with a big data set and your app will enjoy a very quick death.
It is far more efficient to store one array with a bunch of id's than a large number of memory-intensive UITableViewCells.
As mentioned in comments, you should work with underlying datasource, not the table itself.
For example if your table shows rows from Array, it is way more faster to retrieve strings directly from that array than creating UITableViewCells and get strings from them.
Get indices of selected rows using UITableView's property indexPathsForSelectedRows.
Query datasource for each row.
As has been said the tableview only handles displaying, your datasource is what powers the data shown if you think about it.
Plus as said before the tableview dequeues cells as they scroll on and off the screen.
The best way to achieve what you want is to add a property to your datasource for each element that will allow you to filter out the select properties easily.
How are you storing the state for each selected cell currently? As this is the same functionally you would use to be able to generate your selected text array.

Select cells from array UITableView

I have an array of users
var selectedUsers = [User]()
users are added to this array as they are selected in a UITableView (see screenshot: https://www.dropbox.com/s/uk03mhgi3x4jesy/File%2006-10-2015%2C%2018%2003%2044.png?dl=0)
What I'm having difficulty with is when I press back and then reload the view controller, all the checkmarks disappear.
Is there anyway I can keep track of the selected cells?
Thanks in advance
You could use a delegate to pass a array between the two viewcontrollers. For example, each time you select a row, you can store the userId's associated with the row, in the array. So if you were to press back and then open the view with the UITableView, before you load the UITableView, you can first check if there is an array being passed to the viewcontroller containing the UITableView / if there is an array, check if the count is greater than 0. If the array is not empty, then use a for loop to cycle through the array of users being displayed with the array being passed containing all of the previously selected id's, then add the check marks that match up to the Id's in the array.
Here is a tutorial that possesses a similar example: http://makeapppie.com/2014/08/04/the-swift-swift-tutorial-why-do-we-need-delegates/
The answer to this question is kinda dependent on what you want the application to do... Do you want the User selections to persist even if the app is closed? If so consider using NSUserDefaults or CoreData. Otherwise store the data somewhere that does not get blown away (maybe the root view controller of your application). You could for instance implement the delegate pattern on the view controller with the table view and pass the values to the container view controller.. Just some ideas.
So you can use class NSUserDefaults to save small amount of data. If you want to have persistent store so you have to use Core Data that helps you store you data with scheme you provide.
If you just want to pass data from one view controller to another view controller so you just need use delegation pattern or you can use method prepareForSegue where you can pass some data as well but you can't store this way, just pass.
If you make your question more detailed you will get more explicit answer.

Order entities in Core Data data model

I am using Core Data in my application, and I have entities that need to be reordered. I have a collection view that is populated with NSManagedObjects from the data model, and this collection view can be reordered by dragging and dropping the cells. I want the order of the entities in the data model to reflect the order of the cells in the collection view. Does anyone know how I can accomplish this? I am new to Core Data, so I am still getting used to it.
If I understand your question correctly, you may do it simply as follows:
add an attribute viewOrder to your entity, probably an integer type
update it any time the user drags and drops a cell, i.e. re-orders the collection view (& make sure to save: the NSManagedObjectContext whenever you make any changes)
when populating the collection view, set the NSFetchRequest property sortDescriptors to sort the results by viewOrder
note that if you add new managed objects, you'll have to run a fetch to count the current number in core date or to find the max viewOrder

Resources