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

VIPER

Avatar for lcr3 lcr3
December 10, 2020

 VIPER

VIPERの仕様をまとめました

Avatar for lcr3

lcr3

December 10, 2020

More Decks by lcr3

Other Decks in Programming

Transcript

  1. Router protocol WeatherListWireframe { func showWeatherDetail(forecasts: [Forcast]) } class WeatherListRouter

    { private unowned let viewController: UIViewController init(viewController: UIViewController) { self.viewController = viewController } // DI static func assembleModules() -> UIViewController { let view = WeatherListViewController.instantiate() let router = WeatherListRouter(viewController: view) let interector = WeatherListInteractor() let presenter = WeatherListPresenter(view: view, interactor: interector, router: router) view.presenter = presenter // ViewʹPresenterΛઃఆ return view } } extension WeatherListRouter: WeatherListWireframe { // Protocolʹ४ڌ func showWeatherDetail(forecasts: [Forcast]) { let weatherDetailView = WeatherDetailRouter.assembleModules(forecasts: forecasts) viewController.navigationController?.present(weatherDetailView, animated: true) } } • ʮը໘ભҠʯͱʮDIʯΛ୲౰
  2. View • Viewͷߋ৽ • ϢʔβʔͷΠϕϯτ௨஌ protocol WeatherListView: AnyObject { func

    showWeatherData(weathers: [WeatherEntity]) func showErrorAletView(errorMessage: String) var presenter: WeatherListPresentation! { get } } class WeatherListViewController: UIViewController { var presenter: WeatherListPresentation! var weathers: [WeatherEntity] @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() // Presenterʹσʔλऔಘґཔ presenter.viewDidLoad() } } extension WeatherListViewController: WeatherListView { // Presenter͔Βσʔλऔಘ੒ޭ௨஌ func showWeatherData(weathers: [WeatherEntity]) { weathers = weathers tableView.reloadData() } // Presenter͔Βσʔλऔಘࣦഊ௨஌ func showErrorAletView(errorMessage: String) { // ΤϥʔΞϥʔτදࣔॲཧ } } extension WeatherListViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { // Presenterʹηϧ͕λοϓ͞Εͨ௨஌ΛૹΔ let index = indexPath.row presenter.weatherListCellTouched(forecasts: weathers[index].forecasts) } }
  3. Presenter • View͔Βड͚औͬͨΠϕϯτΛݩʹґཔ protocol WeatherListPresentation { func viewDidLoad() func weatherListCellTouched(forecasts:

    [Forcast]) } class WeatherListPresenter { private weak var view: WeatherListView? private let router: WeatherListWireframe private let interactor: WeatherListUsecase // RouterͰDI͢Δͱ͖ʹ࢖༻͢Δ init(view: WeatherListView, interactor: WeatherListUsecase, router: WeatherListWireframe) { self.view = view self.interactor = interactor self.router = router } } extension WeatherListPresenter: WeatherListPresentation { func viewDidLoad() { // Interactorʹఱؾͷ৘ใͷऔಘΛґཔ interactor.getWeatherList() { [weak self] result in switch result { case .success(let weathers): // Viewʹσʔλऔಘ੒ޭΛ௨஌ view?.showWeatherData(weathers: weathers) case .failure: // ViewʹσʔλऔಘࣦഊΛ௨஌ view?.showErrorAlert(errorMessage: "औಘʹࣦഊ͠·ͨ͠ɻ") } } } func weatherListCellTouched(forecasts: [Forcast]) { // Routerʹৄࡉը໘΁ͷભҠΛґཔ router.showWeatherDetail(forecasts: forecasts) } } import UIKit
  4. Interactor • API΁ͷ΍ΓͱΓΛ୲౰ protocol WeatherListUsecase { func getWeatherList(completion: @escaping (Result<[WeatherEntity],

    Error>) -> Void) } class WeatherListInteractor { private let client: APIRequestable // MockΛࠩ͠ସ͑ΕΔΑ͏ʹ͓ͯ͘͠ init(client: APIRequestable = APIClient()) { self.client = client } } extension WeatherListInteractor: WeatherListUsecase { func getWeatherList(completion: @escaping (Result<[WeatherEntity], Error>) -> Void) { let request = WeatherAPI.getWeatherList() client.send(request: request) { result in completion(result) } } }
  5. Entity • σʔλߏ଄ͷఆٛ • ϩδοΫΛ࣋ͨͳ͍Α͏ʹ͢Δ struct WeatherEntity: Codable { var

    title: String var link: String var location: Location var forecasts: [Forcast] }
  6. ୯ମςετ • ςετର৅͕ґଘ͍ͯ͠ΔΫϥεͷMockΛ࡞੒ • ςετ͍ͨ͠ର৅ͷϝιουΛݺͼग़ͯ͠ class WeatherListPresenterTests: XCTestCase { //

    ґଘ͢ΔΫϥεͷॳظԽ let view = MockWeatherListView() let interactor = MockWeatherListInteractor() let router = MockWeatherListRouter() var presenter: WeatherListPresenter! override func setUpWithError() throws { super.setUp() // DI presenter = WeatherListPresenter(view: view, interactor: interactor, router: router) view.presenter = presenter } func testViewDidLoad() { // presenterͷviewDidLoadΛґཔ͞Εͨͱ͖ presenter.viewDidLoad() // interactorʹσʔλऔಘ͕ґཔ͞Ε͍ͯΔ͜ͱ XCTAssertEqual(interactor.callCountGetLocations, 1) }
  7. ·ͱΊ • ୯Ұ੹೚ͷݪଇΛ΋ͱʹద੾ʹΫϥε෼ׂ͢Δ • ը໘ੜ੒͸ Router Ͱߦ͍ɺΫϥε಺෦Ͱ init() ౳Λ͠ͳ͍ •

    ෼ׂ͞ΕͨͦΕͧΕͷΫϥε͸protocolΛհͯ͠ΞΫηε͢Δ͜ͱ • View ͱ Router Ҏ֎͸ import UIKit ېࢭ • MockΛ࢖ͬͯςετର৅ʹඞཁͳΫϥεͳͲΛࠩ͠ସ͑Δ͜ͱͰUnitςετՄ ೳ •