LoginSignup
4
4

More than 5 years have passed since last update.

Realm Object Serverを使用してRealmのデータを端末間で共有する

Posted at

データのセーブに良く使っているRealm
とっても重宝しています
それを、そのまま端末間で共有できたらと思ったのですが・・・

日本ではなかなか導入の事例が見つからず、RealmObjectServerの導入でハマったので自分の忘備録的なものとしても

やってみたかったこと

Realm Object Serverを使って、Realmに保存したデータを端末間で共有

環境

  • サーバー -> さくらのVPS(4G)、KUSANAGIをインストールしている関係で、OSはCentOS7

導入

一応、公式サイトにやり方はあったのだけど・・・

curl -s https://packagecloud.io/install/repositories/realm/realm/script.rpm.sh | sudo bash

sudo yum -y install realm-object-server-developer

sudo systemctl enable realm-object-server
sudo systemctl start realm-object-server

あとはXcodeで実装するのみ

let credentials = SyncCredentials.usernamePassword(username: "[ユーザー名]", password: "[パスワード]", register: false)
        SyncUser.logIn(with: credentials, server: realmAuthURL) { user, error in
            DispatchQueue.main.async {
                if let user = user {
                    Realm.Configuration.defaultConfiguration = Realm.Configuration(
                        syncConfiguration: SyncConfiguration(user: user,realmURL: realmURL),
                        objectTypes: [PCData.self]

                    )
                    print("データベースへの接続を確立しました")
                    self.realm = try! Realm(configuration: Realm.Configuration.defaultConfiguration)
                    //print(self.realm.objects(PCData.self))

                    if self.realm.objects(PCData.self).count == 0{ //DBサーバーにデータが存在しない場合はダミーオブジェクトを作成(通常データに影響を及ぼさないように)
                        print("データの書き込みを行います")
                        let data = PCData()
                        data.isOut = false
                        data.pcCode = "***METADATA***"
                        data.rentPCto = ""
                        data.IDinCourse = 999999999999
                        data.belonging = "Master"
                        try! self.realm.write {
                            self.realm.add(data)
                        }
                    }else{
                        print(self.realm.objects(PCData.self))
                    }
                    isDone = false
                }
                if error != nil{ //何らかの理由で接続できなかった場合はエラーとしてアプリを終了させる
                    print(error)
                    self.alert.dismiss(animated: false, completion: nil)
                    let errorAlert = UIAlertController(title: "データベース接続エラー", message: "アプリを終了して再度試してみてください\n\(error!)", preferredStyle: .alert)
                    let action = UIAlertAction(title: "OK", style: .default, handler: {action in
                        exit(0)
                    })
                    errorAlert.addAction(action)
                    self.present(errorAlert, animated: true, completion: nil)
                }


            }
        }

一度、HTTPの9080番でログイン試行して成功すれば、ユーザーが返ってくるぽいので、それとRealmのクラスを含んだRealmConfigurationを作って、それを使ってtry! Realm(configuration: [作成したConiguration])をする形になるみたい
なお、Realm Object Serverに直接データを書き込むというよりは、ローカルで持っているRealm Databaseをサーバー上のRealm Databaseと同期させる形になるみたい

だがしかし

2017-12-17 22:53:30.880875+0900 PCManage[7021:1784833] Sync: Connection[1]: Connection closed due to error
2017-12-17 22:53:31.673562+0900 PCManage[7021:1784833] Sync: Connection[1]: Connected to endpoint '[Server's IP]:9080' (from '[My IP]:57032')
2017-12-17 22:53:31.684189+0900 PCManage[7021:1784833] Sync: Connection[1]: Writing failed: End of input 

んんん???

↓サーバー側ログ↓

proxy: attempting to upgrade client [My IP]:57032 => headers: {"authorization":"Realm-Access-Token version=1 token=\"eyJhY2Nlc3MiOlsiZG93bmxvYWQiLCJ1cGxvYWQiLCJtYW5hZ2UiXSwiYXBwX2lkIjoiY29tLmFrYmFydC5hcHAuUVJ0ZXN0IiwiZXhwaXJlcyI6MTUxMzUxOTQwOCwiaWQiOiIwMzdmY2I5Yzc0MGE0ZjdhOGVhOTZkZmFhYjUxNmM2ZiIsImlkZW50aXR5IjoiZmI0NmQ1ZjNjYjRiNmE5NWExYWYyNDkzZGIxNjE5YzYiLCJwYXRoIjoiL2ZiNDZkNWYzY2I0YjZhOTVhMWFmMjQ5M2RiMTYxOWM2L3JlYWxtIn0=:Tn4Qa4vzvZ87lnW2htmt6rPCaLL5ASDkpqbcXT2eKskQ3NHJ3ePyMxvJjjyAq5rh8pb2syCM1Dh8LrVk9RilQ```sHwHRU9HyDOky/psePE4UfXidEJGYoML19R9mo+yjHPG7DeP0ykYltTjONJh+OpQkaelHYIMlKAwFP+hxeNWlVAIpjohkqmyr/de3++8IxcVV6/6wJUESdNpDq2e5GGKfxpSwbfhBagNi0m0aSNuwzoqJ5CFqbyoxsyyCZWx6XJ7ZueTmRvGx22SJcthRzxrQRrWMbMtF8yEHY/AARzycO/A/Zi5spXqAzQD6QIrkl5gGI/FwvnLvhvtPEFychXIg==\"","connection":"Upgrade","host":"[]","sec-websocket-key":"K0Tw7zhY3ov9h+VEqHtaPQ==","sec-websocket-protocol":"io.realm.sync.22","sec-websocket-version":"13","upgrade":"websocket"}.}
sync: HTTP Connection[959]: Connection from 127.0.0.1:35414
sync: HTTP Connection[959]: Connection initiates HTTP receipt
sync: HTTP Connection[959]: HTTP request received, url = /realm-sync/%2Ffb46d5f3cb4b6a95a1af2493db1619c6%2Frealm
sync: HTTP Connection[959]: 404 Not Found
sync: HTTP Connection[959]: Connection is closed after HTTP response.

Shingeki77-Anni-Kuso.jpg 404・・・!

教えて!Stack Overflow!

スクリーンショット 2017-12-31 21.30.57.png

ただのバージョン違いでした・・・

参考ページ(公式)
npm install -g realm-object-serverをした後にros startという感じ
そのときにいるディレクトリに、Realm関係のファイルが作成されるので、インストールする前に、管理しやすいディレクトリに移動しておくといいかも
そして、そのままログが吐き出されて、サーバーからログアウトできないので、Screenなどを使って仮想端末を作って、その上で動かしておくと良い(バックグラウンドで使える方法あるんだろうなぁ)
RealmObjectServerを起動した後は、Swiftのコードは修正せずログイン試行でデータベースにアクセスできた

サーバー管理

ROS1.xは、Webでの管理が出来たが、2.x以降は「Realm Studio」での管理となる -> ダウンロードサイト
スクリーンショット 2017-12-31 21.50.01.png

デフォルトのUsernameは「realm-admin」、Passwordは空(パスワード空文字はセキュリティ的にマズいので、変更するか、デフォルトユーザーの削除を推奨)

まとめ

  • バージョンに注意(ドキュメントが並行して残っているので、分かりづらい)
  • Realmとしての使い方は同じ(try! Realm()でConfigurationを引数にする必要あり)
  • 速度快適

日本での採用事例は少ないようですが、かなり便利なので普及すればいいですね

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4