Upgrade to Pro — share decks privately, control downloads, hide ads and more …

VIPERアーキテクチャ

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

 VIPERアーキテクチャ

第5回スタートアップiOS勉強会での発表資料

Avatar for Ryoichi Izumita

Ryoichi Izumita

November 17, 2016
Tweet

More Decks by Ryoichi Izumita

Other Decks in Programming

Transcript

  1. ࣗݾ঺հ • ࿨ઘా ྖҰ • @rizumita • גࣜձࣾLang-8ͰiOSΞϓϦ։ ൃΛ୲౰ •

    HiNative for iOS • εϓϥτΡʔϯͰͷ࢖༻ϒΩ͸ γϟʔϓϚʔΧʔωΦͱόϨϧ εϐφʔσί
  2. VIPER • Clean ArchitectureͷҰछʢͩͱࢥ͏ʣ • MVC/MVVMͳͲͷ໰୊Λղܾ • Router(Wireframe)͕ભҠϩδοΫΛ୲౰ • VIPER

    ≒ MVVM + Router (+ Interactor) • Interactor͕ϏδωεϩδοΫΛ୲౰ • MVVM(FRP)΍Redux(ReSwift)͸ϥΠϒϥϦʹґଘ͢Δ͕VIPER͸ґଘ͠ͳ͍ • FRPΛར༻͢Δ৔߹ͱൺ΂ͯελοΫτϨʔε͕෼͔Γ΍͍͢ • ςετ͠΍͍͢ • ֤ϨΠϠʔؒͷ઀ଓ͸DIΛ࢖͏ͱྑ͍ • ϑΝΠϧ͕ଟ͘ͳΓ͕ͪ • Segueͷར༻͸ۤख
  3. class TaskListWireframe { weak var presentedViewController: UIViewController? func presentViewController(navigationController: UINavigationController)

    { let controller = TaskListViewController(nibName: nil, bundle: nil) let presenter = TaskListPresenter() let interactor = TaskListInteractor() let dataManager = TaskListDataManager() controller.eventHandler = presenter presenter.userInterface = controller presenter.input = interactor interactor.output = presenter interactor.dataManager = dataManager presentedViewController = controller navigationController.pushViewController(controller, animated: true) } } ஫)Ұൠతʹ͸DIΛߦ͍·͢
  4. protocol TaskListViewProtocol: class { func show(tasks: [DisplayTask]) func show(errorMessage: String)

    } extension TaskListViewController: TaskListViewProtocol { func show(tasks: [DisplayTask]) { self.tasks = tasks tableView.reloadData() } func show(errorMessage: String) { // errorMessageΛදࣔ } } class TaskListViewController: UITableViewController { var eventHandler: TaskListModuleProtocol? fileprivate var tasks: [DisplayTask] = [] override func viewDidLoad() { super.viewDidLoad() // লུ eventHandler?.updateView() } // UITableViewDataSource͸লུ }
  5. extension TaskListPresenter: TaskListModuleProtocol { func updateView() { input?.findTasks() } }

    extension TaskListPresenter: TaskListInteractorOutputProtocol { func found(tasks: [Task]) { userInterface?.show(tasks: tasks.map(translate(task:))) } func occurred(error: AppError) { userInterface?.show(errorMessage: translate(error: error)) } } class TaskListPresenter { weak var userInterface: TaskListViewProtocol? var input: TaskListInteractorInputProtocol? } protocol TaskListModuleProtocol { func updateView() } protocol TaskListInteractorOutputProtocol: class { func found(tasks: [Task]) func occurred(error: AppError) }
  6. protocol TaskListInteractorInputProtocol { func findTasks() } class TaskListInteractor: TaskListInteractorInputProtocol {

    weak var output: TaskListInteractorOutputProtocol? var dataManager: TaskListDataManagerProtocol? func findTasks() { dataManager?.findTasks { [weak self] tasks, error in if let error = error { self?.output?.occurred(error: error) } else { self?.output?.found(tasks: tasks) } } } }
  7. protocol TaskListDataManagerProtocol { func findTasks(completion: ([Task], AppError?) -> ()) }

    class TaskListDataManager: TaskListDataManagerProtocol { func findTasks(completion: ([Task], AppError?) -> ()) { completion([Task(title: "First"), Task(title: "Second")], nil) } }
  8. class AddTaskWireframe { func presentAddTaskViewController(parent: UIViewController) { // ભҠίʔυ }

    } protocol TaskListWireframeProtocol { func presentAddInterface() } extension TaskListWireframe: TaskListWireframeProtocol { func presentAddInterface() { guard let controller = presentedViewController else { return } addTaskWireframe?.presentAddTaskViewController(parent: controller) } } class TaskListPresenter { var wireframe: TaskListWireframeProtocol? // লུ… } extension TaskListPresenter: TaskListModuleProtocol { func addNewTask() { wireframe?.presentAddInterface() } // লུ… }
  9. class TaskListPresenterTests: XCTestCase { class UserInterface: TaskListViewProtocol { var calledShowTasks

    = false func show(tasks: [DisplayTask]) { calledShowTasks = true } var calledShowErrorMessage = false func show(errorMessage: String) { calledShowErrorMessage = true } } class Input: TaskListInteractorInputProtocol { var calledFindTasks = false func findTasks() { calledFindTasks = true } } func testUpdateView() { let presenter = TaskListPresenter() let userInterface = UserInterface() let input = Input() presenter.userInterface = userInterface presenter.input = input presenter.updateView() XCTAssertTrue(input.calledFindTasks) } }