Modeling DataSource. Part 2.
Some time ago, there was an article published on the topic of DataSource modeling.
This article will introduce the idea of dataSource modeling to simplify handling table or collection events and improve…
There is a continuation, or to be more precise, the evolution of the idea, elimination of the shortcomings inherent in the previous version, and ultimately an approach that takes place in the real practice of developing applications for iOS.
Packaging to library
The solution proposed earlier was not possible to reuse. In other words, the developer had to copy a large piece of code every time he needed to model the dataSource. The only reason for the existence of such a drawback is the use of the Section.Kind and Row.Kind enumerations, since swift does not allow adding cases to the enum from the extension.
Also one more drawback — the completely identical implementation of Section.Kind and Row.Kind. Duplication of code should be avoided.
The solution is to use the Kind structure and static constants instead of enum Kind and cases. Also, when printing to the console, readable text describing the constant is required. Therefore, it is necessary to implement the RawRepresentable, ExpressibleByStringLiteral, CustomStringConvertible protocols.
As a result, as needed, developer can create any number of constants using access control.
Modeling section of UITableView and UICollectionView
The IndexPath structure contains auxiliary properties to make the syntax readable for both UITableView (indexPath.row) and UICollectionView (indexPath.item). Therefore, the Section structure should be designed with UICollectionView data modeling in mind.
Don’t forget about the text output to the console. The developer does not need to know the UUID of the section, while the kind and the elements of the section (rows/items) are more valuable information.
Editing section items
In everyday practice, developer will probably need to delete, add, move, etc. section elements. The same operations apply to the sections themselves. And since a model is an array of sections and a section is an array of section items, the full set of editing methods that the standard library provides for the Array are required.
One of the possible solutions is to declare the Items structure, which implements RandomAccessCollection, MutableCollection, RangeReplaceableCollection. In fact Items is an array of section elements — Item structures.
It is important to note that the DiffableDataSource uses the hash value to operate, and if this value is not unique, the application will crash. This is the main reason why the Item structure is declared and the data property is declared private(set).
In the code provided above, you can see constructions like
1. sections[.contacts]...2. ...firstIndex(of: .addContact)
- The subscript, which returns Section structure, with dedicated kind, if there is one in the array.
- The method, which returns section index, with dedicated kind, if there is one in the array.
All this, of course, is syntactic sugar, but it simplifies the development process.
As a result, the developer has at hand a library called DataSource, which includes the Kind.swift, Section.swift, SectionItem.swift and SectionProtocol.swift provided above.
Obviously, the code becomes much clearer. And if you compare with hardcoded data — the sky and the snake.
Unfortunately, at the moment Swift does not offer solutions for customizing the output of the collection to console,
What's the best way to override CustomStringConvertible for a collection?
Imagine that you have a set of integers and you want to override the default implementation of CustomStringConvertible…
so the indentation is not the best. Nevertheless, the output is readable.
So, the entire API developed and proposed in the previous article has been preserved and even expanded. Duplication of code has been significantly reduced, it is now possible to distribute the solution as a separate module, be it a package, pod or framework.
I wish you a great mood. That’s it.