## 問題  上記のように、ボタンを押したらリクエストが発生して、いいねできる画面があります。 `FavoriteButton.isFavorited` の値を変えると見た目が変わります。 1. リクエストが完了してからいいねボタンの見た目を変えていますが、APIのレスポンスが遅いとボタンの反応が遅いと思われてしまいます。リクエスト前にボタンの見た目を変えるように変更してください 2. リクエストが失敗したら、いいねボタンの見た目を元に戻してください 3. いいねボタンが連打されてもリクエストが大量に発生しないようにしてください ※いいねの解除は実装しなくて大丈夫です ※MVP版とReactorKit版と素ViewController版があるので好きなテンプレートを使ってください。どのテンプレートを使っても問題ありませんが、素ViewControllerのテンプレートを選んだ場合は、この実装の問題点を教えてください。テンプレートを使わなくても構いません。 ※コードの正確性は求めていないので、雰囲気で動けばOKです ※わからないことがあったらインターネットで調べずに、面接官に聞いてください ### MVP版テンプレート ```swift protocol IllustPresenterInput: AnyObject { func onFavorited() } protocol IllustPresenterOutput: AnyObject { func setIsFavorited(_ isFavorited: Bool) func setIsEnabled(_ isEnabled: Bool) } final class IllustViewController: UIViewController { @IBOutlet private weak var favoriteButton: FavoriteButton! { didSet { favoriteButton.addTarget(self, action: #selector(handleTapped(_:)), for: .touchUpInside) } } var presenter: IllustPresenter? @objc func handleTapped(_ sender: UIButton) { presenter.onFavorited() } } extension IllustViewController: IllustPresenterOutput { func setIsFavorited(_ isFavorited: Bool) { favoriteButton.isFavorited = isFavorited } func setIsEnabled(_ isEnabled: Bool) { favoriteButton.isUserInteractionEnabled = isEnabled } } final class IllustPresenter: IllustPresenterInput { init(favoriteRepository: FavoriteRepository) { self.favoriteRepository = favoriteRepository } private weak var view: IllustPresenterOutput! private let favoriteRepository: FavoriteRepository func onFavorited() { view.setIsFavorited(true) view.setIsEnabled(false) favoriteRepository.favorite { result in view.setIsEnabled(true) switch result { case .success: break case let .failure(error): // エラー処理 view.setIsFavorited(false) } } } } ``` ### ReactorKit版テンプレート ```swift final class IllustViewController: UIViewController, StoryboardView { @IBOutlet private weak var favoriteButton: FavoriteButton! typealias Reactor = IllustReactor var disposeBag = DisposeBag() func bind(reactor: Reactor) { favoriteButton.rx.tap .map { Reactor.Action.favorite } .bind(reactor.action) .disposed(by: disposeBag) reactor.state.map { $0.isFavorited } .bind(to: favoriteButton.rx.isFavorited) .disposed(by: disposeBag) } } final class IllustReactor: Reactor { init(favoriteRepository: FavoriteRepository) { self.favoriteRepository = favoriteRepository } private let favoriteRepository: FavoriteRepository enum Action { case favorite } enum Mutation { case setFavorited(_ isFavorited: Bool) } struct State { var isFavorited: Bool = false } func mutate(action: Action) -> Observable<Mutation> { switch action { case favorite: return favoriteRepository.favorite() .flatMap { .just(.setFavorited(true)) } .catchError { error in .empty() } } } func reduce(state: State, mutation: Mutation) -> State { var state = state switch mutation { case let .setFavorited(isFavorited): state.isFavorited = isFavorited } return state } } ``` ### 素ViewController版テンプレート ```swift final class IllustViewController: UIViewController { @IBOutlet private weak var favoriteButton: FavoriteButton! { didSet { favoriteButton.addTarget(self, action: #selector(handleTapped(_:)), for: .touchUpInside) } } private let repository = FavoriteRepository() @objc func handleTapped(_ sender: UIButton) { favoriteRepository.favorite { result in switch result { case .success: favoriteButton.isFavorited = true case let .failure(error): // エラー処理 } } } } ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up