importUIKitprotocolSampleViewDisplayLogic:class{funcdisplaySomething(viewModel:SampleView.Something.ViewModel)funcdisplayError(viewModel:SampleView.Something.ViewModel)functransitionToSomeWhere(viewModel:SampleView.Sometime.ViewModel)}classSampleViewController:UIViewController,SampleViewDisplayLogic{varinteractor:SampleViewBusinessLogic?varrouter:(NSObjectProtocol&SampleViewRoutingLogic&SampleViewDataPassing)?// MARK: Object lifecycleoverrideinit(nibNamenibNameOrNil:String?,bundlenibBundleOrNil:Bundle?){super.init(nibName:nibNameOrNil,bundle:nibBundleOrNil)setup()}requiredinit?(coderaDecoder:NSCoder){super.init(coder:aDecoder)setup()}// MARK: Setupprivatefuncsetup(){letviewController=selfletinteractor=SampleViewInteractor()letpresenter=SampleViewPresenter()letrouter=SampleViewRouter()viewController.interactor=interactorviewController.router=routerinteractor.presenter=presenterpresenter.viewController=viewControllerrouter.viewController=viewControllerrouter.dataStore=interactor}// MARK: Routingoverridefuncprepare(forsegue:UIStoryboardSegue,sender:Any?){ifletscene=segue.identifier{letselector=NSSelectorFromString("routeTo\(scene)WithSegue:")ifletrouter=router,router.responds(to:selector){router.perform(selector,with:segue)}}}// MARK: View lifecycleoverridefuncviewDidLoad(){super.viewDidLoad()fetchSomethingOnLoad()}// ① Interactorに具体的な処理内容を問い合わせるfuncfetchSomethingOnLoad(){letrequest=SampleView.Something.Request()interactor?.fetchSomething(request:request)}// ② Presenterからの指示を受けてViewを描画するfuncdisplaySomething(viewModel:SampleView.Something.ViewModel){// do something}funcdisplayError(viewModel:SampleView.Something.ViewModel){// do error something}// ③ Routerに画面遷移を依頼するfunctransitionToSomeWhere(viewModel:SampleView.Sometime.ViewModel){// 画面遷移router?.routeToSomeWhere(segue:nil)}}
また、ユーザによるアクション起因の場合は下記のようにするだけです。
12345
@IBActionfunctapSomeAction(_sender:Any){// ① Interactorに具体的な処理内容を問い合わせるletrequest=SampleView.Sometime.Request()interactor?.fetchSometime(request:request)}
importUIKitprotocolSampleViewBusinessLogic{funcfetchSomething(request:SampleView.Something.Request)funcfetchSometime(request:SampleView.Sometime.Request)}protocolSampleViewDataStore{// 画面遷移時にパラメータを受け取れるように定義varsomething:String{getset}}classSampleViewInteractor:SampleViewBusinessLogic,SampleViewDataStore{varpresenter:SampleViewPresentationLogic?varworker=SampleViewWorker?varsomething:String!funcfetchSomething(request:SampleView.Something.Request){// ① WorkerとPresenterを仲介するworker.fetch(success:{(object)in// 処理が成功した場合// ③ Worker経由で取得したレスポンスをPresenterに渡す letresponse=SampleView.Something.Response(object:object,isError:false)self.presenter?.presentSomething(response:response)},failure:{_in// 処理が失敗した場合// ③ Worker経由で取得したレスポンスをPresenterに渡す letresponse=SampleView.Something.Response(object:object,isError:true)self.presenter?.presentSomething(response:response)})funcfetchSometime(request:SampleView.Sometime.Request){// ② どんな条件で、Workerに何の処理を依頼するのかハンドリングするifrequest.time>Date(){letresponse=SampleView.Sometime.Response(future:true)presenter?.presentSometime(response:response)return}letresponse=SampleView.Sometime.Response(future:false)presenter?.presentSometime(response:response)}funcfetchSomeWhat(request:SampleView.SomeWhat.Request){// 画面遷移時に渡されたパラメータを利用した描画を実施したい場合letresponse=SampleView.Something.Response(object:something)self.presenter?.presentSomething(response:response)}}
Worker
Interactor から受けた依頼を実行します。
責務:
① API 処理や Core Data / Realm などのアプリ内ローカルデータの処理をハンドリングする
② 成功/失敗レスポンスをハンドリングする
責務:
① 受け取ったレスポンスを元に最適な表示(成功/失敗などの表示)になるようハンドリングする
② 受け取ったレスポンスを Model.ViewModel 形式に変換する
③ ViewController に Model.ViewModel を渡して描画を依頼する
123456789101112131415161718192021222324252627
importUIKitprotocolSampleViewPresentationLogic{funcpresentSomething(response:SampleView.Something.Response)}classSampleViewPresenter:SampleViewPresentationLogic{weakvarviewController:SampleViewDisplayLogic?// MARK: Present somethingfuncpresentSomething(response:SampleView.Something.Response){// ② 受け取ったレスポンスをModel.ViewModel形式に変換するletviewModel=SampleView.Something.ViewModel(object:response.object)// ① 受け取ったレスポンスを元に最適な表示(成功/失敗などの表示)になるようハンドリングするifresponse.isError{// エラーがある場合// ③ ViewControllerにModel.ViewModelを渡して描画を依頼する viewController?.displayError(viewModel:viewModel)return}// ③ ViewControllerにModel.ViewModelを渡して描画を依頼するviewController?.displaySomething(viewModel:viewModel)}}
Model
Clean Swiftアーキテクチャの肝といっても過言ではないのが Model です。
責務:
① 各種コンポーネントを切り離し、各種コンポーネント間のやり取りに利用される
② Request / Response / ViewModel の3つの構造体を持つ