Skip to content

Instantly share code, notes, and snippets.

@arifinfrds
Last active January 14, 2022 03:59
Show Gist options
  • Save arifinfrds/06f2bc056f8332382c7763717a2171eb to your computer and use it in GitHub Desktop.
Save arifinfrds/06f2bc056f8332382c7763717a2171eb to your computer and use it in GitHub Desktop.
Composition Root
import UIKit
import SwiftUI
private let incomeOutcomeOptions: [String] = ["Income", "Outcome"]
private let categoryOptions: [Transaction.Category] = [.education, .food, .transport, .shopping, .software, .gift, .payment, .game, .transport, .medical]
final class TransactionsViewControllerFactory {
private init() { }
static func makeTransactionsViewController() -> UIViewController {
let makeViewController: () -> TransactionsViewController = {
let storyboard = UIStoryboard(name: "Main", bundle: .main)
let identifier = "TransactionsViewController"
let viewController = storyboard.instantiateViewController(identifier: identifier) as! TransactionsViewController
return viewController
}
let viewController = makeViewController()
let store = CoreDataTransactionStore(.persistent)
let loader = LocalTransactionLoader(store: store)
let adder = LocalTransactionAdder(store: store)
let deleter = LocalTransactionDeleter(store: store)
let transactionsPresenter = DefaultTransactionsPresenter(loader: loader, adder: adder, deleter: deleter)
viewController.presenter = transactionsPresenter
viewController.onAddTransactionButtonTapped = self.presentAddTranstionViewController(_:)
transactionsPresenter.view = viewController
viewController.onItemTapped = { item in
let store = CoreDataTransactionStore(.persistent)
let loader = LocalTransactionLoader(store: store)
let dateDisplayViewModel = DateDisplayViewModel()
let transactionDetailViewModel = TransactionDetailViewModel(
transactionLoader: loader,
transactionId: item.id,
dateDisplayViewModel: dateDisplayViewModel,
optionConfiguration: TransactionDetailViewModel.OptionConfiguration(
incomeOutcomeOptions: incomeOutcomeOptions,
categoryOptions: categoryOptions
)
)
var transactionDetailView = TransactionDetailView(viewModel: transactionDetailViewModel)
store.updateDelegate = TransactionsStoreToAnyPresentationUpdateAdapter(
presentations: [transactionsPresenter, transactionDetailViewModel]
)
transactionDetailView.onEditButtonTapped = {
let updater = LocalTransactionUpdater(store: store)
let optionConfiguration = EditTransactionViewModel.OptionConfiguration(
incomeOutcomeOptions: incomeOutcomeOptions,
categoryOptions: categoryOptions
)
let viewModel = EditTransactionViewModel(
transactionId: item.id,
transactionLoader: loader,
transactionUpdater: updater,
dateDisplayViewModel: dateDisplayViewModel,
optionConfiguration: optionConfiguration
)
var editTransactionView = EditTransactionView(viewModel: viewModel)
editTransactionView.onCancelTapped = {
// This is weird, I want to dismiss current modal screen, but I don't have the reference of it (since it is a SwiftUI.View).
// Then I try to dismiss the root list screen, and the current modal screen dismissed.
// Wrong reference, but works 🤔.
viewController.dismiss(animated: true, completion: nil)
}
editTransactionView.onUpdateSuccessAlertTapped = {
// This is weird, I want to dismiss current modal screen, but I don't have the reference of it (since it is a SwiftUI.View).
// Then I try to dismiss the root list screen, and the current modal screen dismissed.
// Wrong reference, but works 🤔.
viewController.dismiss(animated: true, completion: nil)
}
let editTransactionViewController = UIHostingController(rootView: editTransactionView)
viewController.present(editTransactionViewController, animated: true, completion: nil)
}
let transactionDetailViewController = UIHostingController(rootView: transactionDetailView)
viewController.navigationController?.pushViewController(transactionDetailViewController, animated: true)
}
return viewController
}
private static func presentAddTranstionViewController(_ transactionsVC: TransactionsViewController) -> Void {
let addTransactionVC = AddTransactionViewControllerFactory.createAddTransactionViewController(transactionsVC: transactionsVC)
transactionsVC.present(addTransactionVC, animated: true, completion: nil)
}
}
final class AddTransactionViewControllerFactory {
private init() { }
static func createAddTransactionViewController(transactionsVC: TransactionsViewController) -> UIHostingController<AddTransactionView> {
let store = CoreDataTransactionStore(.persistent)
let optionConfiguration = AddTransactionViewModel.OptionConfiguration(
incomeOutcomeOptions: incomeOutcomeOptions,
categoryOptions: categoryOptions
)
let viewModel = AddTransactionViewModel(
transactionAdder: LocalTransactionAdder(store: store),
dateDisplayViewModel: DateDisplayViewModel(),
optionConfiguration: optionConfiguration
)
var view = AddTransactionView(viewModel: viewModel)
view.onCancelTapped = {
transactionsVC.dismiss(animated: true, completion: nil)
}
view.onUpdateSuccessAlertTapped = {
transactionsVC.presenter.onReload()
// This is weird, I want to dismiss current modal screen, but I don't have the reference of it (since it is a SwiftUI.View).
// Then I try to dismiss the root list screen, and the current modal screen dismissed.
// Wrong reference, but works 🤔.
transactionsVC.dismiss(animated: true, completion: nil)
}
let viewController = UIHostingController<AddTransactionView>(rootView: view)
return viewController
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment