1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

毎日何か成果物か学んだことを書くAdvent Calendar 2019

Day 8

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

Last updated at Posted at 2019-12-08

最初に

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

今回やったこと

  • MVPを意識しながらアプリを作る
  • クラロワのAPI使って自分のアカウント情報を表示する。

妥協ポイント

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

全体の大まかな流れ

image.png

  1. ViewからInputを通してPresenterの処理を呼びます。
  2. PresenterはModelなどの処理を読んだ後にOutputを通してViewの変更をします。
    先ほども言いましたがこの記事ではViewとPresenterの大まかな流れだけやります。
    Modelの部分は明日の記事でやります。

View

image.png
viewのファイルはこの二つです。
storyboradはただlabelを均等に配置してあるだけです。
image.png
続いてUserViewControllerです。

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

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

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?