Monacaのサンプルアプリである「フォトシェアアプリデザインテンプレート」にバックエンド機能を実装する連載の第3回目。前回のプロフィール編集に続いて、今回は写真アップロード機能を作ります。
ライブラリのインストール
今回はJavaScriptライブラリとして以下を利用します。Monaca IDEのJS/CSSコンポーネントの追加と削除から追加してください。
- mustache.js(JSテンプレートエンジン)
- exif-js(EXIF情報を取得するJSライブラリ)
- timeago.js(経過時間を表示するJSライブラリ)
カメラ画面への遷移を作る
カメラで撮影を行う画面(camera.html)を修正します。写真を選択した時に、その画像のプレビューを表示したいのでプレビュー用のCanvasタグを用意します。
さらに画像データや位置情報を保持するためのタグを用意しておきます。
このままだと <input type="file">
標準のファイル選択ボタンが表示されてしまいますので、スタイルシートで消しておきます。
これでUIは完成です。

カメラ画面のイベントを作る
まずカメラ画面を表示したタイミングで処理を行います。そのため、document の show イベントを設定します。
ここでは画面の入力要素の初期化と、ファイル選択時のイベントを設定します。

写真のプレビュー処理について
写真を選択した際には、画像を読み込んでCanvasタグに表示します。その際、写真から位置情報と写真の向きを取得します。iPhoneで撮影した写真をそのまま表示すると上下反転することがありますので、向き情報であるOrientationの取得が必要となります。
画像と向き情報を取得したら、Canvasに描画します。向き(Orientation)によってCanvas内の画像を回転させます。
さらに位置情報を基に住所を文字列で取得します。これはHeartRails Geo APIを使っています。位置情報から住所情報を返してくれるAPIですが、認証不要で使えるので手軽です。

写真のアップロード処理
プレビュー表示したら、3秒あけてアップロードして良いか確認します。以下の処理はちょっと長いのですが、写真のアップロード処理を行った後、アップロードした写真のURLとメッセージをデータベースへ保存する処理です。保存処理がうまくいったら、ホーム画面に戻ります。
上記の処理の中で呼び出している canvasToBlob
は、Canvasタグに入っている写真データを取り出す関数です。Canvasの内容からBlobを生成しています。

この機能を有効にするにはニフクラmobile backendのアプリ設定画面で「データ・ファイルストア」の「HTTPSでの取得」を有効に設定する必要があります。

タイムラインを表示する
写真を投稿したら、タイムラインの写真一覧を更新します。まずは初期表示の時点で写真一覧が表示されるようにします。元々の写真一覧画面(home.html)をベースに、mustache.jsのテンプレート形式に変更します。実際の内容はhome.htmlを参照してもらうとして、ここではテンプレート部分を掲載します。

変数をプロキシとして作る
写真の一覧を更新する処理にはProxyを利用します。写真を配列で保管している変数をプロキシにして、その変数が更新されたらタイムラインをアップデートする仕組みにします。これは最近のReactやVueなどのVirtualDOMで使われている仕組みと同じです。写真を投稿して myPhotos
を更新すると、updateMyPhotos
が実行されます。さらに timelinePhotos
を更新すると、updateTimeline
が実行されてタイムライン表示が更新される仕組みです。
ここまでで、写真の投稿とタイムラインの更新処理が完成しました。写真などのバイナリデータはファイルストアに保存し、そのURLを別途保存しておくとバイナリデータへのアクセス回数も少なく済み、位置情報などのメタ情報をデータベースで管理できるようになります。
ここまでのソースコードはNCMBMania/photoshare at v0.3にアップロードしてあります(前回のプロフィール編集機能も含まれています)。実装時の参考にしてください。