extension MyPageViewController: MyPageViewLoginDelegate {
func myPageViewDidRequestLogin() {
let alert = UIAlertController(title: "로그인이 필요합니다.",
message: "로그인 하시겠습니까?",
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "확인", style: .default, handler: { _ in
print("확인 버튼 누름")
// 로그인 화면으로 이동
let signInVC = SigninViewController()
let signInNavController = UINavigationController(rootViewController: signInVC)
signInNavController.modalPresentationStyle = .fullScreen
// 현재 윈도우 가져와서 루트 변경
if let sceneDelegate = UIApplication.shared.connectedScenes.first?.delegate as? UIWindowSceneDelegate,
let window = sceneDelegate.window {
window?.rootViewController = signInNavController
window?.makeKeyAndVisible()
}
}))
alert.addAction(UIAlertAction(title: "취소", style: .destructive, handler: nil))
self.present(alert, animated: true, completion: nil)
}
func myPageViewDidRequestLogOut() {
let alert = UIAlertController(title: "로그아웃 하시겠습니까?", message: "",
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "확인", style: .default, handler: { _ in
print("확인 버튼 누름")
// 로그인 화면으로 이동
let signInVC = SigninViewController()
let signInNavController = UINavigationController(rootViewController: signInVC)
signInNavController.modalPresentationStyle = .fullScreen
// 현재 윈도우 가져와서 루트 변경
if let sceneDelegate = UIApplication.shared.connectedScenes.first?.delegate as? UIWindowSceneDelegate,
let window = sceneDelegate.window {
window?.rootViewController = signInNavController
window?.makeKeyAndVisible()
}
}))
alert.addAction(UIAlertAction(title: "취소", style: .destructive, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
마이페이지에서
1) 로그아웃을 시도하는 경우
2) 로그인을 시도하는 경우
2가지의 경우의 알럿창을 만들어야 했다!
그런데 둘 다 로그인 화면으로 이동하게 하는 알럿이었고, 단순하게 알림창의 title과 message만 달랐음
이때 급하게 진행을 해서 일단 push하고 Merge를 해야했기에.. 중복 코드를 사용했고,, 내내 마음이 쓰였다 ㅜ_ㅜ
알럿 창을 만들어서, 로그인 화면으로 가는 로직이 동일하다!
그리하여 내가 개발한 파트의 리팩토링을 진행하기로 마음 먹음!
단순하게 중복되는 코드만 따로 분리해줬다.
extension MyPageViewController: MyPageViewLoginDelegate {
func myPageViewDidRequestLogin() {
let alert = UIAlertController(title: "로그인이 필요합니다.",
message: "로그인 하시겠습니까?",
preferredStyle: .alert)
showAlert(alert)
}
func myPageViewDidRequestLogOut() {
let alert = UIAlertController(title: "로그아웃 하시겠습니까?", message: "",
preferredStyle: .alert)
showAlert(alert)
}
func showAlert(_ alert: UIAlertController) {
alert.addAction(UIAlertAction(title: "확인", style: .default, handler: { _ in
print("확인 버튼 누름")
// 로그인 화면으로 이동
let signInVC = SigninViewController()
let signInNavController = UINavigationController(rootViewController: signInVC)
signInNavController.modalPresentationStyle = .fullScreen
// 현재 윈도우 가져와서 루트 변경
if let sceneDelegate = UIApplication.shared.connectedScenes.first?.delegate as? UIWindowSceneDelegate,
let window = sceneDelegate.window {
window?.rootViewController = signInNavController
window?.makeKeyAndVisible()
}
}))
alert.addAction(UIAlertAction(title: "취소", style: .destructive, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
showAlert라는 함수를 생성하여 매개변수로 UIAlertController를 받아올 수 있도록 만들었다!
클로드에게 리팩토링 방향을 물어봤더니,
extension MyPageViewController: MyPageViewLoginDelegate {
// 공통으로 사용되는 로그인 화면 전환 로직
private func navigateToSignIn() {
let signInVC = SigninViewController()
let signInNavController = UINavigationController(rootViewController: signInVC)
signInNavController.modalPresentationStyle = .fullScreen
if let sceneDelegate = UIApplication.shared.connectedScenes.first?.delegate as? UIWindowSceneDelegate,
let window = sceneDelegate.window {
window?.rootViewController = signInNavController
window?.makeKeyAndVisible()
}
}
// 공통으로 사용되는 알럿 표시 로직
private func showAlert(title: String, message: String, completion: (() -> Void)?) {
let alert = UIAlertController(title: title,
message: message,
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "확인", style: .default, handler: { _ in
print("확인 버튼 누름")
completion?()
}))
alert.addAction(UIAlertAction(title: "취소", style: .destructive, handler: nil))
self.present(alert, animated: true, completion: nil)
}
func myPageViewDidRequestLogin() {
showAlert(
title: "로그인이 필요합니다.",
message: "로그인 하시겠습니까?",
completion: navigateToSignIn
)
}
func myPageViewDidRequestLogOut() {
showAlert(
title: "로그아웃 하시겠습니까?",
message: "",
completion: navigateToSignIn
)
}
}
위와 같이 답변을 해주었다.
알럿을 표시해주는 함수와 화면 전환 함수도 분리했다.
-> 이렇게 분리하면 재사용성이 더 높아질 거 같다! 특히 showAlert라는 함수를 계속 사용할 수 있음..
코드를 더 자세히 살펴보면
private func showAlert(title: String, message: String, completion: (() -> Void)?)
completion: (() -> Void)?
- 옵셔널 클로저를 파라미터로 받음
- () -> Void는 파라미터 없고 반환값도 없는 클로저 타입
- ?가 붙어서 클로저 자체가 옵셔널 (전달하지 않아도 됨)
alert.addAction(UIAlertAction(title: "확인", style: .default, handler: { _ in
print("확인 버튼 누름")
completion?() // 옵셔널체이닝
}))
completion?()
- 옵셔널 체이닝으로 completion 클로저 실행
- completion이 nil이 아닐 때만 실행됨
- "확인" 버튼을 눌렀을 때 전달받은 클로저가 실행됨
completion을 옵셔널로 만들어주어 단순 알림용으로, nil인 경우에도 사용할 수 있게 함. . .