vvit
11/6/2017 - 8:43 PM

ASQ.swift

class WelcomeViewModel {
    let coordinator: Coordinator
    let store: ASQStore
}

func WelcomeViewModel.goNext() {
    let question = self.store.firstQuestion()
    let viewModel = ASQQuestionViewModel(coordinator: self.coordinator, question: question, store: self.store)
    coordinator.transitionTo(viewModel: viewModel, type: .push(animated: true)) или просто coordinator.goNext(with: viewModel)
}

func WelcomeViewModel.onSkip() {
    coordinator.stop()
}

func ASQQuestionViewModel.goNext() {
    if let nextQuestion = store.nextQuestion() {
        let viewModel = ASQQuestionViewModel(coordinator: self, question: nextQuestion, store: store)
        coordinator.transitionTo(viewModel: viewModel)
    } else {
        let viewModel = ASQSectionCompleteViewModel(coordinator: self, answers: store.answers, store: store)
        coordinator.transitionTo(viewModel: viewModel)
    }
}
// ASQFlowHelper -> ASQStore
// Мне кажется helper уже не так подходит как store. Но решай сам.
// Единственное я бы не стал из него синглтон делать. Лучше бы передавал по dependency injection из view model во view model


// ...где-то тут скачка всех вопросов (или начальный запрос какой-то)
let store = ASQStore(questionnaire: questionnaire) // aka ASQFlowHelper

// начинаем из какого-то VC
self.coordinator = AsqCoordinator(parentVC: self, store: store)
coordinator.start()

class AsqCoordinator {
    private weak let parentVC: UIViewController
    private let store = ASQStore
    private var navigationController: UINavigationVC?
	
    init(parentVC: UIViewController, store: ASQStore) {
        //assign
    }
}

func AsqCoordinator.start() {
    var welcomeVC = ASQWelcomeViewController.instantiateFromStoryboard()
    self.navigationController = UINavigationController(rootVC: welcomeVC)
    welcomeVC.bindViewModel(ASQWelcomeViewModel(coordinator: self, store: self.store))
    parentVC.present(navigationController)
}

func AsqCoordinator.stop() {
    parentVC.dismiss(self.navigationController, animated: true)
}

enum TransitionType {
    case push(animated: Bool)
    case present(animated: Bool)
    case pop(animated: Bool)
}

func AsqCoordinator.transitionTo<T>(viewModel: T?, type: TransitionType = .push(animated: true)) {
    let viewController = self.viewController(for: viewModel)

    switch type {
    case .push(let animated):
        navigationController?.pushViewController(viewController!, animated: animated)
    case .present(let animated):
        navigationController?.present(viewController!, animated: animated)
    case .pop(let animated):
    	navigationController?.popViewController(animated: animated)
    }
}

func AsqCoordinator.viewController<T>(for viewModel: T?) -> UIViewController? {
    var viewController: UIViewController!

    switch viewModel.self {
    case is ASQQuestionViewModel:
        var questionViewController = ASQQuestionViewController.instantiateFromStoryboard()
        questionViewController.bindViewModel(viewModel as! ASQQuestionViewModel)
        viewController = questionViewController    
    case is ASQSectionCompleteViewModel:
        var completeViewController = ASQSectionCompleteViewController.instantiateFromStoryboard()
        completeViewController.bindViewModel(viewModel as! ASQSectionCompleteViewModel)
        viewController = completeViewController
    default:
        break
    }

    return viewController
}