もっと使おうPhoneGap/Cordova 2.0.0

第8回 File APIを使ったiOS/Androidアプリケーション作成[その5]

この記事を読むのに必要な時間:およそ 11 分

File API紹介の最終回となる今回は,FileTransferオブジェクトを使って,ファイルのダウンロード・アップロードを行う手順を紹介していきます。性質上,Webサーバとファイルを受信するプログラムが別途必要になりますのであらかじめご準備ください。

FileTransferオブジェクトを使ったファイルダウンロード・アップロード

FileTransferオブジェクトを使用して,ファイルをダウンロード・アップロードするアプリケーションを作成してみましょう。

新たに登場するオブジェクトとメソッドは次のとおりです。

  • FileTransferオブジェクト
  • FileTransferErrorオブジェクト
  • FileUploadOptionsオブジェクト
  • FileUploadResultオブジェクト
  • downloadメソッド
  • uploadメソッド

FileTransfer/FileTransferError/FileUploadOptions/ FileUploadResultオブジェクトとは

選択したファイルを外部サーバに送信するサンプルプログラムを紹介する前に,ファイル転送に関係する4種類のオブジェクトについて確認しておきましょう。

公式ドキュメントに一部誤っていると思われる表記があるため,ソースコードから動作を書き起こしています。そのため,Apache Cordova Documentationと差異がある箇所があります。あらかじめご了承ください。

FileTransferオブジェクトは,サーバからファイルをダウンロード,またはファイルをサーバにアップロードする際に使用するオブジェクトです。

FileTransferオブジェクトにプロパティはありません。用意されているメソッドは次のとおりです(使い方のfileTransferは,FileTransferオブジェクトを指します)⁠

メソッド名内容
使い方
download指定したサーバからファイルをダウンロードします。
  • ダウンロードしたいファイルのURLをsourceに指定します。encodeURI()メソッドでエンコードされている必要があります。
  • ファイルの保存先をtargetにフルパス表記で指定します。
  • targetに存在しないディレクトリを指定した場合は,ダウンロード成功時に自動的に作成されます。
  • ダウンロードしたいファイルのホストを,あらかじめホワイトリストに定義しておく必要があります。
  • 成功時,successCallbackに,取得したファイルの情報をFileEntryオブジェクトして渡します。
  • 失敗時,errorCallbackに,FileTransferErrorオブジェクトを渡します。
fileTransfer.download(source, target, successCallback, errorCallback);
upload指定したサーバにファイルをアップロードします。
  • アップロードしたいファイルのフルパスをfilePathに指定します。
  • ファイルの送信先URLをserverに指定します。encodeURI()メソッドでエンコードされている必要があります。
  • ファイル名やMIME,パラメータなどの情報をFileUploadOptionsオブジェクトとして定義し,optionsに指定します。
  • すべてのホスト(自己署名の証明書を使用しているホストなど)を信頼する場合は,trustAllHostsにtrueを指定します。デフォルト値はfalseです(執筆時点で,この指定は無視される模様です)
  • 成功時,successCallbackに,FileUploadResultオブジェクトして渡します。
  • 失敗時,errorCallbackに,FileTransferErrorオブジェクトを渡します。
fileTransfer.upload(filePath, server, successCallback, errorCallback, options, trustAllHosts);

FileTransferErrorオブジェクトは,FileTransferオブジェクトでダウンロードまたはアップロードの際にエラーが発生した際に渡されるエラーオブジェクトです。メソッドはありません。

FileTransferErrorオブジェクトのプロパティは次のとおりです。

code
対応するエラーコードを返します
source
ソースのURIを返します
target
ターゲットのURIを返します
http_status
HTTPステータスコードを返します(レスポンスコードがHTTP接続から返されたときのみ有効です)

対応する定数とエラーコードは次のとおりです。

FileTransferError.FILE_NOT_FOUND_ERR
ダウンロード時の第2引数に指定したパスがファイルURLでない場合や,アップロード時の第1引数に指定したファイルが見つからない場合に返ります
FileTransferError.INVALID_URL_ERR
ダウンロード時・アップロード時ともに第2引数に不正なファイルURLを指定した場合に返ります
FileTransferError.CONNECTION_ERR
ネットワーク接続がない場合や,処理完了時のレスポンスコードが200~300の範囲でなかった場合に返ります

リスト1 FileTransferErrorオブジェクトの定数とエラーコード

// cordova-2.0.0.js 2578-2580
FileTransferError.FILE_NOT_FOUND_ERR = 1;
FileTransferError.INVALID_URL_ERR = 2;
FileTransferError.CONNECTION_ERR = 3;

// CDVFileTransfer.h 24-28
enum CDVFileTransferError {
	FILE_NOT_FOUND_ERR = 1,
    INVALID_URL_ERR = 2,
    CONNECTION_ERR = 3
};

// CDVFileTransfer.m 80-103
// ファイルアップロード実装の一部
if (!url) {
    errorCode = INVALID_URL_ERR;
    NSLog(@"File Transfer Error: Invalid server URL %@", server);
} else if(![file isFileURL]) {
    errorCode = FILE_NOT_FOUND_ERR;
    NSLog(@"File Transfer Error: Invalid file path or URL %@", filePath);
} else {
    // check that file is valid
    NSFileManager* fileMgr = [[NSFileManager alloc] init];
    BOOL bIsDirectory = NO;
    BOOL bExists = [fileMgr fileExistsAtPath:[file path] isDirectory:&bIsDirectory];
    if (!bExists || bIsDirectory) {
        errorCode = FILE_NOT_FOUND_ERR;
    } else {
        // file exists, make sure we can get the data
        fileData = [NSData dataWithContentsOfURL:file];
        
        if(!fileData) {
            errorCode =  FILE_NOT_FOUND_ERR;
            NSLog(@"File Transfer Error: Could not read file data %@", filePath);
        }
    }
    [fileMgr release];
}

// CDVFileTransfer.m 224-230
// ファイルダウンロード実装の一部
if (!url) {
    errorCode = INVALID_URL_ERR;
    NSLog(@"File Transfer Error: Invalid server URL %@", sourceUrl);
} else if(![file isFileURL]) {
    errorCode = FILE_NOT_FOUND_ERR;
    NSLog(@"File Transfer Error: Invalid file path or URL %@", filePath);
}

FileTransferオブジェクトのcodeプロパティと,http_statusプロパティは連動していません。たとえばサーバ側で404エラーが返るURLをdownloadメソッドで指定した場合,codeプロパティはFileTransferError.FILE_NOT_FOUND_ERRではなくFileTransferError.CONNECTION_ERRを,http_statusは404の値を取ります。若干分かりづらいので,ご自身の手で後述のサンプルをカスタマイズし,エラーの値を確認してみてください。

FileUploadOptionsは,FileTransferオブジェクトのuploadメソッド時に指定するオプションをまとめたオブジェクトです。メソッドはありません。

FileUploadOptionsのプロパティは次のとおりです。

fileKey
Content-Dispositionヘッダのname属性に指定する名前を指定します。デフォルト値はnullです
fileName
Content-Dispositionヘッダのfilename属性に指定する名前を指定します。デフォルト値はnullです
mimeType
Content-Typeヘッダに指定するMIMEタイプを指定します。デフォルト値はnullです。指定しなかった場合,Content-Typeヘッダは送信されません
params
HTTPリクエストに含めたいデータをkey/value形式で指定します
chunkedMode
チャンク・ストリーミングでファイルを送信したい場合はtrueを指定します(執筆時点で,この指定は無視される模様です)

FileUploadOptionsの初期値を確認(iOS)

FileUploadOptionsの初期値を確認(iOS)

FileUploadOptionsの初期値を確認(Android)

FileUploadOptionsの初期値を確認(Android)

FileUploadResultオブジェクトは,FileTransferオブジェクトのuploadメソッドでファイルアップロードに成功した場合に渡されるオブジェクトです。メソッドはありません。

FileUploadResultオブジェクトのプロパティは次のとおりです。

bytesSent
送信されたバイト数を示します
responseCode
サーバから返されたHTTPレスポンスコードを示します
response
サーバから返されたHTTPレスポンスを示します

iOSの場合,responseにはstringByAddingPercentEscapesUsingEncodingでエンコードされた文字列が格納されます。JSONをやりとりするアプリケーションを作成する場合,そのままではJSON.parseが動作しないので注意しましょう。Androidの場合,エンコードは行われません。

また,現在の最新バージョンであるPhoneGap 2.1.0では,ファイル転送に関係するオブジェクトにおいてFileWriterオブジェクトやFileReaderオブジェクトにあるような「ファイルのダウン/アップロード中」「ファイルの送信を中止させる」に相当するイベント・メソッドが用意されていません。そのため,ダウンロード・アップロードの進捗率を画面に表示するといったことは難しいでしょう。

ダウンロード・アップロードの進捗イベントを捕捉するprogressイベントや送信・受信を中止するabortメソッドについては,PhoneGap 2.2.0にてサポートされる予定です。これらの動向について詳しく確認したい方は,Apache JIRAの[#CB-622]FileTransfer interface should provide progress monitoringをチェックしておきましょう。

ファイル転送に関係するオブジェクトをまとめると,次のようになります。

オブジェクト名内容
FileTransferファイルのダウンロード・アップロードを行う。
  • アップロード成功時に,FileUploadResultオブジェクトを返す
  • ダウンロード成功時に,ダウンロードしたファイルのFileEntryオブジェクトを返す
  • ダウンロード/アップロード失敗時にFileTransferErrorオブジェクトを返す
FileTransferErrorFileTransferオブジェクトのdownload/uploadメソッド使用時,失敗した際に返るエラーオブジェクト
FileUploadOptionsFileTransferオブジェクトのuploadメソッド使用時,アップロード時のHTTPヘッダに付加したい情報を定義するためのオブジェクト
FileUploadResultFileTransferオブジェクトのuploadメソッド使用時,成功した際の送信バイト数/サーバから返されたレスポンスをまとめたオブジェクト

著者プロフィール

富田宏昭(とみだひろあき)

株式会社キクミミでFileMaker/SQLiteを使ったWebアプリ開発に従事しながら,オープンソースソフトウェアのハウツー記事執筆を行う。趣味は横乗り系スポーツ,美術館めぐり,高速ジャンクション鑑賞。

コメント

コメントの記入