iOS Archirectures - toant-dev/toandev.github.io GitHub Wiki

Architectures

MVVM

Libraries:

  • RxSwift
  • Swinject + SwinjectAutoregistration

Base components:

  • View controllers
  • View models
  • Coordinators
  • Services
  • Data models

NOTE:

We should use a xib file for each view controller

Should log deinit{} for each view controller, view model or coordinator to prevent memory leaks

Each screen should contains: view controller, view model, cordinator and xib file

For each view controller which init from storyboard, such as init view controller, we must resolve Di manually

Multi-schemes

We should add a scheme for each build enviroment, such as DEV, STAGING, PRODUCTION

  1. Each Scheme should have different bundle id, such as: com.app.demo.dev
  2. Add custome flag for each scheme to auto select correct configration
  3. Add service's configuration file for each scheme with different names

-D DEV or -D STAGING or -D PRODUCTION

class Env {
    
    static var shared = Env()
    
    func printEnviroment() {
        #if DEV
        print("Running dev mode...")
        #elseif STAGING
        print("Running staging mode...")
        #else
        print("Running production mode...")
        #endif
    }
    
    var apiHost: String {
        get {
            #if DEV
            return "https://api.reachat.dirox.dev"
            #elseif STAGING
            return "https://api.reachat.dirox.app"
            #else
            return "-"
            #endif
        }
    }
    
    var webHost: String {
        get {
            #if DEV
            return "https://reachat.dirox.dev"
            #elseif STAGING
            return "https://reachat.dirox.app"
            #else
            return "-"
            #endif
        }
    }
    
    var deeplinkHost: String {
        get {
            #if DEV
            return "https://reachatdev.app.link"
            #elseif STAGING
            return "https://reachatstaging.app.link"
            #else
            return "-"
            #endif
        }
    }
    
    var googleConfigFile: String {
        get {
            #if DEV
            return "GoogleService-Info-Dev"
            #elseif STAGING
            return "GoogleService-Info-Staging"
            #else
            return "GoogleService-Info"
            #endif
        }
    }
    
    var googleSignInClientId: String {
        get {
            #if DEV
            return "id1.apps.googleusercontent.com"
            #elseif STAGING
            return "id2.apps.googleusercontent.com"
            #else
            return "-"
            #endif
        }
    }
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        Env.shared.printEnviroment()
        
        // Shared
        AppDelegate.shared = self
        
        // Register all dependencies
        AppDelegate.container.registerDependencies()
        
        // Firebase
        let firebaseOptions = FirebaseOptions(contentsOfFile: Bundle.main.path(forResource: Env.shared.firebaseConfigFile, ofType: "plist")!)
        FirebaseApp.configure(options: firebaseOptions!)
        
        // Google Maps
        GMSServices.provideAPIKey(Env.shared.googleMapKey)
        
        return true
    }