Skip to content

Instantly share code, notes, and snippets.

@damodarnamala
Created April 3, 2024 04:43
Show Gist options
  • Save damodarnamala/8635a2703ed188ca9cdfa2b38f545554 to your computer and use it in GitHub Desktop.
Save damodarnamala/8635a2703ed188ca9cdfa2b38f545554 to your computer and use it in GitHub Desktop.
OOTB Configuration
//
// ViewController.swift
// OOTB-Design
//
// Created by Damodar Namala on 03/04/24.
//
import UIKit
import Resolver
import SnapKit
class ViewController: UIViewController {
var config = Resolver.resolve(Contacts.Configuration.self)
var contactUsecase = Resolver.resolve(ContactsUseCase.self)
lazy var nameLabel: UILabel = {
let label = UILabel()
label.font = .boldSystemFont(ofSize: 18)
label.textColor = .systemRed
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(nameLabel)
nameLabel.snp.makeConstraints { make in
make.centerX.centerY.equalToSuperview()
}
var name = config.strings.name
name = "Aadya"
self.nameLabel.text = name
let names = contactUsecase.fetchContacts()
print(names)
// Do any additional setup after loading the view.
}
}
internal protocol Configurable {
associatedtype ConfigurationType
static var appDefault: ConfigurationType { get }
}
internal protocol AppDependency {
func register()
}
public struct Contacts {
var configuration = Resolver.resolve(Contacts.Configuration.self)
struct Configuration {
var strings = Strings()
}
}
extension Contacts.Configuration {
struct Strings {
var name = "Damodar"
}
}
extension Contacts: Configurable {
static var appDefault: Contacts.Configuration {
return Contacts.Configuration()
}
}
extension Contacts.Configuration: AppDependency {
public func register() {
if Resolver.optional(ContactsUseCase.self) == nil {
let defaultUseCase = RetailContactsUseCase()
Resolver.register { defaultUseCase as ContactsUseCase }
}
Resolver.register { self }
}
}
protocol ContactsUseCase {
func fetchContacts() -> [String]
}
struct RetailContactsUseCase: ContactsUseCase {
func fetchContacts() -> [String] {
return ["Damodar", "Aadya", "Anusha"]
}
}
protocol AppConfiguration {
init()
var dependencies: [AppDependency] { get }
}
extension AppConfiguration {
/// Array of `AppDependency` objects to be registered.
/// Defaults to all properties that conform to the `Dependency` protocol.
var dependencies: [AppDependency] {
Mirror(reflecting: self)
.children
.map(\.value)
.compactMap { $0 as? AppDependency }
}
}
struct AppConfigurationImpl: AppConfiguration {
var contacts = Contacts.appDefault
}
///
//
// AppDelegate.swift
// OOTB-Design
//
// Created by Damodar Namala on 03/04/24.
//
import UIKit
import Resolver
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
sharedSetup()
// Override point for customization after application launch.
return true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
private func sharedSetup() {
let configuration = AppConfigurationImpl()
print(configuration.dependencies)
configuration.dependencies.forEach { $0.register() }
}
}
@damodarnamala
Copy link
Author

damodarnamala commented Apr 3, 2024

import UIKit
import Resolver
import SnapKit

class SecondViewController: UIViewController {
    
}

class ViewController: UIViewController {
    var config = Resolver.resolve(Contacts.Configuration.self)
    var contactUsecase = Resolver.resolve(ContactsUseCase.self)
    
    lazy var nameLabel: UILabel = {
        let label = UILabel()
        label.font = .boldSystemFont(ofSize: 18)
        label.textColor = .systemRed
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    lazy var nextButton: UIButton = {
        let label = UIButton(type: .roundedRect)
        label.setTitle("Next", for: .normal)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(nameLabel)
        self.view.addSubview(nextButton)
        nameLabel.snp.makeConstraints { make in
            make.centerX.centerY.equalToSuperview()
        }
        
        nextButton.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.centerY.equalToSuperview().offset(100)
        }
        
        var name = config.strings.name
        name = "Aadya"
        self.nameLabel.text =  name
        let names = contactUsecase.fetchContacts()
        print(names)
        nextButton.addTarget(self, action: #selector(route), for: .touchUpInside)
    }
    
    
    @objc func route() {
        config.router.didSelectName?(self.navigationController)()
    }
}

internal protocol Configurable {
    associatedtype ConfigurationType
    static var appDefault: ConfigurationType { get }
}

internal protocol AppDependency {
    func register()
}

public struct Contacts {
    var configuration = Resolver.resolve(Contacts.Configuration.self)
    struct Configuration {
        var strings = Strings()
        var router = Router()
    }
}


extension Contacts.Configuration {
    struct Strings {
        var name = "Damodar"
    }
    
    struct Router {
        public var didSelectName: ((UINavigationController?) -> () -> Void)? = { navigationController in
            return {
                let notificationsVC = SecondView.build(navigationController: navigationController)
                notificationsVC.hidesBottomBarWhenPushed = true
                navigationController?.pushViewController(notificationsVC, animated: true)
            }
        }
    }
}
struct SecondView {
    static func build(navigationController: UINavigationController?) -> UIViewController {
        let storyBoard = UIStoryboard(name: "Main", bundle: nil)
        let vc = storyBoard.instantiateViewController(identifier: "SecondViewController")
        return vc
    }
}

extension Contacts: Configurable {
    static var appDefault: Contacts.Configuration {
        return Contacts.Configuration()
    }
}

extension Contacts.Configuration: AppDependency {
    public func register() {
        if Resolver.optional(ContactsUseCase.self) == nil {
            let defaultUseCase = RetailContactsUseCase()
            Resolver.register { defaultUseCase as ContactsUseCase }
        }
        Resolver.register { self }
    }
}

protocol ContactsUseCase {
    func fetchContacts() -> [String]
}

struct RetailContactsUseCase: ContactsUseCase {
    func fetchContacts() -> [String] {
        return ["Damodar", "Aadya", "Anusha"]
    }
}


protocol AppConfiguration {
    init()
    var dependencies: [AppDependency] { get }
}

extension AppConfiguration {
    /// Array of `AppDependency` objects to be registered.
    /// Defaults to all properties that conform to the `Dependency` protocol.
    var dependencies: [AppDependency] {
        Mirror(reflecting: self)
            .children
            .map(\.value)
            .compactMap { $0 as? AppDependency }
    }
}

struct AppConfigurationImpl: AppConfiguration {
    var contacts = Contacts.appDefault
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment