38
40

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ブラウザアプリで、大量のデータをオフラインで持ちたい

Posted at

どうも、社内SEに無事転向しました。
のんびりした開発というか、思い切りのんびりした感じで、逆に自分の中でメリハリつけないと大変そうだなぁと思いながら、いろんな要望を聞いています。

で、今回のこれ。

ブラウザアプリで大量のデータをオフラインで持ちたい

※ブラウザはIE、あとiPadに対応させてほしい

chrome縛り可であれば、serviceworkerでなんとでもなるのですが、この条件だと、使える技術が限られます。

  • オフラインはappCacheで
  • そのオフラインデータとやらは、IndexedDBで

ぐらいが妥当な線だと見て、生まれて初めて取得する盆休み中にいじってみました。

先に結論

 十分使える。むしろ自分用ツールをこれに載せたレベル。

実装

appCacheの書き方

まず、HTMLタグに、appcacheを使用することを宣言します。

index.html
<html manifest="manifest.appcache">

肝心のappcacheの定義は以下のような感じ。

manifest.appcache

CACHE MANIFEST
# Version: 1

CACHE:
./count.php
./fonts/MaterialIcons-Regular.eot
./fonts/MaterialIcons-Regular.ijmap
./fonts/MaterialIcons-Regular.svg
./fonts/MaterialIcons-Regular.ttf
./fonts/MaterialIcons-Regular.woff
./fonts/MaterialIcons-Regular.woff2
./styles/materialicons.css
./js/jquery-2.2.4.min.js
./js/riot+compiler.min.js
./js/kl.js
./js/kl.location.js
./js/kl.dom.js
./js/kl.cache.js
./js/kl.syncidb.js
.       :必要なファイルを列挙
./riot/raw.tag
./styles/main.css
./manifest.json

NETWORK:
*

この中でも、

NETWORK:
*

は絶対に忘れないようにしましょう。
どうすることもできなくなります。

次に、HTMLで、BODYが始まった瞬間に、以下のscriptを入れます。
このscriptタグは、このscriptタグだけで終わらせます。

index.html
<body>
    <script>
        var cache = window.applicationCache;
        cache.addEventListener("updateready", function() {
            alert('アプリケーションの新しいバージョンが利用可能なため、更新します')
            cache.swapCache();
            location.reload();

        });
        cache.addEventListener('noupdate', function() {
            //alert('アプリケーションは最新です');
            //cache.swapCache();
            //location.reload();
        });
        if (navigator.onLine) {
            try {
                cache.update();
            } catch (e) {
                console.dir(e);
            }
        }
    </script>

これがないと、iOSで詰みます。
更新できなくなります。怖い。

以上で、オフラインアプリがざっくり作れました。
アイコンとか色とか設定したい場合は、manifest.jsonとか同時に使えます。
サービスワーカーは同時に使えません。

IndexedDBを使う。

 まず、どうしてIndexedDBか。

  • 想定しているファイル量がどう聞いても5M超えそう。
  • 限界突破できるのは、IndexedDBだけ。
  • IE10以降、Mobile Safari8以降縛りだけど、許してね。

 って感じで。

  • どうせ、こういうDBでデータ持つんなら、配信の仕組みいるよな。(a)
  • 配信の仕組みで更新しきれなかったものがもし存在すれば、サーバに送る、ってすれば、もしかしてサーバの情報を、更新しちゃえる?(b)
  • サーバの情報を、別の端末で受信したときに、(b)で(a)が更新されて、あたかも同期できちゃう?
  • あ、じゃあ完全にオフラインアプリになるじゃん。データも。

 みたいな発想から双方向にしました。

 これはコードが長くなったので、githubに置きました。
 https://github.com/zrelyydereva/syncedIndexedDB

 こんなやりとりしてます。

サーバ - クライアント
list sync
list →ID,リビジョン一覧→ indexedDBで比較
put ←自分のほうが新しいもの← --
put  :  --
put ←自分のほうが新しいもの← ---
get ←自分のほうが古いもののID一覧← 比較し終えて残ったもの
get →データ(配列)→ indexDBに保存

 正直、appCacheだけでは眉唾だった、過去の**HTML5でのオフラインアプリ!**みたいなキャッチで作られたHTML5アプリを見てきたので不安はありましたが、スマホなんかがどんどん外堀を埋めてきてくれた結果、割とすごいのが作れる時代になりましたね。
 

38
40
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
38
40

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?