JavaScript
Cordova
TypeScript

Apache CordovaでWeb(PC、スマホ)、アプリのコード共通化について


はじめに

2018年4月に家事代行サービス Casyのシステムをリニューアルし、静的ページ以外のページ(ログイン後のページ)はSPAで作成しました。

iOSやAndroidアプリの作成にはApache Cordovaを使うことで、Web(PC スマホ),iOSアプリ,Androidアプリがまったく同じコードで動作しています。


よかった点

プラットフォームごとに開発する必要もなくなり、1つの機能に対して大幅に工数が削減できるようになりました。コードを修正をしても審査が必要ないので、気軽にリリースができます。Cordovaの場合はNativeの機能もコミュニティに豊富にpluginが用意されていて、javascriptでメソッドを呼び出すだけで使え、Webの知識だけで開発できます。


Cordovaの現状について

良いことづくめのようですが、Cordovaは古くからあり(2012年ぐらい)、React、Vue、AngularとSPAが広まってきているにも関わらず、この手法で開発されているサービスはそれほど多くないようです。

逆にアプリだけでいいと割り切ってReact Nativeが使われるケースも増えてきました。

Google Trendを見ると2015年をピークに下がりつづけています

スクリーンショット 2018-05-20 14.08.52.png

人気がない原因として、UIWebViewがひと昔前のJavaScriptエンジンのせいもあり、もっさりしていたり、Safariと挙動が違うことがあったり、CSSでアプリっぽく作るのが大変だったり、Swiftが登場して、iOSアプリが作りやすくなったことが要因としてあると思います。

ただCordovaでWkWebViewが使えるようになり(要plugin)、JavaScriptエンジンも刷新され速くなりました。

PC対応を気にしなければ、CordovaベースですでにネイティブっぽいUI部品もそろったフレームワークにOnsen UIionicがあり、CSSの知識すらほとんどなしに開発できる環境ができています。


CordovaのSPA開発で困ったこと


cookieが使えない


問題点

corsの設定で、Cordovaの場合はhostがないので、Access-Control-Allow-Originを'*'にせざるを得ず、そうするとAccess-Control-Allow-Credentialsがtrueにできない決まりなので、cookieが使えない。そのため、Webサーバによるセッション管理が使えない。


対応

ログイン確認ができたら、トークンを発行して送信し、Ajax呼び出しの際にトークンをセットしてもらうことで認証。なりすましを防ぐため、時々トークンを更新する。


Geolocation APIが動かない


問題点

現在地を取得するGeolocation APIがブラウザだと動くのに、Cordovaだと動かない


対応

cordova-plugin-geolocationのプラグインを入れる。

iOS10以上だと位置情報取得にユーザの許可のダイアログが必須になり、ブラウザだと勝手に出してくれるのに、デフォルトのCordovaだとダイアログを出す設定がされていないので、機能自体が使えない。

ついブラウザで動くならCordovaでも動くはずと思ってしまうが、動かないこともあるので特殊なAPIは確認したほうがいい。


WebView(アプリ内ブラウザ)の扱いが難しい


問題点

外部API呼び出し等でCordova内から呼び出すとアクセス元URLをチェックされる等でエラーになってしまう場合に、WebViewを立ち上げるもののgetのURLでしか立ち上げられなく、URLにトークンをのせるのは好ましくないが、再度ログインしてもらうのもつらい。

また一連の動作終了後、Webviewの閉じるボタンを見つけて閉じてもらうのもつらい。


対応

WebViewを立ち上げる前に、1回だけ短時間有効なトークンを取得し、それをWebViewのgetに含めることで自動ログインできるようにする。CordovaでWebviewのURLを監視できるので、完了用に予め決めたURLになったら、Webviewを閉じる


history.back()を実行すると画面がずれる


問題点

history.back()を呼び出すと、画面上部にあるstatusbarの下にあったwkWebViewの画面がせりあがってstatusbarに被り、その分画面下にスペースができる。

iOSの設定で予めstatusbarにoverlayするようにし、最初からwkWebViewをstatusbarに被らせる。statusbarにあった時計が見えなくなってしまうので、自前で時計を出力。


iPhoneXの画面の表示幅が小さい


問題点

iPhoneXで上下に黒い帯があって画面の表示域がせまい。


対応

iPhoneX用のスプラッシュ画像(1125px × 2436px)がアプリにないと、iPhoneXの画面幅が使われない。(要申請)

また、viewportのcontentに viewport-fit=coverの指定が必要。


複数人開発の際にgitの管理が大変


問題点

自動生成されたiOSやAndroidのコードは個人ごとの環境により内容が異なるので、git pullした後ビルドすると大量のdiffができてしまう。


対応

cordova platform rm ios && cordova platform rm androidして自動生成したコードを消した後のコードを管理する。

各platformごとに必要なresourceファイル(画像や画像の設定ファイル等)は、platform以下以外のところに置くようにして、git pullした後にcordova platform add iosやcordova platform add androidした後にそのresourceファイルをplatforms以下にコピーする。

もしくはCorodovaをビルドする端末は1台に制限する


まとめ

Service WorkerがSafariに搭載されることになり、Webでもアプリと同じようにオフラインで動かせたり、Push通知ができるようになると、アプリの場合に必要だった、更新の際の審査やApp内課金による手数料がなくせるため、モバイルの中心がアプリからWebになる可能性があると思います。

ただ、まだService Workerが行き渡っている訳ではないため、その間はCordovaでアプリを作成するのはいい選択だと思います。