Last active
January 14, 2022 03:59
-
-
Save arifinfrds/06f2bc056f8332382c7763717a2171eb to your computer and use it in GitHub Desktop.
Composition Root
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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