講義の目標
- UserDefaultを使った処理ができるようになること
- タッチジェスチャーの取得処理を理解すること
- タイマー処理の実装ができるようになること
- デバッグの仕方(NSLog、デバッガ)をマスターすること
はじめに
今回の課題アプリは ジェスチャーフラッシュ となります。今回より、iOS SDKの提供する各種機能の応用例を中心に解説していきます。このアプリは、iOSの特徴とも言える、タッチジェスチャーとゲームを組み合わせたものとなります。ユーザーはゲーム開始と同時に、ランダムに表示されるジェスチャー(スワイプ・回転・ピンチ)を30個分こなします。その際の所要時間を競います。上位タイムは「ハイスコア」として記録されます。

完成品のサンプルは以下よりダウンロードできます。イメージが湧かない方は是非ご確認ください。
それでは、早速開発を始めて行きましょう!
プロジェクトの立ち上げと設定
新しいアプリを作る際は、まず、新規プロジェクトを立ち上げとアプリの設定を行います。
新規プロジェクトの立ち上げ
Welcom to Xcode画面から、Create a new Xcode projectを選択します。そしてSingle View Appを選択します。

今回は以下のように設定します。
| 入力項目 | 入力値 |
|---|---|
| Product Name | GestureFlash |
| Team | None |
| Oganization Name | 任意(”ALJ”など自分が所属している組織の名前を入れる) |
| Oganization Identifier | jp.co.al-j |
| Language | Swift |
| User Interface | Storyboard |
| Use Core Data | チェックを外す |
| include Unit Tests | チェックを外す |
| include UI Tests | チェックを外す |

アプリの設定
新規プロジェクトを立ち上げたら、アプリの設定を行います。ここで、アプリのアイコンやアプリの表示タイトル(Bundle Name)、サポートするデバイスの向き(Device Orientation)を以下のように、設定します。
Device Orientation の設定
対象デバイスとサポートするデバイスの向きの設定を行います。
ナビゲータエリアからproject > General を選択し、Development infoを以下の設定にします。
Development info
| Target | Device | 入力値 |
|---|---|---|
| iOS13.5 | iPhone | チェックをする |
| iOS13.5 | iPad | チェックをはずす |
| Device Orientation | Portrait | チェックをする |
| Device Orientation | Upside Down | チェックをはずす |
| Device Orientation | Landscape Left | チェックをはずす |
| Device Orientation | Landscape Right | チェックをはずす |

Bundle Nameの設定
アプリの表示タイトルを決めている設定項目Bundle Nameを変更します。
infoタブを選択し、Bundle Nameを次のように変更します。
Custom iOS Target Properties
| Key | Type | Value |
|---|---|---|
| Bundle Name | String | ジェスチャー |

素材取り込み
以下のリンクから素材ファイルをダウンロードします。
今回使用する素材は以下の通りです。
| ファイル名 | 説明 |
|---|---|
| icon-20pt@2x.png | Notification用x2画像 |
| icon-20pt@3x.png | Notification用x3画像 |
| icon-60pt@2x.png | アイコン用x2画像 |
| icon-60pt@3x.png | アイコン用x3画像 |
| icon-29pt@2x.png | 設定用x2画像 |
| icon-29pt@3x.png | 設定用x3画像 |
| icon-40pt@2x.png | Spotlight用x2画像 |
| icon-40pt@3x.png | Spotlight用x3画像 |
| icon-1024pt@1x.png | AppStore用アイコン画像 |
| btn_start.pdf | 「スタート」ボタン用画像 |
| btn_go_top.pdf | 「トップへ」ボタン用画像 |
| swipe-up.pdf | 「上スワイプ」画像 |
| swipe-down.pdf | 「下スワイプ」画像 |
| swipe-left.pdf | 「左スワイプ」画像 |
| swipe-right.pdf | 「右スワイプ」画像 |
| pinch-in.pdf | 「内向きピンチ」画像 |
| pinch-out.pdf | 「外向きピンチ」画像 |
| rotate-left.pdf | 「反時計回り回転」画像 |
| rotate-right.pdf | 「時計回り回転」画像 |
ダウンロードしたら、zipファイルを解凍してiconファイル、画像ファイルを、下図のとおり設定してください。
iconファイル

画像ファイル

画面のデザイン
画面を作成していきます。
スプラッシュ画面の設定
スプラッシュ画面を作成します。
今回は以下のように設定します。

background の設定
ナビゲーターエリアからLaunchScreen.storyboard を選択し、ViewController > View > Attributes inspector を選択し、 Background を以下へ設定します。
| Viewプロパティ名 | 設定値 | Hex Color |
|---|---|---|
| Background | Custom | F39431 |

Labelの設置
ライブラリーエリアを選択し、 View 上に Label を配置します。
Label に対して以下の設定を行います。
| Labelプロパティ名 | 設定値 |
|---|---|
| Text | ジェスチャーゲーム |
| Color | White Color |
| Font | 50px |
| Alignment | centor |
| Lines | 2 |

AutLayoutの設定
Labelに対して、以下の「制約(Constraint)」を設定します。


警告が表示されていなければOKです。
もし、警告が表示していた場合は、候補が表示されますので適宜対応してください。

メイン画面の設定
アプリの設定が完了したら、画面のデザインを行なっていきます。今回は3つの画面(スタート画面・プレー画面・結果表示画面)を持つアプリを作成します。Main.storyboardを開き、以下の手順に従って画面のデザインを行いましょう。
スタート画面のデザイン
まず、スタート画面からデザインしていきます。初期状態で、1画面分のViewは用意されているので、それをスタート画面とします。
今までの講義の画面デザインと同様にLabelとButtonを使って下記の画面を作ってください。


スタート画面のAuto Layout対応
今までの講義で作ったアプリと同様にAuto Layoutを使って下記の図を参考にスタート画面のレイアウト調整をしてください。
ハイスコアラベルの設定


ハイスコア値(1位)ラベルの設定

ハイスコア(2位)ラベルの設定

ハイスコア(3位)ラベルの設定

スタートボタンの設定

説明ラベルの設定


タイトルラベルの設定


これでAuto Layoutの設定は完了です。

プレー画面のデザイン
スタート画面のデザインが完了したら、プレー画面のデザインに移ります。先ほど述べたとおり、初期状態では1画面分のViewしか含んでいません。そこで、「クイズ」の時と同様、ViewをStoryboard上に新規追加します。ライブラリーエリアよりView Controllerを選び、Storyboard上に配置します。

ImageViewの配置
プレー画面では、背景を各ジェスチャーの画像とします、その画像を表示するために、正方形のImageViewを配置します。
| Viewプロパティ名 | 設定値 |
|---|---|
| Width | 300 |
| Height | 300 |

Labelの配置
次に画面上部にクイズのいくつかのLabelを配置します。まずは、以下のとおり、静的なLabel(コードから変更を受けないLabel)を配置します。

静的なLabelの配置が終わったら、コードから変更受ける動的なLabelを配置します。今回配置するのは、経過時間を示すLabelと、こなしたジェスチャーの数を示すLabelです。

プレー画面のAuto Layout対応
プレー画面のAuto Layout設定を行います。下図を参考に設定してみてください。
「経過時間」ラベルの設定

「経過時間」の値ラベルの設定

問題総数(30)のラベル設定

問題をこなした数のラベル設定

「現在:」ラベルの設定

ジェスチャー画像の設定


下図のように表示されればOKです。

※ 警告やエラーが表示される場合



結果表示画面のデザイン
3つの画面のうち、最後の結果表示画面のデザインに移ります。プレー画面同様、結果表示画面用のViewControllerをStoryboard上に新規追加します。

Labelの配置
Labelの配置します。下記のように配置してください。

1つは所要時間(記録タイム)を表示するものです。もう一つは、記録がハイスコアか否かを示すLabelで、ハイスコアを更新した場合、表示されます。
Buttonの配置
「トップへ」Buttonを配置します。

結果表示画面のAuto Layout対応
結果表示画面のAuto Layout設定を行います。下図を参考に設定してみてください。


新規View ControllerのアサインとSegueの設定
今回も前回同様、それぞれの画面に対して新規にView Controllerを作成します。また、各画面間のSegueを設定します。
新規View Controllerの作成
まずは、プレー画面用のView Controllerクラスから作成します。ナビゲーターエリアの中にある、GestureFlashと書かれたフォルダを右クリックし、前回同様Cocoa Touch classを選択し、Nextをクリックし、View Controllerを作成します。


以下の表の通り、クラス名とオプションを設定し、Nextをクリックし、既存のView Controllerとフォルダに保存します
| 入力項目 | 入力値 |
|---|---|
| Class | PlayViewController |
| Subclass of | UIViewController |
| Also create XIB file | チェックを外す |
| Language | Swift |



同様の手順で、結果表示画面用のView Controllerクラスも作成します。以下の表の通り、クラス名とオプションを設定します。
| 入力項目 | 入力値 |
|---|---|
| Class | ResultViewController |
| Subclass of | UIViewController |
| Also create XIB file | チェックを外す |
| Language | Swift |
ここまでの手順を正しく行った場合、ナビゲーターエリアに合計2つのファイルが新たに作成されたはずです。

新規ViewControllerのアサイン
ここまでの手順で、3つの画面用のView Controllerのひな形が作成されました。次に、新たに作ったPlay View ControllerとResult View ControllerをそれぞれのViewにアサインしなければいけません。
クイズアプリの時と同様、Interface Builderからそれぞれの画面のView Controllerを選択します。


Storyboard Segueの設定
Storyboard Segueは、遷移元の画面と遷移先の画面を「線」で結ぶことによって設定します。今回は、以下の3つの画面遷移があるので、それぞれに対してStoryboard Segueを設定していきます。なお、Segueの種類は全てPresent Modallyを選択します。
スタート画面→プレー画面プレー画面→結果表示画面結果表示画面→スタート画面
お気づきかもしれませんが、この流れは前回や前々回作成した手順と全く同じです。詳しい手順がわからない場合は、前回のテキストを参照してください。すべて正しく行えた場合は以下のとおりすべての画面が線で繋がります。
スタート画面からプレー画面への遷移


プレー画面から結果表示画面への遷移


ボタンに紐付いていない、Play View ControllerからResult View ControllerへのSegueに識別子をつけます。その識別子はtoResultViewとします。

結果表示画面からスタート画面への遷移
最後に、ユーザーが結果を見終わったら、スタート最後へ戻れるように、Segueを設定します。まず最初にもとに戻りたいViewControllerに以下の記述を行います。ここではViewController.swiftに記述します。
ViewController.swift@IBAction func backView(segue: UIStoryboardSegue) {
}
次に、結果表示画面上に「トップへ」ボタンを設置したかと思いますが、このボタンに対してSegueを設定します。キーボード上の「control」キーを押しながら、ViewController上のExitというボタンにドラッグしてください。

すると先ほど作成したメソッドが表示されていると思いますのでそれを選択してください。

これで元に戻るための接続が完了しました。
これにて、全てのStoryboard Segue(画面遷移)の設定は完了となります。すべて正しく行った場合、以下のように、すべての画面がそれぞれSegueを示す矢印で結ばれているはずなので、確認してください。

UIオブジェクトをコードと結びつける
Main.storyBoardとコードをアシスタントエディタで接続しておきます。
ViewController

class ViewController: UIViewController { |
PlayViewController

class PlayViewController: UIViewController { |
ResultViewController

class ResultViewController: UIViewController { |
これにて、画面デザインは完了となります。
スタート画面のコーディング
ここでは、スタート画面のView Controllerのコーディングを行います。
メンバー変数の定義
スタート画面は上記のUIオブジェクトと結びつけたものでメンバー変数の宣言は終わりなので下記のようになっていればなにもしなくて大丈夫です。
ViewController.swift
class ViewController: UIViewController { |
User Defaults領域の参照
User Defaultsとは、すべてのiOSアプリが持つ、データ保存領域です。基本的に、様々データを「キー(キーワード)」と紐付けることで、簡単に保存できます。このデータはアプリが終了しても、しっかり残るので、ゲームの途中経過やユーザーの設定を保存するのに最適です。今回は、ハイスコアを記録するのに使います。
スタート画面では、ハイスコアの読み出しを行います。もしハイスコアが記録されている場合は画面上のラベルの値をそれに応じて更新します。今回User Defaultには、以下のとおり3つのデータの保存と参照をします。
| キー | データの種類 |
|---|---|
| high_score1 | ハイスコア1位の記録 |
| high_score2 | ハイスコア2位の記録 |
| high_score3 | ハイスコア3位の記録 |
User Defaultsの参照は非常に簡単です。基本的には、NSUserDefaultsクラスのメソッド1つで、指定したキーの値を変数に代入することができます。以下の通り「override func viewDidAppear(animated: Bool)」メソッドを追加して下さい。
ViewController.swift
// ▼▼ 追加 ▼▼ |
User Defaultsを読み出す際、今回は読み出し結果をDouble型の変数として返すdoubleForKeyメソッドを使っています。もしキーに該当する値が存在しない場合は0が返されます。この他にも、様々データ型で読みだし結果を返すメソッドが用意されているので、適宜、Appleのドキュメント等を参考にして、最も適当なものを選んで下さい。
ViewControllerのライフサイクルについて
ライフサイクルとはアプリが起動してから、バックグラウンドへ移動するまでの間に処理されるコードのサイクルの事です。

NSLogによるデバッグメッセージの表示
コーディングを行う際、正常な動作を確かめる上で、変数の状態や処理の内容を見る必要が出てきます。
例えば、今回の例で、ハイスコアのラベルの値が変更されないというバグに遭遇したとします。その場合、User Defaultsのデータ読み出しの段階で問題が起きているのか、ラベルの値を更新する処理で問題があるのかを、切り分ける必要があります。このような時、NSLogによるデバッグは非常に有効となります。
使い方は非常に簡単です。コードの中に以下の一文を加えるだけです。
//NSLogによるデバッグメッセージ |
この例では、ハイスコアを格納するDouble型の変数の値を出力しています。基本的な使い方はStringでの引数に「format」を指定する方法と同じです。前半で、表示する文字列の書式を指定し、後半に参照する変数を指定します。

これにて、ViewControllerの実装は完了となります。
結果表示画面のコーディング
「クイズ」の時と同様、プレー画面から結果表示画面へ遷移する際、データの受け渡しを行う都合上、次は、結果表示画面のコーディングを行なっていきます。
ResultViewControllerのメンバー変数
まずはメンバ変数から宣言していきます。以下のとおり、メンバ変数を宣言してください。
ResultViewController.swift
class ResultViewController: UIViewController { |
上記のTimeIntervalは、精密な経過時間を扱うことのできるクラスです。これを用いることによって、マイクロ秒単位で時間の計測ができます。その使い方は後ほど説明します。
ハイスコアの計算User Defaults領域への書き込み
結果表示画面では、呼び出された段階で、「time」にゲームの所要時間(記録タイム)が格納されています。
まずはその値を元に、既存のハイスコアと比較をし、上回った場合は書き換えを行うメソッドを実装します。
以下のとおり、ResultViewController.swiftにコードを記述します。
ResultViewController.swift
// ▼▼ 追加 ▼▼ |
ここでは、User Defaultsの値の読み出しを行い、それらを今回の記録である「time」と比較しています。なお、「time」はNSTimeIntervalのインスタンスですが、Double型の変数としても扱えます。比較を行ったあと、最新のハイスコアをUser Defaultsに書き込みます。なお、「ハイスコア更新」ラベルですが、比較前で非表示とします。比較後に、もしハイスコアが更新されるようなことがあれば、表示状態にします。
ResultViewControllerの初期処理
ハイスコアの更新を行うメソッドの実装が終わったら、初期処理を実装します。以下のとおり、ResultViewController.swiftの「viewDidLoad」を実装します。
ResultViewController.swift
override func viewDidLoad() { |
ここでは、timeの値をラベルに反映し、先程実装したハイスコアの更新処理を呼び出しています。
プレー画面のコーディング
次に、本アプリの中心となるプレー画面のコーディングを行なっていきます。
タッチジェスチャーとは?
まず、タッチジェスチャーに関する説明を行なっていきます。昨今のスマートフォンやタブレットは基本的にタッチパネルで操作しますが、これらはページをめくる動作やスクロール動作などを直感的にタッチで行えます。これらをタッチジェスチャーといいます。iOSデバイスでは一般的なスワイプ(1本指でスクロール)をはじめ、回転(2本指で画面上の写真を回転)、ピンチ(拡大・縮小)などのジェスチャーを非常に簡単に検知できるようになっています。

今回はこの中でも、Swipe・Pinch・Rotateの3タイプに着目します。これら3タイプのジェスチャーを30個分、ランダムにユーザーに提示し、それをすべてやり終えるまでの時間を竸います。
メンバー変数の宣言
まずは、メンバー変数の宣言から行なっていきます。
以下のとおり、PlayViewController.swiftを編集して下さい。
PlayViewController.swift
class PlayViewController: UIViewController { |
ここにある、NSDateは、時間を取り扱うためのクラスです。その扱いかたは、後ほどのNSTimeIntervalと併せて解説します。また、NSTimerはタイマーによる割り込み処理を行うためのクラスです。これにより、指定した時間間隔毎に、任意のメソッドを呼び出すことができます。
経過時間の計測とResult View Controllerへの遷移
まずは、時間の経過時間の測定に関する説明をします。その前に、以下のとおり、PlayViewController.swiftを編集して下さい。
PlayViewController.swift
// ▼▼ 追加 ▼▼ |
これは、「クイズ」でも取り扱った、Segueを発動させるメソッドです。ゲームの経過時間(記録タイム)を測定する場合、ゲームが開始された時間から、完了までの時間を計測することになります。そこで今回は、ゲーム完了時にSegueを発動させるようにし、そのタイミングで所要時間を計測します。
経過時間を得るためには以下のように、NSTimeIntervalとNSDateのインスタンスを組み合わせます。
//所要時間を計測 |
ここにある「startTime」は後ほど、初期処理を実装する際に、セットします。NSDateクラスのインスタンスに対して、「timeIntervalSinceNow」を呼び出すと、現在までの経過時間をマイクロ秒単位で得ること事ができます。その際、「開始時刻」から「現在時刻」が差し引かれるので、経過時間は負の数となります。そこで、実経過時間を得るためには、以下のようにする必要があります。
elapsedTime = -(elapsedTime)
経過時間を取得した後は、それをResult View Controllerに渡します。その手法は「クイズ」の時と全く同じです。
次のジェスチャーを提示するメソッド
今回は、ランダムに提示された30個のジェスチャーをこなすことがゲームの目的となります。そこで、指定された1つのジェスチャーが正しく検知された場合、次のジェスチャーを提示するメソッドを実装していきます。以下に示すように、PlayViewController.swiftを編集して下さい。
PlayViewController.swift
//次の問題を表示 |
基本的に、このメソッドでは、これまでにこなしたジェスチャーの数をもとに、次の画面へのSegueを発動するか、次の問題を提示するかを判断します。次の問題を提示するとなった場合、ランダムにジェスチャーが指定されます。
今回は全部で3タイプ・合計8種類のジェスチャーを扱うものとし、それぞれに識別番号を指定します。ます。それらを以下に示します。
| 種類 | 識別番号 | 画像 |
|---|---|---|
| 右スワイプ | 0 | swipe-right.pdf |
| 左スワイプ | 1 | swipe-left.pdf |
| 上スワイプ | 2 | swipe-up.pdf |
| 下スワイプ | 3 | swipe-down.pdf |
| 内向きピンチ | 4 | pinch-in.pdf |
| 外向きピンチ | 5 | pinch-out.pdf |
| 時計回り回転 | 6 | rotate-right.pdf |
| 反時計回り回転 | 7 | rotate-left.pdf |
これらをランダムに指定し、識別番号を「currentGesture」に代入します。その後、画面に出ているラベルやImage Viewを適宜更新します。
ジェスチャーの認識
今回は、ジェスチャーの認識を行うのですが、そのための手段としてiOS SDKでは、UIGestureRecognizerというものを提供しています。これを利用することによって、簡単にジェスチャーを認識することができます。
プロトコルの設定
それでは、まずその準備からはじめます。以下の通り、PlayViewController.swiftにプロトコルの設定を施します。
PlayViewController.swift
【変更前】
class PlayViewController: UIViewController {
【修正後】
class PlayViewController: UIViewController, UIGestureRecognizerDelegate {
UIGestureRecognizerのセット
プロトコルの設定が終わったら、UIGestureRecognizerのセットを行います。以下のとおり、PlayViewController.swiftを編集して下さい。
PlayViewController.swift
// ▼▼ 追加 ▼▼ |
ここにあるコードは非常に長く、暗号文のように思うかもしれませんが、これら一連のコードのよって、それぞれのジェスチャーを認識する準備が整います。
スワイプの認識
スワイプは前述したとおり、1本の指で上下左右になぞるジェスチャーです。これらは方向ごとにそれぞれ独立したUIGestureRecognizerをセットします。
UIGestureRecognizerがセットされた後、iOSデバイスがジェスチャーを認識し場合、次のメソッドが呼ばれます。PlayViewController.swiftに追記して下さい。
PlayViewController.swift
// ▼▼ 追加 ▼▼ |
これらは、上下左右それぞれの方向のスワイプを検知した場合に呼ばれます。その際、「currentGesture」のがチェックされ、指定されたジェスチャーと検知したジェスチャーが一致した場合は、次のジェスチャーを提示する「nextProblem」が呼ばれます。
回転の認識
回転は、2本の指で画面上を回転するジェスチャーを指します。そのジェスチャーを検知した場合に呼ばれるメソッドを、以下のとおり記述して下さい。
PlayViewController.swift
// ▼▼ 追加 ▼▼ |
この時、最初に2本の指が画面に置かれた場所を基準とし、少しでも回転を検知した場合、回転した相対量が「ラジアン」の数値として返されます。まず、「ラジアン」を「度」に変換する必要があります。その際、以下の計算式を用います。
let degrees = radians * CGFloat(180/M_PI)
相対的な回転量が90度を超えた場合、ジェスチャーがこなされたというようにします。この時、スワイプ同様「currentGesture」の値と比較され、提示されたジェスチャーと認識したジェスチャーが一致した場合、「nextProblem」が呼ばれます。
なお、開始位置から右(時計回り)方向に回転された場合、正の値が返されます。開始位置から左(反時計回り)方向に回転された場合、負の値が返されます。
ピンチの認識
次に、ピンチの認識を行います。画面上で2本の指を近づけたり遠ざけたりするジェスチャーです。そのジェスチャーを検知した場合に呼ばれるメソッドを、以下のとおり記述して下さい。
PlayViewController.swift
// ▼▼ 追加 ▼▼ |
この時、最初に2本の指が画面に置かれた時の、2本の指の距離が「1」となります。同じ直線上で少しでも距離が変化した場合、変化の相対量が数値が返されます。例えば、「1以上の数値」が返された場合は、2本の指が離れていることになります。一方、「1未満の数値」が返された場合は、2本の指が近づいていることになります。
今回は、相対距離が「2.4」を上回った場合、外向きのピンチがこなされたとします。同様に、相対距離が「0.4」を下回った場合、内向きのピンチがこなされたとします。ピンチが正常にこなされたと認識できた場合、「currentGesture」の値と比較され、正解の場合は「nextProblem」が呼ばれます。
これにて、ジェスチャーの検知に関するコードの記述は完成となります。
Play View Controllerの初期処理
次に、Play View Controllerの初期処理を行います。以下の通り「viewDidLoad」を編集します。
override func viewDidLoad() { |
ここで着目すべきは、「startTime」の値が現在の時刻にセットされているところです。冒頭で説明したように、これにより、30個のジェスチャーをこなすまでの所要時間(タイム記録)を測定することができます。
NSTimerによるタイマー割り込み処理
次に、よく使う機能としてNSTimerがあります。このNSTimerはタイマー割り込み処理を提供するクラスです。NSTimerが発動されると、指定された間隔毎割り込みが発生し、指定されたメソッド呼ばれます。今回はこれを用いて、ゲーム画面中に経過時間の概算値を表示する機能を実装します。まず、PlayViewController.swiftの「viewDidLoad」を以下の通り編集します。
PlayViewController.swift
override func viewDidLoad() { |
さらに、0.1秒毎に呼ばれる「onTimer」というメソッドを実装します。
PlayViewController.swift
// ▼▼ 追加 ▼▼ |
NSTimerが発動されると、指定時間間隔(今回は0.1秒)毎に「onTimer」が呼ばれます。そして、「onTimer」内で経過時間を示すラベルの値に「0.1」を足します。これにより、ユーザーはゲーム中に概算経過時間を知ることができます。
ビルドと動作試験
これにて、すべての作業は完了となります。編集内容を全て保存し、ビルドを行なってください。このテキストの内容をすべて正しくやった場合、特に問題なくアプリが動作するはずです。
ここで、一点注意があります。iOSシミュレーター上では、マウスを使う都合上、ジェスチャー入力に限界があります。ジェスチャーの動作確認を行う際は、実機での検証を強く勧めます。
プレー画面で、3タイプ・8種類のジェスチャーがしっかり認識できること、NSTimerによって、概算経過時間が表示されることを確認します。また、結果表示画面では記録タイムが表示されること、また、スタート画面上でハイスコアが正常に表示されることも確かめて下さい。

デバッグメッセージの確認
「ジェスチャーゲーム」では、各所にNSLogを用いたデバッグメッセージを表示する命令を記述しています。ここでは、このNSLogによるデバッグメッセージの確認方法を解説します。
デバッグメッセージは、以下のように、デバッガーエリアに表示されます。

このNSLogによるデバッグメッセージは非常に便利かつ、よく使う機能なので、覚えるようにして下さい。
まとめ
今回はiOS SDKにおけるタイマーによる割り込み処理や時間計測の手法を学びました。また、ジェスチャー入力の検知手法、および、NSLogを用いたデバッグメッセージの出力方法を扱いました。
今回扱ったタイマーによる割り込み処理やジェスチャー入力は、様々なアプリで応用されています。よく使う機能なので、ぜひ使い方をマスターして下さい。また、自分流にゲームをアレンジして、いろんな機能を付加して下さい。