1
3

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.

[swift]Alert内の処理に応じて再びAlertを表示したい(AlertActionを引数にする)

Last updated at Posted at 2020-11-19

タイトル長くなりがち。

やりたい事

アカウント設定画面でログアウトボタンを押した時に、

  • 「ログアウトしますか?」というダイアログに「OK」/「キャンセル」の選択肢を用意。

  • 「OK」を押すと、APIでログアウト処理が行われる。
    →成功すると、「ログアウトしました」というダイアログが表示され、画面が遷移する。
    →失敗すると、「ログアウトに失敗しました」というアラートが表示される。

  • 「キャンセル」を押すと、最初のダイアログが消える。

っていう処理を行いたい:hugging:

とりあえず作ってみた

今回は、

  • ちゃんと読んでほしいアラートは手動で閉じる。
  • お知らせ程度のダイアログは勝手に消える。

みたいな感じでメソッドを使い分けています。

AccountViewController.swift
import UIKit
final class AccountViewController: UIViewController {
    @IBAction private func tappedLogoutButton(_ sender: UIButton) {
        let dialog: UIAlertController = UIAlertController(title: "ログアウト",
                                                          message: "ログアウトしますか?",
                                                          preferredStyle: .alert)
        dialog.addAction(UIAlertAction(title: "OK", style: .default) { _ in
            // 本来はAPI通信の結果をresultに入れています。(今回は割愛)
            let result:Bool = true
            switch result {
            case true:
                AlertUtil.showAlert(title: "Success", message: "ログアウトに成功しました。",viewController: self)
                // 以下に画面遷移処理を追加。(今回は割愛)
            case false:
                AlertUtil.showAlert(title: "ログアウト失敗", message: "ログアウトに失敗しました。", viewController: self)
            }
            dialog.addAction(UIAlertAction(title: "閉じる", style: .cancel))
            self.present(dialog, animated: true)
        })
        
    }
    
}
AlertUtil.swift
struct AlertUtil {
    static func showDialog(title: String, message: String, viewController: UIViewController) {
        let dialog = UIAlertController(title: title,
                                       message: message,
                                       preferredStyle: .alert)
        viewController.present(dialog, animated: true) {
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.2) {
                dialog.dismiss(animated: true, completion: nil)
            }
        }
    }

    static func showAlert(title: String, message: String, viewController: UIViewController) {
        DispatchQueue.main.async {
            let alert = UIAlertController(title: title,
                                          message: message,
                                          preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "キャンセル",
                                          style: .default))
            viewController.present(alert, animated: true)
        }
    }
}

上のコードだと、

:raising_hand:
アラート関連の処理はAlertUtilにまとめちゃお!
でも、API通信の結果によってaddActionの処理を分けたいから・・・
最初のダイアログだけViewControllerで作っちゃお!

って感じ。

でも、他の部分ではアラート表示をAlertUtilで行なっているから、

なるべく統一していきたいな・・・

という事で:open_hands:

alertActionを引数にとる

スッキリ統一感のあるコードにするために、alertActionを引数にとる形に変更してみます。

AccountViewController.swift
import UIKit
final class AccountViewController: UIViewController {
    @IBAction private func tappedLogoutButton(_ sender: UIButton) {
        let alertAction: UIAlertAction = UIAlertAction(title: "OK", style: .default) { _ in
            // 本来はAPI通信の結果をresultに入れています。(今回は割愛)
            let result:Bool = true
            switch result {
            case true:
                AlertUtil.showAlert(title: "Success", message: "ログアウトに成功しました。",viewController: self)
                // 以下に画面遷移処理を追加。(今回は割愛)
            case false:
                AlertUtil.showAlert(title: "ログアウト失敗", message: "ログアウトに失敗しました。", viewController: self)
            }
        }
        AlertUtil.showChoiceDialog(title: "ログアウト", message: "ログアウトしますか?", viewController: self, alertAction: alertAction)
    }
}
AlertUtil.swift
struct AlertUtil {
    static func showDialog(title: String, message: String, viewController: UIViewController) {
        let dialog = UIAlertController(title: title,
                                       message: message,
                                       preferredStyle: .alert)
        viewController.present(dialog, animated: true) {
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.2) {
                dialog.dismiss(animated: true, completion: nil)
            }
        }
    }

    static func showAlert(title: String, message: String, viewController: UIViewController) {
        DispatchQueue.main.async {
            let alert = UIAlertController(title: title,
                                          message: message,
                                          preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "キャンセル",
                                          style: .default))
            viewController.present(alert, animated: true)
        }
    }
    
    // このメソッドを追加
    static func showChoiceDialog(title: String, message: String, viewController: UIViewController, alertAction: UIAlertAction) {
        let dialog: UIAlertController = UIAlertController(title: title,
                                                          message: message,
                                                          preferredStyle: .alert)
        dialog.addAction(UIAlertAction(title: "キャンセル", style: .default))
        dialog.addAction(alertAction)
        viewController.present(dialog, animated: true)
    }
}

こうする事で、

showAlert系のメソッドは全てAleretUtilで作成する事に統一し、

AccountViewController内の記述もスッキリしました:ok_woman::sparkles:

1
3
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
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?