이전 포스팅에서는 최근 검색어를 메모리 상에서만 저장하도록 구현했었다. 검색 화면을 벗어난 후 다시 들어갔을 경우에는 입력한 검색어들이 사라지게 되었다. 그래서 다음 포스팅에서는 최근 검색어들을 서버에 저장하여 UI에 표시하도록 하기로 하였다.
그렇지만 많은 앱들이 서버와 로컬 중 어디에 저장하는지를 알고 싶었다. 확인해본 결과 많은 앱들은 네트워크 연결이 불가능한 상태에서는 메인 화면들로 진입하지 못했다. 일부 앱에서는 네트워크 불가능한 상태에서 최근 검색어가 유지되는 것을 확인할 수 있었다. 그래서 회사마다 다르겠지만 구현한 최근 검색어를 로컬 DB를 이용해 유지할 수 있도록 구현해보고자 한다!
SQLite를 쉽게 사용할 수 있도록 하는 Room 라이브러리를 사용하기 위해 다음과 같이 종속 항목을 추가하였다.
Room 라이브러리를 사용하여 DB에 있는 데이터를 제어하기 위해서는 크게 세 가지 항목이 구현되어야 한다.
외부에 노출되는 데이터 클래스인 SearchKeyword와 로컬에 직접 저장되는 데이터 클래스인 LocalSearchKeyword, 총 두 개의 클래스를 생성하였다.
LocalSearchKeyword 클래스는 Room 라이브러리의 어노테이션을 붙였다.
Dao 인터페이스를 생성하고 인터페이스 안에 데이터를 액세스하고 제어할만한 쿼리 함수를 생성하였다. Insert함수에서 onConflict를 설정한 이유는 이미 DB에 저장되어 있는 최근 검색어를 다시 입력한 경우가 있기 때문에 Replace 전략으로 설정하였다.
Room 라이브러리의 Database 어노테이션을 붙여 AppDatabase라는 추상 클래스를 생성하였다. 그리고 Dao를 사용할 수 있도록 하기 위해 추사 메소드를 추가하였다.
그리고 싱글톤으로 AppDatabase 객체를 사용하기 위해 DatabaseModule 오브젝트 안에 싱글톤 인스턴스를 리턴하는 함수를 만들었다.
Room 라이브러리를 사용하여 DB를 제어하기 위해 꼭 구현에 필요하지는 않지만, 외부에 노출되는 SearchKeyword 데이터 클래스와 로컬에 저장되는 LocalSearchKeyword 데이터 클래스를 구분하였기 때문에 Repository가 로컬과 외부 데이터 클래스를 적절히 변환하여 사용할 수 있도록 하도록 구현하였다.
의존성 자동 주입 라이브러리를 사용하지 않고 구현하다보니 직접 인스턴스를 생성하여 관리하고, ViModelFactory를 통해서 ViewModel을 생성하는 등 조금 번거로웠다.
이번 구현을 위해 테스트했을 때 여러 앱이 네트워크 연결 여부에 따라서 다이얼로그가 나타나고 다음 화면으로 진입이 불가능하게 구현했다는 것을 경험했다. 그래서 다음에 직접 네트워크 연결 여부를 파악하고 네트워크 연결이 되어 있는 경우에만 앱을 이용할 수 있도록 구현해볼 예정이다.