SwiftUI move list cells and populate order in CoreData database - swift

I have a problem with moving cells and save the order in CoreData database. I've got the move from UI perspective working, but I can't understand how to mirror it in the core data. Moved list entities have orderPriority attribute in CoreData, its an Int I would like to change on move action.
Move method attached to the list is this:
func move(from source: IndexSet, to destination: Int)
It seems like source and destination are two different things, for example
moving first cell to third position gives source=0 and destination=3, but
moving third cell to first position gives source=2 and destination=0, with only 3 elements in the array destination makes no sense to me.
Source looks like array index, but destination is what I can't undersand and this is why I can't change core data entities to respective order.
Am I doing something wrong?

... but moving third cell to first position gives source=2 and destination=0, with only 3 elements in the array destination makes no sense to me.
Array indices start at zero, source=2 is the 3rd element and destination=0 is the 1st element. Index 2 becomes 0, index 0 becomes 1 and index 1 becomes 2.
By the way the type of source is IndexSet, you can move multiple items at non-subsequent indices to the destination index.
Per default Core Data records are unordered. If you have an index attribute in the entity you have to re-index the records, at least from the first index which has been changed.

Related

NSFetchedResultsController predicate to eliminate duplicates of several properties

I am using an NSFetchedResultsController in my UITableViewController.
Is it possible to specify a predicate that will not retrieve items which have duplicate fields in x number of fields that I specify.
For example, I want to search all results for items but if the itemName AND itemDescription AND itemQuantity are the same, I want only one of these items.
Option 1
When the page loads do a single run through the data and keep a list of objectID that are duplicate. For duplicate object set the row height of the cell to be 0. So they are technically still there, but you can't see it. This make dealing with the NSFetchedResultsControllerDelegate calls easy because no indexPaths have changed
Option 2
If the dataset is always selected in the same way and an object that is a duplicate is always a duplicate you can set an 'isDuplicate' in the object and filter it out in the predicate. Or you can not store at all in the first place. If objects are displayed in different sets and in different way and sometime should be displayed and sometime not be displayed this is not a good solution
Option 3
If you are sorting by the same criteria that make an object duplicate (that is duplicates always appear right next to a non-duplicate) and you are NOT using sections, then you can use sectionKeyPath. SectionKeyPath groups items together into sections. Group the duplicate and non duplicate together and then display every section as a single row (use the first item in each section). The indexPaths of the fetchedResultsController will not match the indexPaths of the tableview so you have to careful to convert them.
Option 4
Instead of accessing the objects from a fetchedResultsController do a fetch and and filter the array. Then use the array to display the objects. The downside is that you don't get updates on when objects change. This can be especially problematic is objects are deleted, as accessing a managedObject that's entity was delete can lead to a crash.
I recommend option 1

GWT: get backing object for row by id in table

Is there any simple way to get the object, used to render given row in CellTable, by index of the row?
I am using AsyncDataProvider, and don't want to remember lists of data objects, returned from the server. Also I am using MultiSelectionModel, so several items could be selected there and I need to track out which one was clicked last.
I know the index of last clicked row, so I need to get the object, corresponding to the row, somehow.
getVisibleItem? possibly combined with getPageStart if you're using paging and you only know the absolute index.
For your use-case, maybe you could use a customized selection model whose setSelected tracks the last change.

Save Entities in a Specific Order

I am using Entitiy Framework and have come across a weird problem.
I am trying to save a collection to the database (say: Collection of Rounds).
Now each item in this collection in turn has a collection of child elements (say: Collection of Events).
Which would look something like this:
Round 1
(No Child Elements)
Round 2
Event 1
Event 2
Event 3
Round 3
(No Child Elements)
Round 4
Event 1
Event 2
As shown above it is not necessary that the parent object will always have a child collection.
Now here is the problem:
My requirement is that i want to save the data as i have added it to the collection.
But, while saving EF saves the items having a child collection first and so the order is modified upon saving.
So, in the database Round 2 is saved first and then others are saved randomly.
Is there any way to force EF to save the Rounds collection in the order that i have constructed it??
It should always save starting from Round 1 and should end with saving Round 4.
Thanks guys : )
Neither database or EF guarantees ordering. In the same way if you query the database you don't have to get elements in expected order. If you want exact order you must add additional column to keep record's ordering value and use OrderBy extension method when retrieving data.
Order of operations executed by SaveChanges is in full control of EF. You cannot change it.

Shifting rows in a UITableView

I have looked at several forums and read different threads, but I can't seem to find an answer. I'd really like some help. I have an array that stores Labels whose contents I display in the UITableView's row. The second row contains fresh data added to the same array and so on. My question is, everytime the labels are displayed in the UITableView, I want it to be displayed on the top row. In essence, the older ones keeps shifting one row down. I understand I need to use: "tableView:moveRowAtIndexPath:toIndexPath:" but it only seems to work with arrays whose contents are strings.
Just to clarify, I'm not displaying each element of the array on a new line. I'm displaying all the elements of the array on a single row, then changing the elements and displaying that as the next row. Except I want the second row to be above the first and so on.
The array you're using is an ordered collection of object, so the easiest way to perform what you're looking fro would be to add the new object in the first position of your array. You can achieve that using the method insertObject:atIndex: of NSMutableArray
ex:
[myArray insertObject:newObject atIndex:0];
This way you don't have to worry about moving your tableView cells ordering.
Hope this helps,
Vincent
First of all you don't need to keep the label in some array, you can keep only the string. And when add an new object to the array add it on position 0 and the do and reload of table view.

Moving UITableView cells and maintaining consistent data

I've enabled editing mode and moving cells around to allow users to position table view content in the order they please. I'm using Core Data as the data source, which sorts the content by the attribute "userOrder". When content is first inserted, userOrder is set to a random value. The idea is that when the user moves a cell around, the userOrder of that cell changes to accomodate its new position. The following are problems I am running into while trying to accomplish this:
Successfully saving the the new location of the cell and adjusting all changed locations of influenced cells.
Getting the data to be consistent. For example, the TableView handles the movement fine, but when i click on the new location of the cell, it displays data for the old cell that used to be that location. Data of all influenced cells gets messed up as well.
I know I have to implement this in:
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {}
I just don't know how. The apple docs are not particularly helpful if you are using Core Data, as in my situation.
Any guidance greatly appreciated!
Problem 1 is pretty much independent of using CoreData, just think of a simple array:
{0 1 2 3 4 A}.
Now the user moves some freshly appended element A within the Array:
{0 1 A 2 3 4}
So starting with the inserted element A, which receives the index 2, all elements need to have their index (which is userOrder in your case) incremented by one.
So you map 0->0, 1->1, A->2, 2->3, 3->4 and so on.
Problem 2 may have two or three sources:
Either your CoreData values are not synced so the database is not in sync with what you see.
[table reloadData] was not called
Your move-Algorithm is wrong
So perhaps you can check the thee points above and if none applies you could consider posting your move-algorithm for closer examination.