iOS 알람 앱 개발 일지 - 타이머 기능 구현

호씨·2025년 1월 14일
1

iOS 알람 앱 개발 일지 - 타이머 기능 구현 ⏰

타이머 알람 연동 기능 구현 💡

타이머 종료 시 알람 화면 표시

타이머의 카운트다운이 완료되었을 때 알람 화면을 표시하고, 선택된 알람음을 재생하도록 구현했다.

// TimerViewModelDelegate 프로토콜 정의
protocol TimerViewModelDelegate: AnyObject {
    func showAlertViewController()
}

class TimerViewModel {
    weak var delegate: TimerViewModelDelegate?
    private var audioPlayer: AVAudioPlayer?
    
    private func playTimerEndMusic() {
        guard let music = selectedMusic, music.name != "무음" else {
            // 음악이 없더라도 알람 화면은 표시
            delegate?.showAlertViewController()
            return
        }
        
        // 음악 재생 설정
        do {
            try AVAudioSession.sharedInstance().setCategory(.playback)
            try AVAudioSession.sharedInstance().setActive(true)
            
            audioPlayer = try AVAudioPlayer(contentsOf: url)
            audioPlayer?.prepareToPlay()
            audioPlayer?.play()
            
            // 음악 재생 후 알람 화면 표시
            delegate?.showAlertViewController()
        } catch {
            print("음악 재생 실패: \(error.localizedDescription)")
            delegate?.showAlertViewController()
        }
    }
}

// TimerView에서 구현
extension TimerView: TimerViewModelDelegate {
    func showAlertViewController() {
        DispatchQueue.main.async { [weak self] in
            let alertVC = AlertViewController()
            alertVC.modalPresentationStyle = .fullScreen
            alertVC.delegate = self
            self?.present(alertVC, animated: true)
        }
    }
}

알람 중단 기능 구현

알람 화면의 "중단" 버튼을 눌렀을 때 동영상 배경과 알람음이 모두 멈추도록 구현했다.

// AlertViewControllerDelegate 프로토콜 정의
protocol AlertViewControllerDelegate: AnyObject {
    func alertViewControllerDidDismiss()
}

// AlertViewController에서 중단 처리
class AlertViewController: UIViewController {
    var player: AVPlayer?
    weak var delegate: AlertViewControllerDelegate?

    @objc private func stopAlarm() {
        player?.pause()  // 배경 동영상 중지
        delegate?.alertViewControllerDidDismiss()  // 알람음 중지 요청
        dismiss(animated: true)
    }
}

// TimerViewModel에서 알람 중지 처리
extension TimerViewModel {
    func stopTimerAndAudio() {
        stopTimer()
        audioPlayer?.stop()
        audioPlayer = nil
    }
}

다시 알림(Snooze) 기능 구현

알람 화면에서 다시 알림 시간을 조정하고 적용할 수 있도록 구현했다.

// AlertViewControllerDelegate에 다시 알림 기능 추가
protocol AlertViewControllerDelegate: AnyObject {
    func alertViewControllerDidDismiss()
    func alertViewControllerDidRequestSnooze(minutes: Int)
}

// AlertViewController에서 다시 알림 처리
@objc private func snoozeAlarm() {
    print("\(snoozeTime)분 후 다시 알림이 설정되었습니다.")
    delegate?.alertViewControllerDidRequestSnooze(minutes: snoozeTime)
    player?.pause()
    dismiss(animated: true)
}

// TimerViewModel에 다시 알림 타이머 설정
extension TimerViewModel {
    func setSnoozeTimer(snoozeMinutes: Int) {
        // 기존 타이머 정보 초기화
        stopTimerAndAudio()
        
        // 새로운 타이머 설정 (분 단위)
        hours = 0
        minutes = snoozeMinutes
        seconds = 0
        
        // 타이머 시작
        startTimer(withName: "다시 알림")
    }
}

UI 디자인 개선

타이머 화면의 색상과 레이아웃을 개선하여 더 나은 사용자 경험을 제공하도록 수정했다.

private func setupBasic() {
    // 배경색 변경
    view.backgroundColor = UIColor(red: 10/255, green: 25/255, blue: 38/255, alpha: 1)
    navigationController?.navigationBar.isHidden = true
}

private func setupComponents() {
    // 컨테이너 배경색 변경
    labelContainerView.backgroundColor = UIColor(red: 0/255, green: 38/255, blue: 77/255, alpha: 1)
    musicContainerView.backgroundColor = UIColor(red: 0/255, green: 38/255, blue: 77/255, alpha: 1)
    
    // 버튼 색상 변경
    resetButton.backgroundColor = UIColor(red: 72/255, green: 144/255, blue: 216/255, alpha: 1)
    playPauseButton.backgroundColor = UIColor(red: 0/255, green: 122/255, blue: 255/255, alpha: 1)
}

구현하면서 배운 점 📚

델리게이트 패턴의 활용

  • 화면 간 통신을 위해 델리게이트 패턴을 활용했다
  • weak 참조를 사용하여 메모리 누수를 방지했다
  • 프로토콜을 통해 명확한 인터페이스를 정의했다

오디오 세션 관리

  • AVAudioSession을 통한 음악 재생 관리
  • 백그라운드에서도 알람이 동작하도록 설정

화면 전환과 상태 관리

  • 모달 화면 전환 시 데이터 전달 방법
  • 알람 상태에 따른 UI 업데이트 처리

UI/UX 개선

  • 사용자 친화적인 색상 선택
  • 직관적인 레이아웃 구성
  • 명확한 시각적 피드백 제공
profile
이것저것 많이 해보고싶은 사람

0개의 댓글

관련 채용 정보