第08講 ウェブブラウザー
印刷を御希望の方はページ一番下の「印刷用ページ」より印刷してください。
PDFファイルとして保存したい場合も「印刷用ページ」より保存できます。 見出しに「★」マークがついた箇所は説明動画がございます。
第8講のポイント
はじめに前回の「RSSリーダー」では、RSSの取得から、XMLのパース、さらには、Table Viewの利用法まで、幅広くカバーしました。さらには、HTTP通信や非同期処理の概念等も学びました。
第8講の課題アプリは「ウェブブラウザー」となります。「ウェブブラウザー」はSafari等と同様のものです。ユーザーの要求に応じてウェブページを表示することが主目的となります。さらに付加機能として、お気に入りのウェブページを保存できるようになっています。お気に入りを保存するにあたって、今回は新たにリレーショナルデータベースというものを使います。
![]() それでは、早速開発を始めて行きましょう!
プロジェクトの立ち上げと設定新しいアプリを作る際は、まず、新規プロジェクトを立ち上げとアプリの設定を行います。
新規プロジェクトの立ち上げ新規プロジェクトを立ち上げます。その際、使用するテンプレートは「Single View Application」となります。
![]()
アプリの設定新規プロジェクトを立ち上げたら、アプリの設定を行います。ここで、アプリのアイコンやアプリの表示タイトル(Bundle Display Name)、サポートするデバイスの向き(Device Orientation)を以下のように、設定します。
外部素材のインポートまず今回使用する外部素材ファイルを一気にインポートしてしまいましょう。
今回使用する素材は以下の通りです。
![]() アイコン設定とサポートするデバイスの向きの設定素材のインポートが完了したら、Project Editorを開き、アイコンをRetina Displayと書かれたエリアの上にドラッグします。
サポートするデバイスの向きとアプリの名前は以下の通り設定します。
![]() Project Editorの「info」タブをクリックして「Bundle Display Name」の項目を次のように変更していきます。
![]() 画面のデザインアプリの設定が完了したら、画面のデザインを行なっていきます。
Autolayoutの無効化画面レイアウトを3.5インチ(iPhone4S以前)と4インチ(iPhone5以降)に対応させるための設定を行います。
まずはXcode4.5からデフォルトで有効になっているAutolayoutを無効にします。
※Autolayoutはまだ不安定ですので本講座はAutolayoutを無効にして画面デザインを行っていきます。
下記のように①View Controller全体を選択し、②「File Inspector」に変更して、③「Use Autolayout」のチェックを外してください。
![]() ブラウザー画面のデザインNavigation Bar・Bar Button Itemの設置まずは画面上部に、Navigation Barを設置します。ライブラリーエリアから、Navigation Barを選択し、画面の上部にドラッグします。
![]() その次に、「更新」ボタンをNavigation Bar上に設置します。これまで使ってきたRound Rect Buttonではなく、今回はBar Button Itemを利用します。
![]() 次に、「お気に入り追加」ボタンの見た目を変更します。ボタンを選択した上で、インスペクターから、今回は通常のViewの上にTable Viewを設置していきます。ライブラリーエリアから「Identifier」を「Add」に変更します。これによって、ボタンの見た目が変更されることを確認してください。これは、「お気に入り追加」ボタンとなります。
![]() この後、Navigation Barのタイトルを削除します。
![]() Text Fieldの設置次に、Navigation Barの左の方に、URLを入力するためのアドレスバーとなるText Fieldを設置します。
![]() その後、Text Viewのサイズをインスペクターから調整します。「Width」を「260」にしましょう。
![]() Toolbar・Bar Button Itemの設置次に画面下部に、Toolbarオブジェクトを配置します。ライブラリーエリアからToolbarを選択して画面の一番下に設置します。
![]() このToolbarにもう4つBar Button Itemを追加し、以下のようにします。設置したら、左寄りの2つをボタンのテキストをそれぞれ「戻る」と「進む」にします。さらに、「お気に入り追加」ボタンと同じ手法で、真ん中から右寄りの3つのボタンのIdentifierをそれぞれ、「Refresh」、「Stop」、「Bookmarks」とします。これらボタンに持たせる機能は、ボタンの内容が示す通りです。
![]() このままだと、見栄え少々悪いので、「進む」ボタン「更新」ボタンの間にライブラリーエリアから「Flexible Space Bar Button Item」を挿入します。
![]() WebViewの配置最後に、画面の真ん中一杯にWeb Viewを配置します。
![]() これでブラウザ画面の配置は完了です。
お気に入り画面のデザイン次に、お気に入り画面のデザインを行います。まず新しいView Controllerを配置し、上部にNavigation Barを配置します。その後、以下のようにNavigation Barの左手にボタンを配置した上で、表示を「戻る」とします。最後にNavigation Barのタイトルを「お気に入り」とします。
![]() 次にTable Viewを設置し、Prototype Cellsを1として、Prototype CellsのIdentifierを「Cells」とします。
![]() 新規View Controllerの生成と画面遷移の設定ここでは、お気に入り画面用のView Controllerを生成するとともに、画面遷移の設定を行います。
Favorites View Controllerの新規作成まずは、お気に入り画面用のView Controllerを新しく作成します。
以下の表の通り、クラス名とオプションを設定し、「Next」をクリックし、既存のView Controllerのフォルダに保存します
正しくできた場合、FavoritesViewController.hとFavoritesViewController.mが以下のように生成されているはずです。
![]() 次は、生成したブラウザー画面とお気に入り画面の間の画面遷移の設定を行います。
Favorites View Controllerのアサイン以下の通り、Favorites View Controllerを、実際のお気に入り画面にアサインします。
![]() 画面遷移の設定この後、ブラウザー画面から、お気に入り画面への画面遷移(Segue)を設定します。基本的には、「ブックマーク」ボタンが押されると、お気に入り画面へのSegueが発動されるようにします。ただし、今回は直接ボタンにSegueを割り当てることはしません。理由はブラウザー画面とお気に入り画面の間でデータの受け渡しがあるからです。
今回、お気に入り画面は、ブラウザー画面上に一時的に現れるものであるという位置づけです。お気に入り画面から、ブラウザー画面へ戻る際は「次の画面にSegue」するのではなく、「前の画面に戻る」というスタンスとなります。そのため、設定するSegueは直接View ControllerからFavorites View Controllerまでのもの1つとなっています。なお、設定するSegueのタイプは、「Modal」を選択します。
![]() Segueを設置したら、SegueのIdentifierを設定します。設置したSegueをクリックし、インスペクターからIdentifierを「toFavoritesView」にします。
![]() リレーショナルデータベース今回は、お気に入りページを保存するのに、「リレーショナルデータベース」というものを活用します。実装をはじめる前に、このリレーショナルデータベースに関する説明を行います。
リレーショナルデータベースの概要リレーショナルデータベースとは、1970年にIBM社のEdgar F. Codd氏によって提唱されたリレーショナルデータモデルの理論に基づいたデータ管理方式の一種です。1件のデータを複数の項目(フィールド)の集合として表現し、データの集合を「テーブル」と呼ばれる表で表すことができます。さらに、ID番号や名前などのキーとなるデータを利用して、データの結合や抽出を容易に行うことができます。
一応公式な説明をすると、このような形になりますが、身近なところで行くと、「表」をイメージしていただいて、構いません。例として、今回お気に入りを保存するための「テーブル」の概観を以下に示します。
なおこの「テーブル」の名前は「my_favorites」とします。
このテーブルでは、「id」、「title」、「url」がそれぞれフィールド(カラム)名となっています。このように「表」のような形でデータを管理するデータベースをリレーショナルデータベースといいます。
リレーショナルデータベースは現在主流のウェブサービスで、ユーザーのデータを保存する代表的手法です。主な製品としては、MySQLやPostgreSQLなどがあり、双方とも世界中で広く普及しています。
iOSにおけるリレーショナルデータベースiOSにおいては、リレーショナルデータベースとして、「SQLite」というものを利用することができます。SQLiteは手軽かつ軽量なリレーショナルの代表格です。これは1つのデータベースを単一のファイルとして扱うことができます。
今回、素材データを読み込む際、「favorites.sqlite」というファイルを読み込んだかと思います。これが今回使用するデータベースとなります。このデータベースには予め、先程示したテーブルが1つプリセットされています。今回はこのデータベースにお気に入りを登録していきます。
SQL言語リレーショナルデータベースにおいて、データを保存したり、読みだしたりする場合、SQL言語というものがよく使われます。このSQL言語を用いることで、データベールにデータを登録したり、登録済みのデータの値を更新したり、任意のデータを抽出した上で読みだしたりすることができます。
まずは、データを登録する例から見て行きましょう。今回の「my_favorites」というテーブルに新たにデータを登録する場合は、以下のようになります。
このように、テーブル名とフィード名をしてした上で、任意の値を新しく登録(INSERT)することができます。
次に、データを読み出す例を見てみましょう。同様に「my_favorites」というテーブルから全データを参照する場合、以下のようになります。
このように、リレーショナルデータベースはSQL文によって、データの登録や参照が行えるようになっています。
SQL言語はこれ以外にも様々なバリエーションがあります。データを参照する際に、特定の条件によって結果の抽出ができたり、テーブルの構成を変更したりと、実に多様な操作が行えます。ここで、全て扱うことはできませんが、興味のある人はぜひ調べてみて下さい。
FMDatabaseライブラリーiOSからSQLiteを利用するにあたり、データを登録したり、参照したりするコードを記述しようとすると、少し複雑なコーディングが必要となります。ここで、FMDatabaseというライブラリーを使うと、コーディングを比較的簡単にすることができます。
今回は、このFMDatabaseを用いてSQLiteを操作することにします。差し当たり、冒頭で必要なファイルを一式インポートしましたが、それ以外に、以下のように必要なライブラリーの設定を施す必要があります。
ナビゲーターエリアよりプロジェクトを選択し、「Build Phases」タブを選択します。そのと、「Link Binary With Libraries」セクションの「追加」ボタンをクリックします。
![]() その後、表示される一覧の中から、「libsqlite3.0.dylib」を選択肢、「Add」をクリックします。
![]() その後、「Link Binary With Libraries」セクションに「libsqlite3.0.dylib」が追加されていることを確認し、完了となります。
![]() コードの記述ここでは、「ウェブブラウザー」のコードの記述をしていきます。
Favoritesクラスの実装まずは、お気に入りのサイトの名前やURLを包括的に扱うFavoritesクラスの実装から行います。
新規クラスの作成これまでと同じ方式で、Xcode上で「Favorites」というObjective-Cの新規クラスを作成しましょう。
![]() 正しく行った場合、Favorites.hとFavorites.mという2つのファイルが出来上がるはずです。
![]() FavoritesクラスのコーディングFavoritesクラスは、包括的にお気に入りサイトの情報を扱うための非常にシンプルなクラスです。以下のとおり、メンバー変数を宣言し、外部クラスから参照ができるように、プロパティの設定を行います。
Favorites View Controllerのコーディングデータ受け渡しの都合上、まずは、Favorites View Controllerのコーディングを行います。
メンバー変数の宣言とDelegateの設定まずはメンバー変数の宣言からから行なっていきます。
Delegateの設定このFavorites View Controllerでは、データベースに登録されたお気に入りサイトがTable View上に表示されます。お気に入りサイトが選択されたとき、もとのブラウザー画面で、その選択されたサイトのURLをロードするようにします。そこで、選択された項目のURLをブラウザー画面に伝達する必要があります。
今回の画面遷移は、「新しい画面を立ち上げる」のではなく、「前の画面に戻る」という扱いにします。前者の場合、Segue時に遷移先のメンバー変数に渡すことができますが、後者の場合は少し話が違ってきます。それは、遷移元にデータを返す必要があるからです。
ここで、Delegate通知が登場します。自分自身のDelegateを宣言し、このDelegate通知を遷移元に画面で受けるようにします。その際、所定のメソッドが呼ばれるようにプロトコルの設定を行い、そのメソッドでURLを受けるように設定します。
最初はわかりづらいかもしれませんが、とりあえず、コードを記述し、慣れるようにしましょう。それでは、以下のようにFavoritesViewController.hを編集し、独自のプロトコルの生成を行います。同時に、FMDatabaseライブラリーとFavoritesクラスを参照できるようにimport文を追記しましょう。
FavoritesViewController.h
ここにある、「id <FavoritesViewControllerDelegate> delegate」はこのクラス自身のDelegateを示します。
基本的には、ブラウザー画面側でこのFavorites View Controllerの発するDelegate通知を受け取るようにします。その上で、Delegate通知が発生した際に、呼ばれる2種類のメソッドを独自のプロトコルとして設定します。
データベースの参照まずは、データベースを参照する前に、Favorites View Controllerの初期処理を見て行きましょう。FavoritesViewController.mの「viewDidLoad」を以下の通り改変していきます。
ここでは、まず、お気に入りを格納する配列である「favoriteList」を初期化しています。その後、データベースファイルの場所を取得しています。基本的には、「サンドボックス」の中の「Documents」フォルダに「favorites.sqlite3」が格納されているものとします。「サンドボックス」に関しては後ほど解説します。
次に、実際にデータベースを参照し、登録されているすべてのお気に入りサイト情報を「favoriteList」に格納するメソッドを、FavoritesViewController.mの中で記述します。
まず、データベースファイルの場所をした上で、FMDatabaseクラスのインスタンスを生成します。次に、データベースを開き、SQL文(クエリ文)を実行します。ここでは、「my_favorites」テーブルに入っているデータをすべて参照するようになっています。その後、返された項目ごとにFavoritesクラスのインスタンスを生成し、タイトルとURLを格納します。これの処理をお気に入りの数だけ繰り返し、すべてのお気に入りデータの入った「favoriteList」ができあがります。読み込みが完了したら、データベースを閉じます。
Table Viewの構築データベースからの読み込みが終わったら、お気に入りのタイトルをTable Viewに流し込みます。その前に、インターフェースファイル上でList Viewのプロトコルの設定を追加します。
前回の「RSSリーダー」同様、以下の3つのメソッドを記述します。これらは、TableViewの構築に関わるメソッドです。
基本的には、前回の「RSSリーダー」と同じ仕組でTable Viewを構築しています。唯一違っている部分は、今回は標準のセルを用いている点です。
セルがクリックされた時の処理Table Viewが整ったところで、セルがクリックされた時に呼ばれる処理を以下の通り記述します。
先程述べたとおり、今回はリスト中のアイテムが選択された場合、該当するサイトのURLを元のブラウザー画面に伝達する必要があります。そこで、Table View中のお気に入りの項目が選択されたとき、Delegate通知が発生するようにし、ブラウザー画面の中の「favoritesViewControllerDidSelect」というメソッドを呼び出すようにします。その際、引数としてお気に入りサイトのURLを渡します。
「戻る」ボタンが押された時の処理最後にお気に入り画面の「戻る」ボタンが押された時に、ブラウザー画面に戻るメソッドを記述します。
これにて、お気に入り画面の実装は完了となります。
View Controllerのコーディング次にView Controllerのコーディングを行います。
メンバー変数の宣言まずはメンバー変数の宣言からから行なっていきます。
今回はウェブページを表示するにあたって、UIWebViewクラスを用います。このクラスは、iOSアプリ上に任意のウェブページを簡単に表示することを可能にします。
同時に、View ControllerからFMDatabaseライブラリーとFavorites View Controllerクラスを参照できるようにします。以下の通り、ViewController.hを編集します。
SQLiteデータベース とサンドボックスまず、iOSデバイスは、それぞれアプリ専用の領域として、「サンドボック」が与えられています。このサンドボックスとは、iOSアプリが直接データを安全に読み書きできる領域で、アプリごとにそれぞれ用意されています。アプリ側からファイルを書きこむ(書き換える)場合、このサンドボックスにファイルがある必要があります。
今回は、データベースへの書き込みも行う都合上、初回起動時にデータベースファイル(favorites.sqlite)をプロジェクトのフォルダから、サンドボックス内の「Documents」フォルダにコピーする必要があります。そこで、起動する度に、サンドボックス内の「Documents」フォルダにデータベースファイルがあるかどうかを確認し、なければコピーするメソッドを実装していきます。
以下の通り、ViewController.mに記述して下さい。
ここにある、「databaseName」や「databasePath」の値は、後ほど初期処理を記述する際に設定します。
Web View上にウェブページを表示まずは、Web View上にウェブページを表示するためのメソッドを記述します。
単純にWeb Viewに任意のウェブページを表示する場合は、上記のコードを見ても分かる通り、非常に簡単です。しかし、このままでは、ウェブページが正常にロードされたか、ロードに失敗したかを知ることはできません。そこで、Web ViewからDelegate通知をView Controllerで受けるようにし、成功時と失敗時に呼ばれるメソッドを実装していきます。
その前に、プロトコルの設定をインターフェースファイル上でやります。以下の通り、ViewController.hを編集して下さい。
プロトコルの設定ができたら、実際に呼ばれるメソッドをViewController.mに実装していきます。
これらは、ページのロードが成功した時と失敗した時にそれぞれ呼ばれるメソッドです。
ページのロードに成功した場合、ロードしたページのタイトルとURLを取得するとおもに、アドレスバーのText Fieldの値を、ロードしたページのURLに書き換えています。
一方、ロードに失敗した場合は、その旨をUIAlertViewを用いて通知するようにしています。
なお、これらが正しく動作するためにはWeb ViewのDelegate通知をView Controllerで受けるようにしなくては行けません。そのための設定がもう一つあるのですが、それは後ほど初期処理を記述する際に行います。
アドレスバーの設定今回、ブラウザー画面上部にURLを指定するためのText Viewを設置しました。その際、キーボード入力を正しく扱うメソッドを記述する必要があります。
まずは、インターフェースファイルにプロトコルの設定を行います。
ViewController.h
次に、キーボードのreturnキーが押された時に、呼ばれるメソッドを以下の通り、ViewController.mに実装していきます。
ここで、着目すべきは、キーボードからの入力があった際に、文字列を処理しているところです。Web Viewでウェブページを表示するためにURLを渡す時、必ずURLの先頭に「http://」が含まれている必要があります。一方で、ユーザーの中には「http://」を省略する人も少なくはありません。そこで、このメソッドの中では、入力された文字列を検査し、先頭に「http://」が含まれない場合は追加するようにしています。
このメソッドが正しくよばれるためには、もうひとつ施すべき処理があるのですが、それは後ほど処理を記述する際に説明します。
お気に入りの追加次は、お気に入りの追加処理を実装していきます。差し当たり、画面上の「お気に入り追加」ボタンに紐付くIBAction型のメソッドを実装していきます。
なお、お気に入りが追加されるときに、SQLiteデータベースにアクセスし、追加を行うクエリ文を発行します。これにより、「favorites.sqlite3」に含まれる「my_favorites」というテーブルに新たなお気に入り項目が追加されます。
それでは、View Controller.mに以下のコードを記述してください。
このメソッドでは、現在表示されているページがお気に入りとして登録される仕組みになっています。登録が行われる条件として、ページが正常にロードされていることを冒頭でチェックしています。
正常にロードされたことが確認できたら、SQLiteデータベースにアクセスし、クエリ文を発行することで、お気に入りを追加しています。SQLiteデータベースへの追加が終わったら、その旨をUIAlertViewで通知するようになっています。
お気に入り画面への遷移次に、お気に入り画面への遷移を行うメソッドを、「お気に入り」ボタンと紐付くIBAction型のメソッドとして実装します。また、その中でSegueを発動させるメソッドも併せて記述します。
以下のようにViewController.mに記述していきます。
お気に入り画面から戻った後の処理ここでは、今まで扱ってきた、Segueを発動させるメソッドを呼び出しています。しかし、このままでは、お気に入り画面が閉じられた時に、ユーザーによって選択されたお気に入りサイトのURLを受け取る術がありません。
そこで、Favorites View Controllerからのデリゲート通知によって呼ばれるメソッド実装していきます。
その前に、ViewController.hに、Favorites View Controllerのプロトコルの設定を施す必要があります。
プロトコルの設定が終わったら、以下のようにViewController.mに実際のメソッドを記述していきます。
お気に入り画面上の「戻る」ボタンが押されたとき、Delegate通知がなされ、ここで実装した「favoritesViewControllerDidCancel」が呼ばれます。同様に、お気に入り画面上のTable Viewからお気に入りが選択された際は、ここで実装した「favoritesViewControllerDidSelect」が呼ばれます。その際、引数として、選択されたお気に入り項目のURLが渡されるので、それをロードします。
View Controllerの初期処理View Controllerの初期処理を行います。そこで、ViewController.mの中の、「ViewDidLoad」メソッドを以下のように編集します。
ここではまず、Text FieldとWeb ViewからのDelegate通知をそれぞれView Controllerで受け取れるようにするために、以下のような記述がなされています。
また、冒頭で説明したように、データベースの名前とファイルの場所を示す、「databaseName」と「databasePath」を設定しています。その後、サンドボックス内にデータベースのコピーが存在するかどうかを確認した上で、無ければコピーを作成するメソッドを呼び出しています。
最後に、最初のホームページ(ここでは「http://www.google.co.jp」を指定)を呼び出しています。
UI画面とコードの関連付けここまでで、基本的にコードの記述は全て完了となります。そこで、これまでに設置したUI画面上の部品とコード上の処理を関連付けます。
ブラウザー画面の関連付けまずは、ブラウザー画面のWeb Viewから関連付けます。以下の通り、Web ViewそのものはView Controllerの中の「webView」と関連付けます。さらに、「Received Actions」以下の「goBack」、「goForward」、「reload」、「stopLoading」の4つをそれぞれ画面下部の「戻る」、「進む」、「更新」、「中止」ボタンと関連付けます。
![]() 次に、アドレスバーのText FiledをView Controllerの「urlField」と関連付けます。このとき、Text Fieldを選択する際、確実にText Fieldを選択するために、Document OutlineからText Fieldを右クリックしましょう。
![]() 同様に「お気に入り追加」ボタンのセレクタをView Controllerの中の「saveFavorite」と関連付けます。
![]() 最後に、同様の手法で「お気に入り」ボタンのセレクタをView Controllerの中の「goToFavorites」と関連付けます。
![]() お気に入り画面の関連付けここでは、お気に入り画面の関連付け作業をやっていきます。
まずはTable Viewの「dataSource」と「delegate」をFavorites View Controllerに設定します。
![]() 次に、「戻る」ボタンのセレクタをFavorites View Controllerの「back」と関連付けます。
![]() ビルドと動作試験これにて、すべての作業は完了となります。編集内容を全て保存し、ビルドを行なってください。このテキストの内容をすべて正しくやった場合、特に問題なくアプリが動作するはずです。
まず、起動時にGoogleのホームページが表示されることを確認して下さい。その後、手動でURLを入力したり、リンクをクリックしたりしながら、適宜ウェブを閲覧しつつ、適当なタイミングでお気に入り追加ボタンを押し、お気に入り登録が完了することを確認して下さい。また、「戻る」や「進む」などのボタンが動作することも確認しましょう。
お気に入り画面からは、これまで登録したサイトの一覧が表示され、Table Viewのアイテムをクリックすると、ブラウザー画面に表示されることを確認して下さい。
![]() まとめ第8講では、Web Viewの扱い方やSQLiteを用いたリレーショナルデータベースの紹介を行いました。それらを元に、Safariのようなウェブブラウザーを独自に作成しました。
今回のアプリはDelegate通知や独自のプロトコルの設定等、色んな要素が重なりあっているため、難易度が多少高くなっています。一方で、ここに書かれている内容を理解できれば、iOSやObjective-Cの仕組みをマスターしたレベルまでになったといえるでしょう。もし、わかりにくいと思った場合は、ソースコードを今一度見直し、復習するようにしてください。
次回は少し方向性を変え、位置情報センサーや加速度計を扱っていきます。引き続き、頑張って行きましょう。
|