DispatchSourceTimer 이용한 ViewController 자동 종료 테스트 코드

메인스레드 및 백그라운드 스레드에서 사용 가능

NSTimer와 다르게 DispatchSourceTimer는 일시중지 / 재개 등을 할 수 있는 장점이 있음.

예제는 상황과 좀 다르긴하지만 사용하는 방법만 정리했음.

  • interface 정의
    • timerState: 타이머의 상태에 따라 UI버튼에 변화를 주기 위한 값
    • start(): 타이머 시작 
    • resume(): 타이머 재개
    • suspend(): 타이머 일시 중지
    • cancel(): 타이머 취소 (타이머 다시 시작 가능)
  • 참고사이트 : https://onelife2live.tistory.com/44
class TimerTestViewController: UIViewController {

    // 타이머 구동 시간
    var waitingTime: Int = 5
    private var timer: DispatchSourceTimer?
    // 타이머 종료 Closer
    var waitingTimerCloser: (() -> Void)?

	override func viewDidLoad() {
        super.viewDidLoad()
        setup()
    }

	func setup() {
        if self.waitingTime > 0 {
            if self.timer == nil {
                self.timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)
                self.timer?.schedule(deadline: .now(), repeating: 1)
                self.timer?.setEventHandler(handler: { [weak self] in
                    self?.waitingTime -= 1

                    if self!.waitingTime <= 0 {
                        self?.timer?.cancel()
                        self?.timer = nil
                        self?.waitingTime = 0

                        self?.presentingViewController?.dismiss(animated: true) { [weak self] in
                            if let waitingTimerCloser = self?.waitingTimerCloser {
                                waitingTimerCloser()
                            }
                        }
                    }
                })
                self.timer?.resume()
            }
        }
    }
}

[사용방법]

let timerVC = TimerTestViewController.init(nibName: "TimerTestViewController", bundle: nil)
        
timerVC.waitingTime = 10	// 10초
timerVC.waitingTimerCloser = {
	if let timerCloser = waitingTimerCloser {
           timerCloser()
     }
}
        
        
DispatchQueue.main.async {
	timerVC.modalPresentationStyle = .overFullScreen
            
	guard let topVC = UIApplication.currentTopViewController() else {
		log(direction: .ERROR, ofType: self, datas: "UIApplication.currentTopViewController Error")
		return
	}
            
	topVC.present(timerVC, animated: true, completion: nil)
}

+ Recent posts