Awesome
<p align="center"> <img src="https://github.com/Czajnikowski/Babylon/raw/master/logo.png"> </p>Hello Babylon
Thank you for taking the time to consider my demo during the recruitment process for the Remote Senior iOS Developer position at your company. I'd be more than happy to join your impressing team.
Initially I prepared the demo as an assignment in the interview process for Babylon Health. I actually passed the demo stage and scored "very well", but the company decided to pause on hiring new remote engineers just a day before my Skype interview. Well 🤷🏼♂️
It's a pretty generic demo though. You may find some interesting bits there if you're interested in SwiftUI
, Combine
, Playground Driven Development or architecture. I appreciate constructive critique as well 🙂
Demo
As a demo, I've chosen The babylon demo project.
Requirements
Xcode 11 Beta 5, no Catalina needed.
Dependencies
I decided to stick to the native frameworks, so there are no 3rd party dependencies by now. The main frameworks of my choice are:
Combine
for reactive programmingSwiftUI
for the View layerFoundation
for networking and caching
Architecture
The responsibilities of the app are split across three separate frameworks and the app target itself:
View
- leaf framework concerned just about the presentation layer.Networking
- leaf framework concerned about networking.ViewModel
- framework depending on bothNetworking
andView
concerned about the bidirectional mapping of data between theView
and underlying logic and services.Babylon
app target - main target where dependency injection takes place via theCoordinator
There is a subtle difference between classic MVVM and my approach. In classic MVVM the View layer depends on ViewModel and in my approach, the ViewModel depends on the View.
Such dependency graph makes View
a decoupled, leaf framework making it easy to compile, develop and test independently. Thanks to it I've been able to leverage the Playground Driven Development technique to implement and troubleshoot both view's implementations (see *.playground
in the project).
The frameworks are additionally extracted into separate projects. This makes presumable cross-team development less prone to merge conflicts.
Tests
I've written two, taking PostListViewModel
under test (see PostListViewModelTests
or Cmd + U on the Babylon
scheme).
I've been trying to incorporate snapshot testing as well (see snapshot_testing
branch) using FBSnapshotTestCase
by Uber, but it doesn't seem to work well with SwiftUI at the moment.
Known issues
- Eagerly evaluated destinations
- Problem with Alert binding
- Unable to bind to animation
- Unable to embed multiline Text in vertically scrollable ScrollView
- "Reparenting nested renderer host -- preferences may be missing" while navigating to Details view
Requirements checklist
✅ Swift 5.1.
✅ The information is available offline by leveraging the URLCache
. The quickest-to-implement solution I can imagine.
✅ Reloading available as a navigation bar item in PostListView
.
✅ Have a point of synchronization in PostDetailsViewModel.loadData()
, I used a Zip
for that.
✅ I find the code to be production grade. Not production ready though (uses iOS SDK beta 3).
✅ It compiles and runs.