React Native Router Fluxでタブの履歴を残す方法

InstagramのようにAndoridのバックボタンで前のタブに戻るようにするためにどのタブが前のタブか知る必要があります。React Native Router Flux(with Redux)を使っていて、これを実現するために下記のようなReducerを作りました。

やってることは、FOCUSしたときにtabHistoryとして、Arrayに追加してるだけです。無限に履歴を残す必要はないので10個で制限してますが、もしかしたら2つでいいかもしれません(最初の要素は現在のタブになるので二つ以上は必要)

で、これを下記みたいな感じでBackAndroidで使用すれば良いでしょう。

(モバイル)アプリとサーバ間の同期方法 – Evernote way

アプリとサーバ同期の方法は、自力で生み出すのは試行錯誤するのは目に見えているので既存の方法を調べてみました。あまり確立した方法がない中、Evernoteが同期のスペック(EDAM synchronization)を公開していることを知り、そのスペックを読んでみました。

簡単に言うと、サーバ側のデータを中心として、複数クライアントからでも同期できるという方法です。クライアント側でがんばる方法とも言えます。

同期を構成する要素

  • Full SyncとIncremental Syncの2パターンがある。
  • 同期するオブジェクトはシークエンス番号(Update Squence Number: USN)をもつ。Create/Update/Deleteの度にインクリメントしてアサインする。
  • 同期するオブジェクトはGUIDという一意のIDをもつ。
  • サーバ側の変数は、
    • updateCount: 最大USN
    • fullSyncBefore: 削除済みリストをクライアントキャッシュから削除したいときに使うか。または、問題があった場合に、Force FullSyncさせるためのもの。時間型変数(DateTime)。
  • クライアント側の変数は、
    • lastUpdateCount: 最後に同期したときのサーバから得たupdateCount
    • lastSyncTime: 最後に同期した時間型変数(DateTime)
  • 各同期オブジェクトにdirtyフラグをもつ。変更があった場合に、同期対象にするためのフラグ。

では、具体例(TodoList)を用いて説明します。ユーザ毎にUpdateCountを持つので上記の変数は下記のように変化します。

  1. アカウント作成時に初期値user.updateCount = 0となる
  2. TodoListのタスクが作られると、task1.usn=1, user.updateCount=1
  3. もう一つタスクが作られると、task2.usn=2, user.UpdateCount=2
  4. task1をアップデートして、task1.usn=3, user.updateCount=3
  5. task2を削除してhard deleteでuser.updateCount=4、soft Deleteはtask1.usn=4, user.updateCount=4
  6. Taskの上位概念のProjectを作成project1.usn=5, user.updateCount=5

同期するオブジェクトに番号がふられるので、クライアント側でどの時点のupdateCount(=lastUpdateCount)を記録しておけば、インクリメントで該当オブジェクトを取得できる。

クライアントとサーバ間の同期方法

それでは、同期方法をみていきます。クライアント側からの見方になります。

  1. 1度も同期した事がなければ、Full Sync。
  2. fullSyncBefore > lastSyncTime, の時、 Full Sync。(例えば、なんらかの理由でForceアップデートしたい時にfullSyncBeforeをその変更時間にすれば、強制的にFull Syncさせることができる)
  3. updateCount = lastUpdateCountの時、サーバ側に変更がないので、クライアント側の変更を更新する(=Send Changes)
  4. それ以外のときは、Incremental Syncする。

Full Sync

Full Syncとは全データに対して走査し、同期すること。クライアントのデータを全消しして、全部取得することではないので注意。スペック内のExampleが名前が一意である必要のあるTagを使って説明しているので少しわかりづらい。一意である必要がある場合は、Renameを考慮する必要がある。下記は、Todoのタスクのように一意性を問わない場合の例。

  1. 更新すべきデータを取得する。
  2. IDのリストを作って、クライアントDBと比較し、クライアント側にIDがない場合は、クライアントDBに追加する
  3. IDがクライアントにあって、サーバ側にない場合、
    1. クライアントのオブジェクトのdirtyフラグがない場合、そのデータをクライアントから消す
    2. dirtyフラグがある場合は、あとでアップロードする。
  4. IDがクライアントとサーバ両方にある場合は、オブジェクトのUSNを比較して、
    1. 同じなら、データは同期している
    2. 同じで、クライアント側にdirtyフラグがある場合は、後でアップロードする
    3. サーバ側のUSNが大きくて、dirtyフラグがない場合、サーバ側のデータに置き換える
    4. サーバ側のUSNが大きくて、dirtyフラグがある場合、コンフリクト発生しているのでマージするか、ユーザにコンフリクト状態をレポートする
  5. サーバのデータマージが終わったら、サーバのupdateCountをクライアントのlastUpadteCountにして、現在の時間をlastSyncTimeにする
  6. 変更を更新する(=send Changes)

Incremental Sync

Full Syncと似ているが差分だけとってくるので、各オブジェクトのUSNの比較を行わなくて良い。削除済みリストとクライアントのリストを比較して必要なら削除する必要がある。

  1. クライアントのlastUpadteCount以降のデータを取得する
  2. IDのリストを作って、クライアントDBと比較し、クライアント側にIDがない場合は、クライアントDBに追加する
  3. IDがクライアントとサーバ両方にある場合は、
    1. dirtyフラグがない場合、サーバ側のデータに置き換える
    2. dirtyフラグがある場合、コンフリクト発生しているのでマージするか、ユーザにコンフリクト状態をレポートする
  4. サーバからのデータがから削除済みのリストを作成し、対象データがある場合はクライアント側から削除
  5. サーバ側のデータマージが終わったら、サーバのupdateCountをクライアントのlastUpadteCountにして、現在の時間をlastSyncTimeにする
  6. 変更を更新する(=send Changes)

Send Changes

  1. ローカルにあるdirtyフラグのあるオブジェクトに対して、
    1. 新しいオブジェクト(USNが設定されてない)場合は、サーバ側にCreateをリクエストする。
    2. オブジェクトが変更された(USNが設定されている)場合は、サーバ側にUpdateをリクエストする。
  2. レスポンスとして、
    • USN = lastUpdateCount + 1のときは同期状態。クライアントのlastUpdateCountを更新する
    • USN > lastUpdateCount + 1のときは、同期していないので、後でIncremental Syncをする。

フレッツ光でプロバイダを乗り換えたら安くなって下りの速度が6倍になった話

背景

家でFacebookを眺めてると動画フィードでローディングのアイコンが頻繁に出て、ネットが遅いって感じてきました。特に夜に遅くなってる気がしてました。

調査

ネットでインターネットの速度を測ってみると3Mbit/sでした。光なのに4G回線より遅い。。すぐさまネットで調べてみると、ひかりではADSLの基地局の家からの距離問題は特にないけど、プロバイダの混雑具合で速度が変わるケースが出てくるらしい。

事実確認

契約していたプロバイダはbiglobeさん。3年目で初期キャンペーンの旨味はもうなく、切り替えに特に違約金も発生しない。(プロバイダは運らしく。biglobeが悪いわけではなく、私の地区では厳しいかったということです)。

Now is the time to switch my provider!

行動1

乗り換えでぐぐってみるとkakaku.comのアドがトップに。何も考えず、クリック。一番安くてBiglobeじゃないYahooBBに申し込みました。指定した時間で電話がかかってきて、説明を受けました。その内容が、

  • キャンペーンのキャッシュバックは数ヶ月後に発生
  • キャンペーン適用には2年縛り契約
  • 2年縛り契約には更新月があり、それを逃すと自動更新。
  • 自動更新月以外は違約金発生
  • なんたらっていうオプションに自動参加(あとから取れると言う説明)
  • 必要あるなしに関わらず、ルーターみたいのが送られてくる(それも初月無料だけど解約しないと課金発生)

ここで、電話をインタラプトして、「すいません、かなり面倒なので申し込むの止めます」って言いました。。
もうキャンペーンのキャッシュバック以上に労力ないしは気苦労がかかりそうです。。

電話を切って、再考。そもそもこういったキャンペーン打ってるとこに申し込みが集中して、プロバイダの回線がパンクしてるのではないかと。マイナーだけどいいプロバイダを探してみようと思い立ちました。

行動2

そういえば、実家のプロバイダは1998年ごろからずっとAsahiネット。調べてみると東証一部上場の企業なんですね。上場がすごいなーなんて思いつつ、HPで乗り換えキャンペーンを発見。早速申し込みました。(biglobeは解約)

設定

3日後にIDとパスワードが郵送で送られてきて、192.168.1.1を叩いて変更。すぐにつながりました。

結果

Terminalを開いてspeedtest-cliをダウンロード。

日本検索。

で、テスト。

30Mbit/s !!! やっほい!

でプロバイダをbiglobeに戻してspeedtest.

4.69Mbit/s。 全然違う。

乗り換えてよかった! 月額も900円ちょいから700円になってうれしい。

Scroll to top