WKWebViewとSalesforceでHybridアプリ開発

はじめに

みなさん、こんにちは。 走れるシステムエンジニア、溝口です。

先日勝田全国マラソン(フルマラソン)とさいたまシティマラソン(ハーフ)に参加してきました。

結果はフルが2:45:19とハーフが1:14:17で、どちらも個人的な目標はクリア出来ました。

今年はトラックレースにも参加していきたいですね!

WKWebViewとは

さて、本題です!

今回はSalesforce MobileSDKを使用したモバイル開発で、内部ブラウザでWebページを表示するWebViewと、Nativeのコードをどう組み合わせていくか、ということを書いていこうと思います。

Appleは元々Nativeアプリ内でWebブラウザを表示させる仕組みとしてUIWebViewというコンポーネントを提供していましたが、iOS8から新たにWKWebViewというUIWebViewの改良版に当たるコンポーネントが使えるようになりました。

WKWebViewの特徴として

・iOSのSafariと同じJavascriptのエンジンを使用しているので、UIWebViewよりも動作が早い

・ローディング状態の取得など、使えるメソッドが増えた

などが挙げられます。

余談ですが、iOS版Chromeのようなサードパーティ製のブラウザは、従来であればSafariのパフォーマンスをどうやっても超えられなかったのですが、このWKWebViewが提供されたことによりSafariと同等かそれ以上に動作効率が良くなったと言われています。

1点注意する点として、WKWebViewはiOS8以上でしか使用出来ない為、iOS7以上のOSをサポートする場合、UIWebViewと共存させる必要が出てきます。

WKWebviewとUIWebViewの共存に関しては、先日「iOSオールスターズ勉強会」というイベントに参加した時に、ヤフー株式会社の佐野岳人さんの発表『let UIWebView as WKWebView』 が大変参考になったので、是非見てみて下さい。

WKWebViewへのセッションの引き渡し

Salesforce MobileSDKを組み込んだNativeアプリの中でWebViewで画面を表示する、所謂Hybridなアプリを開発する時に気になるのが、セッションの引き渡しをどうするのか、といった部分だと思います。 WebViewでSalesforceの画面を表示する場合、Native側でOAuthで認証したセッションを画面遷移時に引き渡す必要があります。 どういう風に実装するのか、下記のコードを見てみましよう

認証に必要な情報は基本的にSFRestAPIのシングルトンインスタンスに格納されています。 instanceUrlに「https://ap.salesforce.com」のような現在ログインしているサーバのインスタンスURLが格納されています。 accessTokenがセッション情報となるので、パラメータでsidとして指定し、遷移先のURLをretURLに指定することで認証情報を遷移先のSalesforceのページに引き渡すことが出来ます。 意外と簡単ですね!

WKWebViewを組み込んでみよう

前回のSalesforceMobile SDK3.0のアプリをSwiftで書いてみたで作ったアプリをベースとして、WKWebViewを組み込んでみましょう! このアプリは取引先を10件取得した後一覧表示し、表示されたレコードをタップすると詳細画面を表示する、といったものでした。 この詳細画面をNativeで作成した画面から、WKWebViewを使用し、VisualForceで作成した画面に置き換えてみましょう。 以下が今回作成したVisualForceとExtension、画面イメージになります。

AccoutMobile

取引先名を表示、作成、編集が出来るだけの簡単な画面です。 せっかくなので、今流行りのPolymerを使用したマテリアルデザインで作成してみました。 このMUIは最近出たばかりのフレームワークですが、今後も期待できそうなCSSフレームワークです。
では、この画面をどのようにしてWKWebViewで表示するのか、前回作成した詳細画面がどのように変わったのか見て行きましょう。

7行目でWKWebViewのプロパティを設定し、47行目のsetupWebView()で自身のViewにWKWebViewを描画、自身にデリゲートを設定しています。 次に、66行目?88行名でWKWebViewのデリゲートメソッドを記述しています。

それぞれ

didStartProvisionalNavigation:WebViewの読み込みが開始された時に呼ばれるメソッド

didFinishNavigation:WebViewの読み込みが完了した時に呼ばれるメソッド

didFailNavigation:WebViewの読み込みが失敗した時に呼ばれるメソッド

decidePolicyForNavigationAction:ページ遷移などのアクションが発生した時に呼ばれるメソッド

という機能を持っています。

今回は詳細画面(WebViewの画面)からSaveボタンで保存処理を行った際に、保存処理が完了次第、一覧画面(Nativeの画面)に遷移する、という機能を実装しました。


どのような仕組みになっているかと言うと Apex側ではAccountMobileExtension.clsのdoSave()メソッドの中でPageReferenceとして「completed://」というページに遷移するように記述しています。

これをNative側のdecidePolicyForNavigationActionでフックして、「completed://」というプレフィックスを持つアクションが発生した場合は前画面に戻る、という実装をして、WebViewから保存が完了したメッセージを受け取れるようにしています。

どのように動くかは、次のデモ動画を見てみましょう。

WKWebViewを動かしてみよう

今回WKWebViewを実装したアプリのデモ動画です。



詳細画面遷移時に多少の読み込みは発生しますが、

・Web、Android、iOSと共通で使える ・Native側でバリデーションを考慮しなくていい

・IDの引き渡しのみになるので、Nativeでのモデルの管理が楽になる

・Apex、VisualForce開発側とNative開発側で協業が出来る

ということを考慮すると、今回の詳細画面の様に一部の画面をWebViewで実装するというのはかなり効率が良いと言えるのではないでしょうか。

まとめ

モバイルと言えばOSではiOSやAndroid、ハードではタブレット、ファブレット、スマートフォン、開発手法としてNativeか、Hybrid、HTML5といった様々な選択肢があると思います。

NativeのパフォーマンスをHTML5が超えられるはずない!Native最高!とか、HTML5+Jacascriptでアプリを作れば色んな端末で動く!Webアプリが今後主流になる!とか、色々な意見があると思いますが、個人的には「使い分け」が大事なのかなと思います。

例えばリストビューやコレクションビューの様なNativeのパフォーマンスが必要で、かつUI/UXにもクリティカルに関わってくる画面に関してははNativeで実装して、パフォーマンスが多少劣っても気にならないデータの入力画面等はWebアプリとしてWebViewで表示するなど、その画面毎に最適な実装を採用していけば良いと思います。

1つのアプリの中でNativeで作る部分とWebViewで表示させる部分、それ以前に認証方法であったり、オフライン対応要件の有無や、ハードウェア特有の機能の使用の有無など、モバイルアプリを開発するにあたって考慮しなければならない事はたくさんあります。

その数ある選択肢の中から「最適なソリューション」を取捨選択し、提案出来るエンジニアになりたいですね。

おまけ

前回に引き続き宣伝です! Manawaというランナー向けの練習管理アプリと、Schedule BlockerというSFM SDKを活用したアプリをAppStoreで配布しています。 是非DLして活用して頂けると幸いです!