LoginSignup
5
8

More than 5 years have passed since last update.

IonicでOSに依存しないファイル選択・読み込み

Last updated at Posted at 2018-02-20

今回やったこと

IonicベースのアプリでAndroid・iOS問わずファイル選択画面→読み込みを実装しました。
※文字コード変換付き

悪戦苦闘

Ionicベースのアプリ開発中にユーザーの任意のファイルをロードしたくなりました。でもAndroidでもiOSでもというのが意外と大変で...stackoverflowにもスレが結構立っています。

初手

Ionic native APIのFile APIを利用。でもこれ、読み込みファイルのパスわかる前提で「ドコドコにあるファイルを読み込むよー」的なところから使うもの...今回はパスもわからないんですごめんなさい...。

次手

一旦iOS対応は諦めてAndroidのみ対応なnative APIのFile Chooser APIを利用。ファイルを選ばせてくれるらしい。Windowsでいうエクスプローラー、MacOSでいうFinderかな?
この子はファイルまでのURI(content://path/to.fileという形式)を拾ってきてくれるので、あとはこれを参照するためにHTTP APIを利用。
ところがどっこい怒られた
エラー:HttpURLConnection Invalid HTTP method: content
AndroidのcontentメソッドはHTTP APIでは読めませんでした。

いろいろ考えましたが...。

「そういえばIonicってもともとHTMLなんだから、formで送信すれば良くないですか」と気づきました。
一度Ionicで使えるForm送信を試してみましたが、type="file"だとうまくいかなかったです。(リンク先のIonicのサイトにもtextとかselectしか例がない...うまくいったら教えてくださると助かります)

最終結果。

大筋は先程のform利用と同じですが、<form></form>は使わずに<input type="file">の変更検知でうまくいきました。

home.html
<label for="js-import-file__form">読み込むファイル</label>
<input id="js-import-file__form" (change)="fileUp($ev)" type="file">
<button id="js-import-file__submit" (click)="submitNewFile()" ion-button block disabled="disabled">読み込み</button>
home.ts

// クラスのフィールド
// のちのち書き込みとかで native API の File を使うときは
// 型名が競合してしまうので File ではなく any に。
private inputFile: any;

// file選択フォームの値(=選択ファイル)を変更すると発火
public fileUp(ev: Event) {
  this.inputFile = (<HTMLInputElement>ev.srcElement).files[0];
  // ファイル非選択時はButtonをdisabledにします
  if (this.inputFile.name) { // ファイルが選択されているとき
    document.getElementById('js-import-file__submit').removeAttribute('disabled');
  } else { // ファイルが選択されていないとき
    document.getElementById('js-import-file__submit').setAttribute('disabled', 'disabled');
  }
}

// submitボタンおすと発火
submitNewFile() {
  // ローディング画面でも表示...
  let loading = this.loadingCtrl.create({
    spinner: 'circles',
    content: '読み込み中...'
  });
  loading.present();
  // Ionic の native API も使えますが、
  // もし文字コード変換も行うときは Web API の FileReader 使います。
  var reader = new FileReader();
  reader.readAsText(this.inputFile, "Shift-JIS");
  reader.onload = () => {
    // reader.result に読み込んだテキストがいつも通り格納されます。
    // console.log(reader.result);

    // ローディング画面を解除しましょう...
    loading.dismiss();
  }
}


5
8
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
5
8