タイトル長くなりがち。
やりたい事
アカウント設定画面でログアウトボタンを押した時に、
-
「ログアウトしますか?」というダイアログに「OK」/「キャンセル」の選択肢を用意。
-
「OK」を押すと、APIでログアウト処理が行われる。
→成功すると、「ログアウトしました」というダイアログが表示され、画面が遷移する。
→失敗すると、「ログアウトに失敗しました」というアラートが表示される。 -
「キャンセル」を押すと、最初のダイアログが消える。
っていう処理を行いたい
とりあえず作ってみた
今回は、
- ちゃんと読んでほしいアラートは手動で閉じる。
- お知らせ程度のダイアログは勝手に消える。
みたいな感じでメソッドを使い分けています。
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)
}
}
}
上のコードだと、
アラート関連の処理はAlertUtilにまとめちゃお!
でも、API通信の結果によってaddActionの処理を分けたいから・・・
最初のダイアログだけViewControllerで作っちゃお!
って感じ。
でも、他の部分ではアラート表示をAlertUtilで行なっているから、
なるべく統一していきたいな・・・
という事で
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内の記述もスッキリしました