iPhoneのネイティブ機能をWebViewから呼び出す方法(1)

・はじめに

 
リワード広告の「Reward Plus」の担当エンジニアをやっています、波切です。
最近、iPhone向けの新サービスが立ち上がり、私自身もiPhoneアプリ開発に入門したばかりなので、iPhone系の開発の話題を提供できればと思います。

・ネイティブとWebの連携

 HTML5の普及で、昨今ネイティブ機能でしか実現できないことは、だいぶ減ってきました。
Webの方が柔軟性があり、しかもネイティブの開発よりも少ない労力で開発することができるので、Webが利用できる場面では積極的に活用していきたいものです。
 一方で、アプリ内課金やデバイス機能へのアクセス、プッシュ通知等といったiPhoneの特性を生かしたサービスをつくるためには、ネイティブ機能へのアクセスは、まだまだ避けて通ることはできません。

そこで、よく利用されるのが、コンテンツの表示はWebで行い、必要に応じてネイティブ機能にアクセスする方式です。

この方式を採用する場合に問題となってくるのが、どうやってネイティブとWebを連携するかになりますが、今回は、UIWebViewからiPhoneのネイティブ機能へアクセスする方法について調べてみました。

・WebViewのイベントを使う方法

 WebViewのdelegateメソッドである、
shouldStartLoadWithRequestメソッドを利用するとWebViewがHTTPのリクエストを行う際に割り込んでネイティブ処理を行うことができます。

実際にネイティブ画面とWebViewを連携するシステムを例にとり説明したいと思います。

Untitled

システムの概要図(クリックすると拡大します)

今回は、メインのネイティブ画面からボタンを押すことで、WebViewがモーダル表示されて、その中のWebViewからネイティブ機能にアクセスしたいと思います。

早速コードを見てみましょう!

[WEB側 実装例]

[ネイティブ側 実装例]

・実装の説明

 上記の、WEB側の実装例を見ていたただければ分かりますが、<a>タグのリンクの指定で通常のhttp://呼び出しではなく、native://という文字列を渡してリンク呼び出しをしています。

これをネイティブ側のWebViewがURLのロードを開始する際に呼ばれるイベントの中でチェックして、呼び出し先のURLがnative://で始まっていたら
要求されたネイティブメソッドを呼び出すという仕組みになっています。

・まとめ

今回ご紹介した方法で、手軽にネイティブとWEBを連携させるには、十分実用になると思います。
一方で、いくつかかゆいところに手が届かないところもあります。

(1)ネイティブで処理を行った結果を簡単に取得することができない。

 今回の方式でネイティブ処理を呼び出すと、関数のように処理を行った結果を返せないため、
処理の結果を得るのに工夫が必要となります。方法としては、上記のシステム情報を得る例のように、ネイティブ側から、直接結果を書き込んでしまうか、WEB側にコールバック関数を用意しておいてネイティブ側から呼び出す方法等が考えられます。

しかし、どちらの方法にしてもWEB側の処理にあわせて、ネイティブ側の処理を書き直さなくてはいけなくなるため、ネイティブ処理を多くのWEBページで再利用する場合には、今回の方法はあまり適しているとはいえないでしょう。

(2)ネイティブ呼び出しを連続で行うのにトリッキーな方法が必要となる。

 これは、下の例を見ていただければ分かりますが、ネイティブ処理を連続で呼ぶ場合は、フレームを介さないとうまくいかないようです。

[失敗例]
[成功例]

・次回

次回は、今回の方式で課題になっていた部分を解消する、別の方法をご紹介したいと思います。
この方法を使うと、ネイティブ側の記述量は若干増えますが、WEB側の記述をシンプルに行うことが出来てしかもWEB側に値を返すことが出来る便利な方法です。

お楽しみに! 

第二回はこちらから
http://blog.engineer.adways.net/archives/13813985.html

※今回のソース一式は、下記のURLからダウンロードできます。

https://github.com/fugafigs/NativeFromWebView1