iOS 타이머 앱 개발일지 - 음악 선택 및 재생 기능 개발

호씨·2025년 1월 10일
0

iOS 타이머 앱 개발일지 - 음악 선택 및 재생 기능 개발 🎵

프로젝트 구조 개선 🏗

새로운 파일 추가

MusicModel.swift

struct MusicModel {
    let id = UUID()
    var name: String
    var filename: String
    var isSelected: Bool
    
    static func defaultMusic() -> MusicModel {
        return MusicModel(name: "무음", filename: "", isSelected: true)
    }
}

주요 특징:

  • UUID를 사용하여 각 음악 파일의 고유성 보장
  • 음악의 메타데이터(이름, 파일명) 및 상태(선택 여부) 관리
  • 정적 메서드를 통한 기본 음악 상태 제공
  • 구조체를 사용하여 값 타입의 이점 활용

MusicSelectViewController.swift

protocol MusicSelectViewControllerDelegate: AnyObject {
    func didSelectMusic(_ music: MusicModel)
}

class MusicSelectViewController: UIViewController {
    weak var delegate: MusicSelectViewControllerDelegate?
    private var audioPlayer: AVAudioPlayer?
    private var currentSelectedMusic: MusicModel?
    private var musicList: [MusicModel] = []
    // UI Components...
}

주요 특징:

  • Delegate 패턴을 통한 화면 간 데이터 전달 구현
  • AVAudioPlayer를 활용한 음악 재생 기능
  • 현재 선택된 음악 상태 관리
  • 음악 목록 데이터 관리

기존 코드 개선

TimerView의 구조를 다음과 같이 개선하였다:

// 레이블 관련 컴포넌트
private let labelContainerView = UIView()
private let labelTextLabel = UILabel()
private let nameTextField = UITextField()

// 음악 관련 컴포넌트
private let musicContainerView = UIView()
private let selectedMusicLabel = UILabel()
private let timerEndButton = UIButton()
  • 관련 UI 요소들을 논리적으로 그룹화
  • Container View 패턴을 통한 레이아웃 관리 개선
  • 명확한 네이밍을 통한 코드 가독성 향상

주요 기능 구현 💻

1. 음악 선택 화면 구현

private lazy var tableView: UITableView = {
    let table = UITableView()
    table.backgroundColor = .clear
    table.register(UITableViewCell.self, forCellReuseIdentifier: "MusicCell")
    return table
}()

private func setupUI() {
    view.backgroundColor = .black
    
    // 컴포넌트 추가 및 제약조건 설정
    view.addSubview(cancelButton)
    view.addSubview(settingButton)
    view.addSubview(tableView)
    view.addSubview(silentButton)
    // Constraints 설정...
}

주요 구현 내용:

  • 모달 형태의 음악 선택 화면 구현
  • SnapKit을 활용한 Auto Layout 설정
  • 다크 모드에 최적화된 UI 디자인
  • 사용자 친화적인 인터랙션 구현

2. 음악 재생 기능 구현

private func playMusic(_ music: MusicModel) {
    print("재생 시도: \(music.name)")
    audioPlayer?.stop()
    
    guard let path = Bundle.main.path(forResource: music.name, ofType: "mp3") else {
        print("음악 파일을 찾을 수 없습니다: \(music.name)")
        return
    }
    
    let url = URL(fileURLWithPath: path)
    
    do {
        try AVAudioSession.sharedInstance().setCategory(.playback)
        try AVAudioSession.sharedInstance().setActive(true)
        audioPlayer = try AVAudioPlayer(contentsOf: url)
        audioPlayer?.prepareToPlay()
        audioPlayer?.play()
        print("재생 시작됨")
    } catch {
        print("음악 재생 실패: \(error.localizedDescription)")
    }
}

주요 구현 내용:

  • AVFoundation 프레임워크를 활용한 음악 재생
  • 에러 처리 및 로깅을 통한 디버깅 용이성
  • 음악 재생 상태 관리 및 제어

3. 데이터 관리 및 상태 전달

extension MusicSelectViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let selectedMusic = musicList[indexPath.row]
        currentSelectedMusic = selectedMusic
        playMusic(selectedMusic)
        
        // 체크마크 업데이트
        musicList.indices.forEach { index in
            musicList[index].isSelected = (index == indexPath.row)
        }
        tableView.reloadData()
    }
}

UI/UX 디자인 개선 🎨

시각적 디자인

  • 일관된 색상 스키마 적용 (다크 모드 기반)
  • 둥근 모서리 처리로 모던한 디자인 구현
  • 적절한 여백과 간격을 통한 가독성 향상

사용자 경험 개선

  • 음악 선택 시 즉각적인 재생으로 피드백 제공
  • 체크마크를 통한 현재 선택 상태 시각화
  • 취소/설정 버튼을 통한 명확한 작업 흐름 제공

코드 구조화 및 유지보수성 ⚙️

MARK 주석을 통한 코드 구조화

// MARK: - Properties
// MARK: - Lifecycle Methods
// MARK: - UI Configuration
// MARK: - Private Methods
// MARK: - Button Actions
  • 코드의 논리적 구조화
  • 빠른 네비게이션 지원
  • 유지보수성 향상

확장성을 고려한 설계

  • Protocol 기반 설계로 유연성 확보
  • 모듈화된 구조로 기능 확장 용이
  • 재사용 가능한 컴포넌트 설계

향후 개선 계획 🚀

성능 최적화

  • 메모리 사용량 최적화
  • 리소스 관리 개선
profile
이것저것 많이 해보고싶은 사람

0개의 댓글

관련 채용 정보