MVVMSkeleton

  1. Structure
  2. Module components
  3. Navigation
  4. Environments management

Video presentation record

Structure

  • Application – contains app’s entry point files(AppDelegate, SceneDelegate), app configurations(dev, stg, prod) and
    • App entry points (AppDelegate, SceneDelegate)
    • AppContainer – container/builder for app services
    • App configuraion
      • Environment type (dev, stg, prod)
      • Constants (special keys/identifiers)
  • BusinessLogic
    • Models – response, database, domain entities
    • Services – Independent services and managers
    • Coordinators – app navigation control services
  • Core
    • Base – Base classes for app’s modules
    • Extensions – Extensions for Foundation, UIKit, Combine, other classes/structs
    • Helpers – Independent and reusable tools
    • Views – Reusable views(which can be used twice or more times)
  • Presentation – all modules in the app (can be grouped by flow)
  • Resources – assets, colors, fonts, strings resources

Screenshot 2022-02-07 at 21 44 31

Module Components

Each module has 4 main components(can be more if you need to split giant logic in some of them):

  • View
  • ViewController
  • ViewModel
  • Builder

Which are connected with controller though the bindings. In this case case controller acts as a connector between View and ViewModel.

Screenshot 2022-02-07 at 23 53 03

View

  • View is independent component.
  • Each View has its own action publisher where you should notify subscribers(ex. ViewController) about user interaction inside its view.
  • Action enum, publisher and subject will be generated automatically with providing template.
  • (Optional) I prefer building UI from the code, but you can use Xib with IB.

Screenshot 2022-02-08 at 00 04 53

ViewModel

  • ViewModel is independent component.
  • Each ViewModel has its own transition publisher where you should notify subscribers(ex. Coordinator) when you should go forward or backward in your flow.
  • If ViewModel need some services or parameters, the should be injected through the initializer.
  • Transion publisher and subject will be generated automatically with providing template.
  • (Optional) I prefer storing temporary data in ViewModel directly, but you can create Model component and move it there.

Screenshot 2022-02-08 at 00 12 30

ViewController

  • ViewController holds strong reference to View and ViewModel(BaseViewController contains ViewModel property as a generic type of “ViewModel”).
  • ViewController listen to View’s action publisher and pass it to ViewModel.
  • ViewController listen to ViewModel publishers and pass its data to View or interact by itself on its signals.

Screenshot 2022-02-08 at 00 22 45

Builder

  • Builder constructs a Module
  • It creates needed components with injecting needed services and parameters and wrap it into “Module” type – which is just container with 2 generic types(controller and transition, image below)
  • Builder also generates automatically with included template

Screenshot 2022-02-08 at 00 29 00

Screenshot 2022-02-08 at 00 29 42

Navigation

Screenshot 2022-02-08 at 00 38 13

  • When app starts it builds an App Coordinator and starts one of the flows(run child coordinator)
  • When its flow(child coordinator) will send finish signal througn the “didFinishPublisher”, parent coordinator can move its own flow or run another coordinator.

Screenshot 2022-02-08 at 00 46 31

  • Each coordinator initializes with UINavigationController and AppContainer and has “start” method
  • “start” method build first(root) module for its coordinator
  • Each methods in the coordinator should create a module(using Builder) pass container and other parameters if needed into it, subscribe to its transition publisher for running next modules or finishing the flow

Screenshot 2022-02-08 at 00 45 30

Environment management

  • Application folder contains xcconfig files for managing different environments(contains type of environment, app name and bundleId)

Screenshot 2022-02-08 at 01 03 17

  • When AppConfiguration initializes it retrives environment type and other info from Info.plist by key

Screenshot 2022-02-08 at 01 00 41

Screenshot 2022-02-08 at 00 55 50

  • Inside AppEvironment enum you should specify differences between your environments(ex. baseURL, apiToken, …)

Screenshot 2022-02-08 at 01 06 27

  • For running app with needed environment type – just select needed scheme

Screenshot 2022-02-08 at 01 09 04

GitHub

View Github