It's a Todo iOS Application with offline support by the use of Core Data which has been developed as a code challenge. It's written purely in Swift without using 3rd party frameworks. The project included Unit Tests for the Core Data Layer and UI Tests exist as well.
How DO I respect the topics below while developing a software:
- Reusability of the code 🔁
- Clean Code Principles 🧼
- SOLID Principles 🥰
- Design Patterns 🖌
- Loose coupling 🙇🏻♂️
- Abstraction ☁️
- Modularity 🧱
- Testability 🧪
- and Clean Architecture for sure! 😁
MVC architecture in iOS translated to Massive View Controller. The first reason for this choice is because soon or late the code base converts to a spaghetti code-base easily. The second one is that I highly believe in sOlid principles, especially the o one which means Open For Extension So, I used this architecture to make a passive ViewController by outsourcing business logic to the ModelView layer.
It makes the app coordination super simple. Plus, it brings loosely coupling between ViewControllers. Thus, we'll have a more testable codebase. In another way, a Coordinator is like a company that knows how to make each scene(VCs and VMs).
This layer is simply responsible for communicating with whatever exists outside of the application. Like API calls, Bluetooth, saving on storage or database, etc. Again, I highly respect the SOLID principles. On the diagram image on part services, you can see Dependency Inversion. For example, in the future, if we would like to use Realm instead of Core Data, we can simply implement the Storage protocol in a class that uses Realm and easily inject it into the services layer instead of the current implementation of the Storage which is using Core Data. Thus, again, this brings Modularity and Open For Extention principles to the code-base.
- Todo
- Simply represent a todo model which fetchs from the HDD (a pure model)
- TodoViewData
- It's a wrapper(decorator) around each Todo which do some preprocess on data before use them on ViewControllers.
- TodoObject
- It contains both models above + TodoNSManagedObject of each Todo. It uses as a container which knows 3 aspects of each todo. How its NSObject, ViewData and pure model represented.
If we use the same Core Data stack for the application and the same one for the tests. It's near impossible to test the Core Data CRUD actions. Why? Because if you use the same stack for saving on disk using the application, your disk data gets changes,so, you must always change your test accordingly.
Solution? ✨ Make 2 different stacks which makes storage and Core Data layer of the application super testable and runs tests super faster.
How to reach it? 🧠
The left one uses by the application to really save on disk.
The right one uses by the test cases. It's created on memory that is why tests run very fast.
Show.Case.mov
I invite you to see Unit Tests of the Core Data and application itself as well as UI Tests. I used GWT method to make the tests cleaner.
Attention☝🏼
Before running UITests
, press Command⌘ + k
on the Simulator
to toggle the software keyboard.
You can find the diagram file in the repo and open it in here
Project Definition
We would like you to build a simple "to-do" app which consists of tasks in list and task detail in detail screen.
- Feel free to use any architecture or design pattern
- Do not use any reactive paradigm (SwiftUI, RxSwift etc.)
- You can build the user interface with XIBs || Storyboards || Code
- For the local storage, you should use Realm or CoreData
- For the local storage, you should use Realm or CoreData
- Keep code as clean as possible
- Your code should be easy to maintain
- Do not try to build a fancy UI, your implementation details are more important
- Consistency on code convention and indentation
- Library usage (No more and less than required)
- Git usage
- A README.md which describes technical details/decisions
- Unit Tests or UI Tests are bonus
After completing the assignment, create a pull request to main
branch.
Then please send an email to the People Department with the link of the GitHub repo.