RealmWrapper 개발기

강동희
cashwalk
Published in
5 min readJul 24, 2018

쓰기 쉬운 RealmSwift를 조금 더쓰기 쉽도록 템플릿을 제공해주는 ‘RealmWrapper’ 개발기를 적어보려 합니다.

Realm이란

2014년 7월 15일에 공개된 모바일 데이터베이스로 CoreData와 Sqlite에 비해 빠르고 쓰기 쉬우며 다양한 기능을 제공해주는 장점이 있습니다.

다음은 Realm을 사용하는 간단한 예제입니다.

Realm 객체를 생성 후 write메소드를 이용하여 트랜잭션을 열어 user를 추가하는 코드입니다.

Realm 객체를 기본생성자로 생성하는 경우 RLMRealmConfiguration.default()을 이용하여 Realm 객체를 생성하게 됩니다.

App Documents 폴더 안에 default.realm 파일이 생성이 되었고 파일을 실행해보면 age는 20이며 name은 “Kevin”인 데이터가 저장된 것을 확인할 수 있습니다.

다음 예제는 Realm.Configuration을 이용하여 여러종류의 realm 파일을 생성하는 코드입니다.

friendRealm : fileURL을 지정하여 friend.realm을 생성하였습니다.

inMemoryRealm : 데이터를 디스크에 저장하지 않고 메모리에서만 저장하고 사용하는 inMemory.realm을 참조하고 있습니다.

realm 파일이 존재하지 않는다면 새로 생성하고 존재한다면 기존의 realm 파일을 참조하게 됩니다.

생성된 realm 파일은 다음과 같습니다.

Realm.Configuration

Realm.Configuration을 이용하면 다양한 형태의 realm 파일을 생성할 수 있습니다.

Realm.Configuration의 생성자는 다음과 같습니다.

위와 같은 방식으로 쉽게 데이터를 추가하고 Realm 객체를 생성할 수 있지만, 몇가지 단점이 존재합니다.

여러개의 realm 파일을 사용하는 경우 migrationBlock, schemaVersion, objectType 제한 등 많은 옵션의 Realm.Configuration이 설정된다면 realm 파일의 관리가 힘들어집니다.

또한 write메소드를 이용한 Realm 트랜잭션에서 Realm 객체는 동일 스레드에서 생성된 Realm 객체만 접근할 수 있습니다.

이러한 이유로 프로덕션 코드에 복잡한 로직에 Realm 관련 코드가 추가된다면 복잡도가 늘어나게 되어 코드 가독성이 떨어지게 됩니다.

RealmWrapper

캐시워크 iOS에서는 기본적인 Realm DB 뿐만 아니라 AppExtension을 위한 AppGroup DB와 Realm Notification을 이용하기 위한 InMemory DB를 적극 사용하고 있습니다.

이처럼 많은 realm 파일을 사용하고 있기에 realm 파일들을 관리하기 위한 ‘RealmWrapper’를 개발하게 되었습니다.

RealmWrapper에는 2개의 protocol과 1개의 class가 있습니다.

2개의 protocol은 RealmManageable과 RealmProxiable입니다.

1개의 class는 RealmQuery입니다.

RealmManageable

RealmManageable은 Realm객체 생성과 Main Thread에서 Realm 트랜잭션을 보장해주는 protocol입니다.

RealmManageable은 Realm.Configuration에 필요한 Property가 선언되어있습니다.

RealmManageable을 구현한 InMemoryRealmManager에 원하는 Property를 구현합니다.

설정한 Realm.Configuration으로 생성된 Realm 객체를 이용하여 transaction을 열수도 있고, RealmManageable에 transaction 메소드를 이용하여 transaction을 열수도 있습니다.

transaction 메소드는 기본적으로 defaultQueue에서 sync하게 돌아가도록 구현되어 있어 MainThread에서 처리됩니다.

DispatchQueue와 isSync 파라미터 및 콜백 클로저를 추가하여 커스텀하게 transaction을 열 수도 있습니다.

다음과 같이 RealmManageable을 이용하면 realm 파일을 쉽게 관리할수 있게됩니다.

RealmProxiable

RealmProxiable은 Realm 객체에 대신 접근하여 대리자 역할을 하는 protocol입니다.

RealmProxiable을 구현하여 RealmManager 클래스 타입을 선언해주면 선언한 클래스의 transaction 메소드와 RealmQuery 타입으로 반환해주는 query 메소드를 이용할 수 있습니다.

다음과 같이 CRUD의 역할을 대리할 수 있게됩니다.

RealmQuery

RealmQuery는 RealmSwift.Results을 감싸고 있는 클래스로서 Realm Notification 기능을 쉽게 사용할 수 있는 기능을 제공합니다.

Results의 insertions, deletions, modifications을 IndexPath형태로 받을 수 있습니다.

--

--