In the next sections of this document, I will be mainly focusing on describing the
Suffixes tab since it has a more interesting structure and more sophisticated solutions implemented.
In this project I followed MVVM architecture approach together with SOA.
The project has three internal packages:
UIComponents module contains the main visual components of the app, so it’s easy to be reused in other apps of the same group.
Navigation module contains a custom implementation of the navigation, since the native SwiftUI navigation implementation does not provide the desired level of the control over navigation.
I implemented it in a separate module, so it can be easily reused or replaced when the native soution is ready.
Networking module contains code working with the backend. The reason why I implemented it in a separate module is that it can be reused in different apps which use same backend.
The module is generated with the use of OpenApi code-gen, which helps to quickly adapt the client-side SDKs every time developers updated a corresponding REST API.
RealmDatabase as external dependencies added with the help of SwiftPM.
ServiceLocator is a singleton registry for all the services that are used by the application.
CacheService provides caching of the network response to get the artists info for further splitting the names into suffixes.
FileService provides saving and reading from the saved file of the suffix search results.
NetworkService provides an abstaction layer to connect the app and the
SuffixManipulationService module is responsible for the different operations with suffixes.
Networking module contains the models, that represent the structure of the backend responses and are used for parsing.
All properties in the response models are
optional in order to make the models sustainable to malformed backend responses. An app must not fail if the backend returns malformed data for a propery which is not used in the app.
WrappedSequence struct is created in order to embrace the power of the sequence protocol and allow iterating over the
titles inside the
SuffixIterator struct and
SuffixSequence struct allows to iterate over suffixes that are formed from a single string. For example, if it takes a word
dog, then it forms a sequence of the following suffixes:
dog, og, g.
Job and class
JobScheduler are used to schedule concurrent tasks of searching matching suffixes and estimating a search efficiency by providing the search time.
Injected property wrapper
Injected property wrapped is used to inject dependency to the different services inside
view models without using initializers.
ArtApi.yaml in the project directory, that represents the API specification, that was created with the Swagger Editor and used to generate the
generate.sh is a script used to generate the
SwiftLint is integrated into Xcode to follow Swift style and conventions.
SuffixesManipulationTests tests the methods that are used for operations with suffixes.
ArtCatalogueUITests folder contains UI tests for three tabs, testing a simple user flow and the presence of the navigation buttons on the screen.
On Production I would add the backend response error hanling for the case when backend return nil for the properties that are necessary for the business logic. So that the app doesn’t crash in that case, and user could see an error message. I would also track such exceptions as Crashlytics non-fatal events. In that case the team quickly learns about a problem related to the backend responses and can take appropriate actions.
I would add the following tests:
- Integration tests for parsing of data models. For that I would add json files and parse them with the existing models. The tests would check that fields of parsed models have same values as jsons.
- Swift 5.5
- Xcode 13.3.1
- iOS 15.0+