MVP意識しながら自分のクラロワアカウントをアプリに表示する。(ViewとPresenter編)

## 最初に
昨日の記事でクラロワのトップ選手を持ってきましたが今回はMVPを意識しながら自分のユーザーデータをアプリに表示させるところまでやります。
次の記事
https://qiita.com/daichi77/items/f32e31df7b173422b5ed
## 今回やったこと
- MVPを意識しながらアプリを作る
- クラロワのAPI使って自分のアカウント情報を表示する。

## 妥協ポイント
- レイアウトのデザインは全く気にしない。
- 記事を二つに分ける。(今日はviewとpresenterの部分をやります。明日の記事にModel書きます。)

## 全体の大まかな流れ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255216/19491346-4ba0-d4e9-1fdf-8373cba46211.png)
1. ViewからInputを通してPresenterの処理を呼びます。
2. PresenterはModelなどの処理を読んだ後にOutputを通してViewの変更をします。
先ほども言いましたがこの記事ではViewとPresenterの大まかな流れだけやります。
Modelの部分は明日の記事でやります。
## View
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255216/899ce4ef-9b70-2e26-2094-2bdb2f89ad2a.png)
viewのファイルはこの二つです。
storyboradはただlabelを均等に配置してあるだけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255216/91cf275a-1d4d-b5d8-74ea-92fc140d6b80.png)
続いてUserViewControllerです。

```swift:UserViewController.swift
import Foundation
import UIKit
class UserViewController: UIViewController {
    
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var expLevelLabel: UILabel!
    @IBOutlet weak var trophiesLabel: UILabel!
    @IBOutlet weak var bestTrophiesLabel: UILabel!
    private var presenter: UserPresenterInput!
    override func viewDidLoad() {
        super.viewDidLoad()
        self.inject(presenter: UserPresenter(view: self))
        self.presenter.fetchUsers()
    }
    func inject(presenter: UserPresenterInput){
        self.presenter = presenter
    }
}

//outputの部分、Presenterから呼ばれる。
extension UserViewController: UserPresenterOutput {
    
    func updateUser(user: Player) {
        
        //viewの処理なのでメインスレッドで
        DispatchQueue.main.async {
            self.nameLabel.text = user.name//ユーザーネームを代入
            self.expLevelLabel.text = "ランク:\(String(user.expLevel))"//レベルをラベルに代入
            self.trophiesLabel.text = "トロフィー:\(String(user.trophies))"//トロフィーをラベルに代入
            self.bestTrophiesLabel.text = "最高トロフィー:\(String(user.bestTrophies))"//最高トロフィーをラベルに代入
        }
    }
    
}   
}

```
viewControllerでやっていることは単純でPresenterの初期化とOutPutの処理の記述、inputの呼び出しです。
extension Protocolで切り分けることでOutputの部分を明確にしています。
オブザーバー同期だとOutputの部分が宣言的ものになります。
次にPresenterです。
## Presenter

```swift:UserPresenter.swift

import Foundation

protocol UserPresenterOutput: AnyObject {
    func updateUser(user: Player)
}

protocol UserPresenterInput {
    func fetchUsers()
}

class UserPresenter: UserPresenterInput {
    private weak var view: UserPresenterOutput?
    
    init(view: UserPresenterOutput) {
        self.view = view
    }
    
    func fetchUsers(){
        let client = ClashRoyaleClient()
        let request = ClashRoyaleAPI.SearchUser(keyword: "/#99V2VQUQ")
        client.send(request: request) { result in
            switch result {
            case let .success(response):
                self.view!.updateUser(user: response)
            case let .failure(error):
                print(error)
            }
        }
    }
    
    
}
```
Presenterに書いてあるのはprotocolの定義とModelの処理を呼んでその結果次第でOutputを呼ぶInputの部分です。
ViewやPresenter次の記事で出てくるPresenterをProtocolで切り出すことで完全に疎結合にしてtestをしやすくしています。
Inputの部分ではModelのAPIを叩く処理を呼び出してその後にOutputを呼び出しています。

## 言い訳タイム
時間がなく忙しいのでModelの部分(APIを叩く部分)は明日書きます。
次の記事(Model編)
https://qiita.com/daichi77/items/f32e31df7b173422b5ed