카테고리 없음

FestaGram) AlertController

500beckwon 2020. 5. 11. 16:10

alert을 만들때 하나하나 alertAction만들어서 넣기가 좀 그래서 구글링을 통해 새로운 방식의 alert을 만들어보려고한당.

 

import UIKit

enum SelectedType: String {
    case option = "안내"
    case logout = "로그아웃"
    case block = "차단"
    case report = "신고"
}

 class CommonService {
    static let shread = CommonService()
    
    var orderSelect: SelectedType = .option
}

일단 새로운 파일을 만들고

 

import UIKit
import Firebase

fileprivate let postRef = Firestore.firestore().posts
fileprivate let storeRef = Storage.storage()

struct AlertComponents {
    var title: String?
    var message: String?
    var actions: [UIAlertAction]
    var completion: (() -> Void)?
    
    init(title:String?,
         message: String? = nil,
         actions: [AlertActionComponent],
         completion: (() -> Void)? = nil) {
        self.title = title
        self.message = message
        self.completion = completion
        self.actions = actions.map {
            UIAlertAction(title: $0.title, style: $0.style, handler: $0.hander)
        }
    }
}

struct AlertActionComponent {
    var title: String
    var style: UIAlertAction.Style
    var hander: ((UIAlertAction) -> Void)?
    
    init(title:String, style: UIAlertAction.Style = .default, handler: ((UIAlertAction)-> Void)?) {
        self.title = title
        self.style = style
        self.hander = handler
    }
    
}

protocol AlertPresentable   {
    var optionAlertComponents: AlertComponents { get }
    func selectAlertType(by orderSelect: SelectedType) -> AlertComponents
}

extension AlertPresentable where Self: UIViewController {
    private var alertTitle: String? {
        return optionAlertComponents.title
    }
    
    private var message: String? {
        return optionAlertComponents.message
    }
    
    private var actions: [UIAlertAction] {
        return optionAlertComponents.actions
    }
    
    var alertStyle: UIAlertController.Style {
        return .actionSheet
    }
    
    private var completion: (() -> Void)? {
        return optionAlertComponents.completion
    }
    
    func presentAlert(_ alertStyle: UIAlertController.Style) {
        let alert = UIAlertController(title: alertTitle, message: message, preferredStyle: alertStyle)
        actions.forEach { alert.addAction($0) }
        present(alert, animated: true, completion: completion)
    }

}

이렇게 프로토콜을 이용해서 Controller파일에 프로토콜을 채택하면 다양하게 이용이 가능한데

 

 

extension ViewPostingController {
    func selectAlertType(by orderSelect: SelectedType) -> AlertComponents {
         let _postUID = post?.userUID ?? ""
        switch orderSelect {
        case .option:
            let cancel = AlertActionComponent(title: "취소", style: .cancel) { _ in
                CommonService.shread.orderSelect = .option
            }
            
            let rePostAction = AlertActionComponent(title: "수정", style: .default) { _ in
                
            }
            
            let deleteAction = AlertActionComponent(title: "삭제", style: .default) { _ in
                
            }
            
            let blockAction = AlertActionComponent(title: "차단(Block)", style: .destructive) { _ in
                CommonService.shread.orderSelect = .block
                self.presentAlert(.alert)
            }
            
            let report = AlertActionComponent(title: "신고(Report)", style: .default) { _ in
                CommonService.shread.orderSelect = .report
                self.presentAlert(.alert)
            }
            
            if _postUID == CurrentUID.shread.currentUID {
                let alert = AlertComponents(title: "관리", message: "관리할 항목을 선택해주세요.", actions: [cancel,deleteAction,rePostAction])
                return alert
            } else {
                let alert = AlertComponents(title: "설정", message: "관련 항목을 선택해주세요.", actions: [cancel,blockAction,report])
                return alert
            }
            
        case .block:
            return blockAction()
        case .report:
            return reportAction()
        case .logout:
            return outAction()
        }
    }
    
    func blockAction() -> AlertComponents {
        let blockMessage = "차단을 하시면 해당 유저에 관련된 모든 것을 두번 다시 볼 수 없게 됩니다. 차단하시겠습니까?"
        let okAction = AlertActionComponent(title: "차단", style: .destructive) { _ in
            //FIXME: 차단 기능
            CommonService.shread.orderSelect = .option
            print("차단")
        }
        let cancel = AlertActionComponent(title: "취소", style: .cancel) { _ in
            CommonService.shread.orderSelect = .option
        }
        let alert = AlertComponents(title: "차단", message: blockMessage, actions:[okAction,cancel])
        return alert
    }
    
    func outAction() -> AlertComponents {
        let outMessage = "대화방을 나가면 대화 기록이 없어집니다. 나가시겠습니까?"
        let okAction = AlertActionComponent(title: "나가기", style: .destructive) { _ in
            //FIXME: 나가기 기능
            CommonService.shread.orderSelect = .option
            print("나가기")
        }
        let cancel = AlertActionComponent(title: "취소", style: .cancel) { _ in
            CommonService.shread.orderSelect = .option
        }
        let alert = AlertComponents(title: "차단", message: outMessage, actions:[okAction,cancel])
        return alert
    }
    
    func reportAction() -> AlertComponents {
        let reportMessage = "신고를 하시면 24시간 내에 신고된 컨텐츠의 내용을 확인한 후 제재가 결정됩니다."
        let okAction = AlertActionComponent(title: "신고", style: .destructive) { _ in
            //FIXME: 신고기능
            CommonService.shread.orderSelect = .option
            print("신고")
        }
        let cancel = AlertActionComponent(title: "취소", style: .cancel) { _ in
            CommonService.shread.orderSelect = .option
        }
        let alert = AlertComponents(title: "차단", message: reportMessage, actions:[okAction,cancel])
        return alert
    }
    
    
}

코드가 더 길어진거 같은데 좀더 줄여서 세련되고 있어보이고 머리 잘돌아가게 만들필요가 있을 것 같다 현재 

이 AlertCustom은 3 Controller에 사용중인데 UIViewcontroller에 선언하자니 좀 너무 많이 잡아먹고 해당 옵션들도 

유저가 본인이냐 타인이냐 어떤 컨트롤러냐에 따라 다르게 나와야 해서 좀더 고민해서 고칠 필요가 있는 것 같다

alert을 선택했을 때 enum타입을 다시 설정해줘야 기존의 항목들이 나오는것도 더 번거로워 보이고...

 

일단 이렇게 만들고 좀더 생각해 봐야겠다.