SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Apache Cordovaで本格スマホアプリに挑戦しよう

Apache Cordova+AngularJSでローカルファイルにアクセスするプラグインを使おう

Apache Cordovaで本格スマホアプリに挑戦しよう 第5回

ファイルの一覧を取得する

 では、実際にAPIを使っていきます。まずは、指定したディレクトリからファイルもしくはディレクトリの一覧を取得します。

 リスト4はwwwディレクトリ以下にあるファイルもしくはディレクトリ一覧を取得する場合のサンプルコードです。

リスト4 ファイルの一覧を取得(app/www/js/controllers/FileReadController.jsの抜粋)
// (1) URLを使ってパスを指定
window.resolveLocalFileSystemURL(
    cordova.file.applicationDirectory + "www",

    // (2) Entry(DirectoryEntry)の取得に成功した場合
    function(entry){
        // (3) ファイル一覧を取得する為の
        var reader = entry.createReader();
        reader.readEntries(function(entries){
            // $applyはAngularJSに変更を伝える為
            $scope.$apply(function(){
                //  (4) 指定したディレクトリ以下のファイル、もしくはディレクトリの一覧が取得できる
                $scope.files = entries;
            });
        },function(error){
            window.alert("読込失敗 :" + error.code);
        });
    },
    // (5) 失敗した場合
    function(error){
        var message = "unknown";
        switch(error.code){
            case FileError.NOT_FOUND_ERR:
                message = "ファイルが見つかりません";
                break;
            default:
                message = "その他エラー";
                break;
        }
        window.alert("読込失敗 :" + error.code + " - " + message);
    }
);

 (1)ではwindow.resolveLocalFileSystemURL()メソッドを使って指定のURLからファイル、もしくはディレクトリの情報を取得します。URLを指定する場合には、先ほど説明したcordova.fileオブジェクトのプロパティを使ってURLを作成します。

 今回は、アプリケーションデータ(applicationDirectory)配下のwwwディレクトリの情報を取得したいので、「cordova.file.applicationDirectory + "www"」でパスを取得しています。

 取得に成功すると、引数にEntryオブジェクトを引数としてsuccessCallbackが実行されます(2)。

 指定したパスはディレクトリなので、Entryオブジェクトの実体はDirectoryEntryになります。DirectoryEntryオブジェクトが取得できたら、(3)のように、そのオブジェクトのcreateReaderメソッドでDirectoryReaderオブジェクトを作成し、readEntriesメソッドを使って、指定のディレクトリ配下にあるFileEntryもしくはDirectoryEntryが格納された配列を取得します。

 (4)ではAngularJSでHTMLテンプレート側で使えるように変数を設定しています。scope.$applyというメソッド内部で値を設定しているのは、AngularJSでHTML表示側に設定した値を反映させるためです。AngularJSを利用していない場合には、あまり気にする必要はありません。

 (5)はエラーの場合の処理です。エラー原因はcodeプロパティの値で判断をします。File System APIではエラーがあったときには、codeプロパティにエラー番号が設定されます。このエラー番号はFileErrorの定数として定義されていますので、その定数を利用し原因を特定します。

 エラー時には共通してこのエラー番号にて処理をしますので、実際に利用する際にはある程度、共通化した方が良いでしょう。

表7 エラーコード(code)について
定数 説明
NOT_FOUND_ERR ファイルもしくはディレクトリが見つからなかった場合
SECURITY_ERR セキュリティ上の理由などにより操作できなかった場合
ABORT_ERR 処理がなんらかの理由により中断された場合
NOT_READABLE_ERR 読込権限がない場合
NO_MODIFICATION_ALLOWED_ERR ファイルへの書込ができなかった場合
INVALID_MODIFICATION_ERR ファイルへの変更要求が受け付けられなかった場合
PATH_EXISTS_ERR すでに指定されたパスが存在している場合
ENCODING_ERR URLが不正な場合
TYPE_MISMATCH_ERR ファイルタイプが異なる場合
QUOTA_EXCEEDED_ERR 規定したストレージ領域が足りなくなった場合

 図3はサンプルを実行した時の結果です。

図3 www配下のファイル・ディレクトリを表示した結果
図3 www配下のファイル・ディレクトリを表示した結果

 またその時のHTMLテンプレートをリスト5に示します。ng-repeatというのはAngularJSで繰り返してDOM要素を表示する時に利用する属性指定です。

 この指定によって、$scope.filesの配列分だけ繰り返して表示することができます。

リスト5 一覧を表示するHTMLテンプレート(app/www/views/dir_read.html)
<div>
    <h2>ディレクトリの読込</h2>
    <div class="list-group">
        <!-- $scope.filesの配列分だけ以下を繰り返して表示する。 -->
        <div class="list-group-item" ng-repeat="item in files">
            <span class="glyphicon glyphicon-folder-close" aria-hidden="true" ng-show="item.isDirectory"></span>
            <span class="glyphicon glyphicon-file" aria-hidden="true" ng-show="item.isFile"></span>
            <span>{{item.name}}</span>
        </div>
    </div>
</div>

ファイルの内容を読む

 ファイルの情報が取得できるようになったので、続いて実際のファイルの内容を読んでみましょう。サンプルではwww配下のファイルを扱っていますが、その場合にはFileSystem APIを使わなくてもajaxなどを使って読むことはできます。よって、一般的には、別の領域(dataDirectory)に保存したファイルなどを読むことが多いかもしれません。その場合には、パスを変えれば問題ありません。

 ファイルの内容を読むためのコードは、リスト6のようになります。

リスト6 app/www/js/controllers/FileReadController.jsの抜粋
// (1) FileEntryを取得する
window.resolveLocalFileSystemURL(
    cordova.file.applicationDirectory + "www/json/labels.json",
    function(entry){

        // (2) Fileオブジェクトを取得する
        entry.file(function(file){
            // (3) FileReaderを使って内容を読む
            var reader = new FileReader();
            reader.onload = function(e){
                $scope.$apply(function(){
                    $scope.text = e.target.result;
                })
            };
            //  (4) テキストとしてデータを読みこむ
            reader.readAsText(file);
        });
    },
    function(error){
        window.alert("読込失敗 :" + error.code + " - " + message);
    }
);

 (1)では前回と同様に、window.resolveLocalFileSystemURLメソッドを使い、FileEntryオブジェクトを取得します。ここではサンプルの都合上、あらかじめwwwディレクトリに用意しておいたファイルを指定しています。

 (2)のように取得したFileEntryオブジェクトのfileメソッドを用いると、Fileオブジェクトが取得できます。このFileオブジェクトはFormのFileコントロールを使って取得したFileオブジェクトと同じものです。

 従って、(3)のようにFileReaderを使って内容を参照することができます。今回は、テキストデータですので、(4)のようにreadAsTextメソッドを使ってファイルのデータを読みこみます。

 例えば、読みこむデータが画像の場合には、readAsDataUrlなどを使います。

最後に

 今回は主に、ファイルを参照する操作について説明をしましたが、次回も引き続き、cordova-plugin-fileプラグインを使ってファイルの作成や書き込みの説明をします。

 ファイル操作ができるとWebアプリではできなかったことが、いろいろとできるようになります。特にハイブリッドアプリであれば、実際にはデータはサーバ側にあるケースが多いと思いますが、そのデータをダウンロードしておき、オフラインになっても利用できるようにするなどの使い方も可能です。

 また、Cordovaは既にHTML5として用意されているAPIがあればできるだけそのAPIと同じインターフェースを使って機能を実装しています。これらは既にそれらの知識があるエンジニアに取ってはわかりやすいのではないかと思います。

参考資料

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
Apache Cordovaで本格スマホアプリに挑戦しよう連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 小林 昌弘(コバヤシ マサヒロ)

WINGSプロジェクト について> 有限会社 WINGSプロジェクト が運営する、テクニカル執筆コミュニティ(代表 ...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/9454 2016/06/09 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー