A showcase project, which fetches data and renders my CV.
It is also my playground project, where I like to play with architecture, design patterns, and technics.
A simple iOS app is written in Swift.
UI was created using the UIKit
framework. SwiftUI
is used only to enable previews of the views. New views will be created in SwiftUI
.
The app is not built using only one architecture, but each view uses only one of them. Currently used architectures:
- Clean Swift
- MVVM
All the code is written in a testable way. Unit tests are written using XCText
, Quick
, and Nimble
frameworks.
Bitrise and Travis CI are used for CI, Codecov for measuring code coverage.
SwiftLint is used for linting the Swift source code. It is added to the project as a build phase.
To run the project only Xcode is needed (version 13+). All the project dependencies will be fetched automatically by the Swift Package Manager.
- Clone the repo
git clone https://github.com/gwikiera/CV.git
- Open the
CV
Xcode projectcd CV open CV.xcodeproj
The app is not based on only one architecture. Different screens were built using different approaches. Currently used architectures:
- Clean Swift - Image is an example. ImageViewController informs ImageInteractor about actions. ImageInteractor contains the bussiness logic, and perform work using its workers, at the end informs ImagePresenter about new data to be presented. ImagePresenter based on received data formats it to the format undestandable by ImageViewController. At the end of the
VIP
cycle ImageViewController display new data to the user. - MVVM - CLE is an example. CLEViewController.swift listen to the stream of CLEViewState model objects from passed CLEViewModel. CLEViewController.swift triggers some actions on CLEViewModel, which may end up with new data comming in.
The app is modularized into many small modules using Swift Package Manager. Each module is standalone and designed to deliver specific functionality. Some modules have dependencies on other local or remote modules. Tests for modules are written in the dedicated test targets. The main advantages of using modularization are the ability to build each module in a separation, speed up the process of testing and previewing SwiftUI
code, and the potential to extract some modules into separate repositories.
Dependencies in the app were constructed using the pointfree.io style. Instead of using protocols
to define abstraction, it uses structs
initialized with closures for each dependency functionality, APIClient is an example. It allows tp define many static objects which creates live
, mock
or failing
implementations of this struct
, like in APIClientLive. Using var
s allows to easily change one of the closures of failing
implementation for tests purposes (those var
s are not public
so the client app or module cannot change them).
The app dependencies are grouped inside the AppEnvironment struct. It allows changing the app environment based on the passed launch arguments. Due to that, the project contains two schemas: live CV
and CV-Mock
, which operate on the hardcoded data.
The app target contains only CVUITest
target because all of the testable code was moved to the modules. Testable modules are unit tested, code coverage level is passed to the codecov to visualize it. Unit tests are written using third party modules like Quick and Nimble, and also internal TestsHelpers module.
CV-UIKit
target contains snapshot tests written using the swift-snapshot-testing framework. Tests can be found in the SnapshotTests.swift file, reference snapshots are stored in the SnapshotTests directory.
For each PR and the main branches the project is built and tested by two separate providers: bitrise and [travis-ci]. All unit tests for all modules are triggered, and the code coverage report is attached to each PR.
Distributed under the Apache License. See LICENSE for more information.