Skip to content

An simple recipe finder iOS app built using MVVM pattern, clean code, and unit testing coverage

Notifications You must be signed in to change notification settings

arinjoy/RecipeBoss

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RecipeBoss

An simple recipe finder iOS app built using MVVM pattern, clean code, and unit testing coverage and best practices used in modern iOS programming using Swift.

App Goal:

  • Showing a list of great recipes from a source
  • Showing them in grid layout in landscape mode
  • On device orientation change, show a different view with more detail of the recipe but within same container
  • Used same collection view cell dynamically using size class to detect device rotation to support both layout
  • Used UICollectionViewCompositionalLayout in iOS13+
  • Used Combine for reactive binding
  • Load images of the recipes separately and cache them and fetch the data incrementally as user scrolls though to manage network bandwidth better

JSON Data Source:

The data for the recipes stays in local JSON file. But it can be loaded from a remote source url using http GET if needed. Full support for network layer has been added with potential custom error handling. See usage in view model on error outcome in loading.

At this stage the app points to the local JSON data source. See tech note of the ApplicationComponentsFactory and how dependency injection works there.

 /// TODO: Here is the glue. Use `defaultProvider` when real network loading is needed
 /// For now leaded locally from a JSON file
 networkService: ServicesProvider.localStubbedProvider().network

Custom Error handling

  • See view model logic of error handling & empty state handling
  • Placeholder view is created to achciev these two cases using same view

3rd Party Libraries (only in unit testing)

  • Quick - To unit test as much as possible 🤫
  • Nimble - To pair with Quick 👬

Apple frameworks

  • Combine – To do reactive binding when needed 🤫
  • UIKit – To build as usual everywhere 😀

Clean MVVM Architecture

  • ViewController talks to ViewModel which relies on UseCase under its layer
  • The ViewModel processes lower level domain models of recipes and converts into higher level RecipeViewModel items for the need of the UI
  • ViewModel take helps from Transformer
  • Accessbility ID, label, hints, traits etc calculation and any other formatting etc. is done via the Transformer
  • ViewModel and Transformer are individually unit tested
  • There is some support for Routing to show how it can be achieved through FlowCoordinator pattern
  • Some glue code left with some tech notes how the recipe cell tapping and detail view navigation can be done in future

Dependency Injection

  • ApplicationComponentsFactory helps in DI and pick the service injection that is need
  • Other layers of the app in domain and data level everything is protocol driven to achieve loose coupling and DI based unit testing.
  • See unit tests at each layer

Code Organisation / Layers / Grouping

Folder / Grouping are done as per below: Project has 2 targets:

  • RecipeBoss - The main code
  • RecipeBossTest - Unit testing of all layers using Quick/Nimble

Codebase has 3 layers:

  • PresentationLayer
  • DomainLayer
  • DataLayer

Accessibility

  • Custom accessibility to each element is supported
  • Accessibility identifiers are injected to each element to help support UI Automation Testing
  • See Transformer logic to see acessibility computations
  • TODO more work is needed after supporting paginated carousel support. Perhaps full cell should be one accessibility element with some children inside as well.

Custom Theme

About

An simple recipe finder iOS app built using MVVM pattern, clean code, and unit testing coverage

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages