Rmp demos cover

데모와 함께 하는 Realm 모바일 플랫폼 따라잡기: Scanner, RealmPop 예제

이번 Realm World Tour 2017 행사는 여러 도시에서 열리는 Realm 소개 행사로써, 한국에서는 서울과 부산에서 진행됐습니다. Realm의 데모 앱인 Scanner와 RealmPop으로 Realm 모바일 플랫폼의 사용법을 알려드리는 세션입니다.


앱 소개

먼저 데모 앱에서 어떻게 Realm 모바일 플랫폼이나 Realm 모바일 데이터베이스를 쓰는지 말씀드리겠습니다.

Scanner

Scanner 앱은 사진이나 책을 스캔해서 IBM Watson 서비스를 돌려서 거기서 처리한 결과를 반환합니다.

rwt-seoul-demo-scanner

  1. 사용자가 사진을 찍으면
  2. 로컬 DB에 동기화됩니다.
  3. 그러면 로컬 DB와 서버가 자동으로 동기화되고,
  4. 서버의 이벤트 핸들러가 열립니다.
  5. 이벤트 핸들러가 이미지 처리를 위해 Watson에 데이터를 보내면
  6. Watson이 데이터를 분석하고
  7. 처리 결과를 다시 이벤트 핸들러에 반환합니다.
  8. 이벤트 핸들러는 이를 서버의 DB에 업데이트하고,
  9. Realm 오브젝트 서버와 로컬 DB가 자동으로 동기화되며,
  10. 마지막으로 클라이언트의 변경 리스너가 호출되고 변경 데이터로 UI를 갱신합니다.

Scanner 앱은 GitHub에서 다운받을 수 있습니다.

RealmPop

rwt-seoul-demo-realmpop

RealmPop은 iOS와 안드로이드의 앱으로 즐기는 게임 형태입니다. 먼저 사용자의 이름을 입력하고 대기 중인 상대를 선택해서 1:1 게임을 매칭합니다. 게임이 시작되면 위치는 다르지만 동일한 숫자가 화면에 보이는데, 각자 가장 큰 수를 선택해 나가는 방식으로 진행합니다. 잘못 클릭한 사람이 지게 됩니다.

이런 개발 뉴스를 더 만나보세요

RealmPop 앱은 GitHub에서 다운받을 수 있습니다. 이제 이런 데모 앱에 Realm 모바일 데이터베이스와 플랫폼이 어떻게 사용됐는지 말씀드리겠습니다.

Realm 오브젝트 서버

rwt-seoul-demo-rmp

Realm 모바일 플랫폼은 두 가지 요소로 이뤄집니다. 오브젝트 서버와 모바일 데이터베이스의 짝으로 이뤄집니다. 이중 Realm 모바일 데이터베이스는 iOS, Android, React Native, Xamarin 환경에서 사용하는 로컬 데이터베이스이고, Realm 오브젝트 서버는 서버 단에서 자동으로 연동해서 여러 디바이스나 사용자 간에 동기화가 되는 서버입니다. 이 두 구성요소는 자동으로 동기화되고, 오브젝트 서버는 데이터가 변경될 때마다 별도로 연결된 이벤트 핸들러가, 앱 내에서는 내부에 포함된 이벤트 핸들러가 호출될 수 있습니다.

rwt-seoul-demo-object-server-ui

Realm 오브젝트 서버는 로그와 액세스 토큰을 제공하며, 콘솔은 웹 UI 형태입니다.

빌드 설정

이제 Java나 Swift에서 어떻게 간단하게 설정할 수 있는지 알아보겠습니다.

Java

rwt-seoul-demo-build-1

루트 build.gradle에 realm-gradle-plugin에 대한 의존성을 넣어주세요. 화면에서는 2.2.2를 보여주고 있지만 3 버전이 배포됐으므로 맞는 버전을 사용하시면 됩니다. Realm을 사용하려면 디펜던시 설정 외에도 플러그인 등록이 필요합니다.

rwt-seoul-demo-build-2

앱 내의 build script에서 플러그인 방식으로 적용해주세요. 이렇게 하는 이유는 동기화가 필요없는 분이나 버전이 다른 사용자에게 필요 이상의 API를 제공하지 않고 각 상황마다 유연하게 대처할 수 있도록 하기 위해서입니다. syncEnabled로 동기화를 활성화할 수 있는데 false인 경우 Realm 모바일 데이터베이스만 동기화 기능없이 사용할 수 있고 true인 경우 동기화를 사용할 수 있습니다. 기본 경로는 app 디렉터리입니다.

rwt-seoul-demo-build-3

이제 Application을 설정합니다. 일종의 전역 초기화를 위해 Application 객체를 사용하는데, Realm을 위한 여러 설정을 추가할 수 있습니다.

rwt-seoul-demo-build-4

그런 다음 AndroidManifest.xml에 방금 만든 Application 객체를 등록합니다.

Swift

CocoaPods나 Dynamic Framework로 설정할 수 있습니다. CocoaPods로 할 경우 Podfile에 Realm을 설정한 다음, pod install을 합니다.

모델

Scanner

rwt-seoul-demo-scan-model

Scanner 앱의 Swift 코드로 모델을 보겠습니다. Scan이라는 모델을 위해서는 객체를 만들면 됩니다. null을 허용한다면 optional로 설정해 주시고, 허용하지 않으면 기본값을 설정해 주세요.

rwt-seoul-demo-scan-model-java

Java의 경우 RealmObject를 상속해서 객체를 만들고, null을 허용하지 않는 경우 @Required 어노테이션을 붙여주세요. getter/setter는 꼭 만들지 않아도 괜찮습니다.

RealmPop

rwt-seoul-demo-realmpop-pk

RealmPop의 모델은 Scanner보다 복잡하므로 다 보여드리진 않겠지만, 기본키를 사용하는 부분이 있어 예시로 보여드리겠습니다. Swift의 경우 PrimaryKey 함수를 오버라이드해서 설정합니다.

rwt-seoul-demo-realmpop-java

역시 어노테이션으로 @PrimaryKey를 설정합니다. getter/setter를 생성하는 경우 안드로이드 스튜디오의 단축키 기능을 활용하세요.

인증

이제 인증을 통해 서버의 동기화 Realm에 접근하는 방법을 알려드리겠습니다.

Java

rwt-seoul-demo-login-java

SyncCredentials를 만들어서 전달하는데, ID/Password를 전달할 수 있습니다. 비동기 로그인은 SyncUser.loginAsync(...)를 사용합니다. AUTH_URL에는 인증 서버 주소를 적고, onSuccess에서 성공을, OnError에서 실패를 처리합니다.

인증이 성공하면 Realm을 설정하는데, 로컬에서 사용할 때는 사용하지 않을 수도 있지만, 동기화를 사용할 경우 SyncConfiguration을 사용합니다. REALM-URL에는 서버에 있는 어떤 데이터베이스를 사용할지 경로를 지정합니다.

그 다음으로는 Realm 인스턴스를 만드는데, 하나의 스레드에서는 한 개의 인스턴스를 사용해야 합니다. 별도의 스레드마다 다른 인스턴스를 사용할 수 있는데, 이런 방식으로 다른 스레드에서 읽을 때도 락 없이 사용할 수 있고, 쓰기에만 트랜잭션이 발생합니다. 심지어 한 스레드에서 쓰기 트랜잭션이 일어나고 있어도 다른 스레드에서는 읽을 수 있습니다.

데이터베이스를 쓴 다음 onDestroy에서 realm.close()로 인스턴스 닫는 것을 잊지 마세요.

Swift

rwt-seoul-demo-login-swift

Swift에서는 Credentials 객체를 만들지 않고 메서드에 직접 전달했습니다. Java에서처럼 로그인하는데, 성공/실패에 별도의 코드 블럭을 호출하지 않고 usererror 매개변수로 전달됩니다. Java와 마찬가지로 Realm 설정을 하고 인스턴스를 얻어 왔습니다.

다양한 인증

사용자/암호 말고도 구글과 페이스북을 통해서도 로그인을 하도록 Credential을 만들 수 있으며, Swift에서도 가능합니다.

쓰기

rwt-seoul-demo-write-transaction

이제 직접 데이터베이스에 접근해서 읽고 쓰면 로컬뿐만 아니라 원격에서 자동으로 반영됩니다. 쓰기는 트랜잭션을 생성해야 하는데, 오른쪽 Swift 예제처럼 블럭으로 처리하거나 왼쪽의 Java 예제처럼 beginTransaction()commitTransaction() 사이에서 처리하는 방법, 두 가지를 제공합니다.

먼저 모델을 사용해서 인스턴스를 생성합니다. 다음으로 쓰기 트랜잭션 안에서 일반 필드처럼 Scan 인스턴스의 상태를 수정합니다. 그리고 변경 관리를 위한 이벤트 리스너를 등록합니다. 서버나 앱의 다른 부분에서 데이터가 변경됐을 때 리스너를 호출할 수 있습니다.

읽기

rwt-seoul-demo-get-object

위 코드가 Swift, 아래 코드가 Java로 특정 id의 객체를 가져오는 코드를 볼 수 있습니다.

rwt-seoul-demo-filtering

객체를 여러 개 리스트 형태로 가져오는 것도 필터링과 정렬을 통해 가능합니다.

클라이언트 변경 알림

Realm에서 데이터를 읽고 쓰는 것은 일반 필드를 사용하는 것처럼 쉽습니다. 변경 리스너도 마찬가지입니다.

Java

rwt-seoul-demo-noti

onChange에서 변경된 객체가 인자로 전달되는 예제입니다. 여기서 전달된 객체를 가지고 UI를 쉽게 갱신할 수 있습니다.

Swift

rwt-seoul-demo-kvo

iOS에서 제공하는 표준 Key-Value Observation을 사용해서 변경된 내용을 처리할 수 있습니다.

서버 변경 알림

rwt-seoul-demo-change-event

Node.js를 사용해서 오브젝트 서버에도 변경 리스너를 등록할 수 있습니다. 서버 이벤트 핸들러를 만들 때는 예제의 var admin_user = Realm.Sync.User.adminUser(REALM_ADMIN_TOKEN)처럼 토큰을 사용해서 관리자 계정을 얻고, 만든 admin_user와 NOTIFIER_PATH 경로, 상단의 콜백으로 리스너를 등록합니다.

콜백에서는 변경될 때마다 실행될 코드를 넣습니다. 콜백은 change_event 하나만을 받지만 그 안에 포함된 다양한 속성을 이용해서 Realm 인스턴스, 변경된 대상 객체, 변경된 인덱스에 대한 상세 정보를 얻을 수 있습니다. 특히 changes.insertions로 정밀한 알림을 제공하는데, 추가, 삭제, 변경 집합을 인덱스로 세밀하게 전달해서 정확히 어떤 데이터가 변화했는지 알 수 있습니다.

데모

데모 영상을 통해 Realm 모바일 데이터베이스와 Realm 모바일 플랫폼을 사용해서 앱에 어떤 기능을 추가할 수 있는지 확인해 보세요!


모바일 개발자가 더 나은 앱을 더 빠르게 만들도록 돕는 Realm 모바일 데이터베이스와 Realm 모바일 플랫폼을 통해 핵심 로직에 집중하고 개발 효율을 높여 보세요! 공식 문서에서 단 몇 분 만에 시작할 수 있습니다. 또한 Realm 홈페이지에서는 모바일 개발자를 위한 다양한 최신 기술 뉴스와 튜토리얼을 제공하고 있으니 즐겨찾기하고 자주 들러 주세요!

다음: Realm Mobile Platform으로 실시간 협업 기능과 확장이 가능한 리액티브 앱을 만들어 보세요.

General link arrow white

컨텐츠에 대하여

이 컨텐츠는 저자의 허가 하에 이곳에서 공유합니다.

Leonardo YongUk Kim

Leonardo YongUk Kim is a software developer with extensive experience in mobile and embedded projects, including: several WIPI modules (Korean mobile platform based on Nucleus RTOS), iOS projects, a scene graph engine for Android, an Android tablet, a client utility for black boxes, and some mini games using Cocos2d-x.

4 design patterns for a RESTless mobile integration »

close