Skip to content

radiantchoi/WhereIsMyMusic

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

들어봄 (Heard It Before)

"이 곡 뭔지 알아?" "일단 한번 들어봄"

들어봄은 어떤 앱인가요?

  • "지금 들리는 음악을 앞으로도 들을 수 있게 하는 앱"을 목표로, 오디오 인식을 통해 음원 정보를 찾아 주고 해당 검색 결과를 기반으로 국내 음원 사이트에 다시 검색해주는 앱입니다.
  • 국내 음원 사이트마다 보유하고 있는 음원의 풀이 다르다는 불편함에 착안해 만들어졌습니다.
  • 한 번의 음성 기반 검색을 통해 6개의 음원 사이트에 한 번에 검색할 수 있습니다.

App Store 링크

프로젝트 기능

검색 도중 취소 및 성공시 검색 실패시
검색성공_AdobeExpress 검색실패_AdobeExpress

음성 인식을 통한 음악 검색

  • 검색 버튼을 누르면, 기기의 마이크를 사용해 음원을 수집하고, ShazamKit 데이터베이스에 기반해 검색합니다.
  • 검색에 성공했을 시 검색 결과 화면으로 넘어가고, 검색에 실패했을 시 에러 팝업을 띄웁니다.

검색 결과의 제목을 기반으로 국내 다른 음원 사이트에 검색

  • 음원을 인식해 검색에 성공했을 시, 해당 검색 결과를 기반으로 국내 여러 음원 사이트에 검색하고, 그 검색 결과를 가져옵니다.
    • 현재 지원하는 음원 사이트로는 애플뮤직, 멜론, 벅스, 지니, 플로, 유튜브가 있습니다.

기술 스택

MVC → MVVM

  • Why? → 처음 앱을 만들기 시작했을 때는 음성을 통한 음악 검색이라는 최소한의 목적을 가진 MVP를 빠르게 만들기 위해 애플 앱 개발의 기본인 MVC로 앱을 작성했습니다. 이후 이 서비스가 기능을 확장할 여지가 많다고 판단해, MVVM으로 리팩토링을 진행했습니다.
  • How? → UI를 보여주는 View와 데이터를 담고 있는 Model, 비즈니스 로직을 담고 있는 View Model로 분리함으로써 서로의 역할을 분리하였습니다.
  • Result! → 각각의 역할이 명확히 구분되어 있기 때문에, 한층 수월하게 개발할 수 있었습니다. 특히 처음 릴리즈할 때보다 리팩토링 및 기능 추가를 수행할 때 장점이 부각되었습니다.

Clean Architecture (Refactoring)

  • Why? → 앞으로 여러 가지 다른 기능을 더하기 위해서는 어떤 식으로 리팩토링할까 고민했습니다. 기능의 확장에 열려있는 구조에 대해 고민해본 결과, Clean Architecture를 적용하기로 했습니다. Layer를 기준으로 분리하고, Outer Layer에 대해 아무것도 모르게 함을 통해 비즈니스 로직의 결합도를 낮추려는 Clean Architecture의 철학이 이러한 목적과 일치하다고 느껴 채택하였습니다.
  • How? → 코드의 역할에 따른 분리에 집중하였습니다. 하나의 기능을 나타내는 코드들은 UseCase로 작성하여 관리하였습니다. 또한, 데이터를 주거나 받는 부분은 Repository로 만들어 다루었습니다. 이때, 각각의 UseCase 및 Repository는 Protocol Type을 만들어 직접적으로 구현체에 의존하지 않도록 하였고, 로직 자체를 쉽게 갈아낄 수 있도록 만들었습니다.
  • Result! → Protocol에 함수의 interface를 작성하는 것만으로 어디에 함수를 구현할지 쉽게 알 수 있었고, 개발하는 과정에서 상당한 편의성을 느낄 수 있었습니다. 향후 테스트를 진행할 때, Mock 객체와 Implement 객체를 쉽게 바꿀 수 있기 때문에 이 측면에서도 한층 수월할 것이라 기대됩니다.

Reactive Programming (RxSwift)

  • Why? → 여러 외부 API에 네트워크 통신을 요청하고 그 결과를 통해 서비스를 작동시키기 때문에, URLSession을 이용한 통신이 잦고 그 결과를 비동기적으로 받아오는 과정에서 Callback Hell이 일어날 확률이 높습니다. 이러한 Callback Hell은 가독성 및 로직의 유연성을 많이 저해합니다. RxSwift는 이러한 로직과 그에 따른 데이터를 함수형 패러다임에 맞게 다룰 수 있도록 도와줍니다.
  • How? → 대표적으로, 서버 통신의 결과를 Single로 만들어 리팩토링 중입니다. 하나의 network request는 데이터를 보내거나 받기 위한 단일 통신이기에, Session을 유지할 필요가 없어 Single을 사용하였습니다. 테스트가 용이하고 또한 확장에 유연한 코드, 다시 말해 표현력이 높은 코드를 작성하기 위해 map과 같은 고차함수들의 사용을 지향하였습니다.
  • Result! → 검색 결과를 받는 과정에서 map, flatMap 등의 고차함수 및 operator를 사용하여 보다 가독성있고, 유연한 로직을 작성하였습니다.

ShazamKit

  • Why? → 애플의 음원 인식 SDK로, 앱의 메인 기능인 음성 기반 음악 검색을 구현하기 위해 사용했습니다.
  • How? → 검색 로직을 구조적으로 분리해, ShazamKit 관련 로직에 특화된 객체를 만들고 활용했습니다.
  • Result! → 3~12초 사이의 Signature를 외부 마이크 입력을 통해 생성하여, 원활히 검색할 수 있었습니다.

업데이트 예정사항

  • Spotify, Vibe 사이트 지원
  • 개인 계정 로그인 지원 - Apple Login 등의 OAuth 활용
    • 검색 기록을 저장하고 표시
  • 텍스트 기반 검색
  • 검색 UI 편의성 증대: 검색 버튼 확대 혹은 변경
  • 검색 결과로 반환된 음악 재생