Identifiable and Selectable Collection

This week I came across an interesting problem creating a new screen. When you have objects that need to be uniquely identifiable, require to keep objects in order and only one of these objects can be selected in a list at a time. So I wanted to share with you guys the solution I came up with and while we are at it we can use some of the new asynchronous functionality in swift, lets go!!

If you want to see the code before reading, here it is!

Initial Solution

The initial idea I had used the indexes of an array as the ID, but there is a lot of thing wrong with that, for example if an item is deleted and the ids are not reset everything is going to behave funky. There are other problems with that as well, so the option here is to have a unique id array(to keep the order of the objects) and a dictionary to keep the actual value of the object.

No alt text provided for this image

Here we have a "user" structure that holds a unique id and other information about the user. Our selectableListViewModel then has a list of ids, and a dictionary holding each user, we also have a published list of users, that are in the correct order. The fetchUsers function is marked async to mimic a server call and adds 3 new users to the list.

The selectUser function deselects all users and then selects the user that was passed in as a parameter.

As you can see that is pretty messy and there is a lot of duplicated code, furthermore if this logic is to be used anywhere else we would have to duplicate this entire code again! Instead of having this in this struct, so let's make a struct to handle all that jazz! 

Creating An Identifiable and Selectable Collection

So now we should create a struct that takes in an Identifiable Object and keeps the original order that the objects were passed in, we should also be able to select an object and deselect all others. Here we go!

The first thing we can do is abstracting the selection and deselection logic from the struct (Each user should handle that), we can do this by making a protocol.

No alt text provided for this image
No alt text provided for this image

Now the selection part is all handled by the use itself, which will make our final code much cleaner.

The next step is to make a struct that will hold our objects:

No alt text provided for this image

Now we have a struct that holds the collections we want, we have the elements, ids, a way to get the ordered elements and a function that returns an element given an id! We are now halfway through, now we need to handle the selection of an element and make this struct into an actual collection, still with me? 

The next step is to allow elements to be selected, we can do this by letting IdentifiableCollection implement the RangeReplacebleCollection so we can modify our struct:

No alt text provided for this image

Here we populate the required functions for RngeReplacebleCollection, we replace the elements at the subrange in the dictionary and also the ids.

Once this is done we can then implement the selectable function:


No alt text provided for this image

We create a copy of the current object, elect the current element in that collection and return it. This is looking nice, let's use this in our code!

No alt text provided for this image

Ain't this looking so much cleaner? We can use our model in a view to make a selectable list:

No alt text provided for this image

We can also use pull to refresh in iOS 15 to "fetch" more users into the list, and we got the outcome that looks like this:

Well there we are!! hope you guys liked this!

The code is here. If ya'll want to have a peek!



To view or add a comment, sign in

Insights from the community

Others also viewed

Explore topics