Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
時間制限付きクイズアプリをつくる
〜 怒涛のフルカスタマイズバージョン 〜
自己紹介
✦
今までの仕事履歴(本業)
石川県金沢市生まれ
本業はサーバーサイドのプログラマ ※Rails&PHP使い
26歳〜31歳:Ruby / PHPのプログラマ
23歳〜25歳:Webデザイナー兼ディレクター
最近はiOSアプリ開発にも...
これまでつくったもの(2015年)
① 簡易家計簿アプリ「Coffre」
② ゲームアプリ「10秒虫食い算」
・カレンダーを自作しています
・シンプルなお小遣い帳感覚で支出管理できます
・全問正解者ほとんどいません…
・不定期ですがコラムも書い...
クイズアプリのサンプルからアレンジを
�(ありきたりなアイデアでも最初はOK!)
クイズアプリは工夫の余地がたくさんあるし、あとは開発に必要な知識を網羅するのにはとても良いネタ!
✦ 初心者から上級者まで応用範囲が広く取り組みがいがある!
① ...
時間制限を実装して難易度をUP!
�(時間制限というアレンジは結構面白いと思われる)
タイマー部分のデバッグは慣れないうちはしんどいけれどアプリができると結構面白く感じられるハズ。
✦ 10秒虫食い算開発時にやってみた恐ろしいアレンジがきっかけ...
計算結果ページもライブラリでひと工夫
(ある程度基本的な事項が理解できてきたら便利なライブラリを使ってみよう)
自分でまったくゼロから実装が難しかったり、工数を短くしたい場合にはライブラリを活用して機能追加!
✦ これまでの結果やグラフの実装を...
画面の仕様と設計について
�(シンプルだけどもクイズアプリの基本が網羅できる形にしました)
特に大事なのは「ゲーム部分」と「ゲーム結果」の画面。作りをしっかりと見ておくとよいかと思います。
✦ 画面はシンプルに3画面(オープニング → ゲーム ...
ゲームのフローチャート
(ゲームのフローチャートがないと実装がこんがらがりやすい)
今回はタイマーによる時間制限も考慮しないといけないため、いきなりの実装はかなりリスキーです。
✦ ゲームの流れをしっかりとあらかじめ作っておこう
前提条件:
1...
サンプルとデモの紹介
(まずは是非サンプルをダウンロードして実機で確かめてみて下さい)
ゲーム部分の挙動やプログラムの実装部分を前述のフローチャートと合わせて見てみてくださいませ。
✦ 今回は時間制限付きの4択クイズアプリを作成してみました
①...
実際のポイント①:タイマー処理
✦ NSTimerクラスを使って「時間制限」と「残り秒数の表示」をする
�(タイマー処理は以外と簡単にできる)
NSTimerのscheduledTimerWithTimeIntervalメソッドの引数に設定でき...
実際のポイント②:CSVファイル読込
✦ 問題文や選択肢の一覧はCSVファイルで管理しておく
�(CSVの読み込み方法に関しては覚えておくと便利)
簡易的なデータベースの代わりとしても十分に活用可能。しかしカンマ区切りという点には注意が必要。
...
実際のポイント③:配列のランダムソート
✦ NSMutableArrayクラスを拡張してメソッドを追加
�(拡張やプロトコル指向のプログラミングに関しては自分もまだまだ勉強している最中)
今回は簡単な機能でこんな風に既存クラスを拡張してメソッド...
実際のポイント④:ゲームに関する動き
✦ 今回のサンプルアプリでのメソッドが実行される順番について
 (正解 or 不正解の判断処理と解答のアクション時のメソッドの流れに注目)
次の問題を表示する or 計算結果を保存して次の画面へ遷移する部分...
//登録日順のデータを最新から5件取得をする
static func fetchGraphGameScore() -> [Double] {
let gameScores: Results<GameScore> = realm.objects(...
仕様決めからボタンやラベル要素の活用の基本・画面遷移からデータ永続化まで一通り実現できますよー
✦
クイズアプリを題材にしての学習はアプリ開発でもかなりよいプラクティス
セッションのまとめ
✦
タイマーを利用した時間制限などのアイデアを入れると...
Upcoming SlideShare
Loading in …5
×

時間制限付きクイズアプリをつくる

1,430 views

Published on

第14回Swiftビギナーズ勉強会の資料になります。

「食べ合わせ」を題材にした4択クイズアプリの実装をもとに、時間制限の実装の部分からタイマー処理の使い方・データ永続化・ライブラリの活用やクイズの振る舞いの組み立てまでをまとめました。

★時間制限付きクイズアプリをつくるサンプル紹介と実装ポイントのまとめ(怒涛のフルカスタマイズバージョン)
http://qiita.com/fumiyasac@github/items/18ae522885b5aa507ca3

Published in: Technology
  • Be the first to comment

  • Be the first to like this

時間制限付きクイズアプリをつくる

  1. 1. 時間制限付きクイズアプリをつくる 〜 怒涛のフルカスタマイズバージョン 〜
  2. 2. 自己紹介 ✦ 今までの仕事履歴(本業) 石川県金沢市生まれ 本業はサーバーサイドのプログラマ ※Rails&PHP使い 26歳〜31歳:Ruby / PHPのプログラマ 23歳〜25歳:Webデザイナー兼ディレクター 最近はiOSアプリ開発にも絶賛浮気中! 趣味:シルバーアクセサリー集め・スイーツ作り・開発 女子向け・グルメ・エンタメ関連のお仕事が多い&最近はRailsやLaravelも Qiita : http://qiita.com/fumiyasac@github Github : https://github.com/fumiyasac ✦ 酒井文也(さかい ふみや) 東京(大塚)住まいの31歳 こんな格好してますが… 遊び人ではなくエンジニアです お酒好きそうと思われますが… ビールが全く飲めません キャリアのほうは… 結構ブランクあったりとベッコベコです ※心の叫び❶ ※心の叫び❷ ※心の叫び❸
  3. 3. これまでつくったもの(2015年) ① 簡易家計簿アプリ「Coffre」 ② ゲームアプリ「10秒虫食い算」 ・カレンダーを自作しています ・シンプルなお小遣い帳感覚で支出管理できます ・全問正解者ほとんどいません… ・不定期ですがコラムも書いています ・サーバーサイドはRuby on Railsを使用 http://www.coffre.me/ ・デザインにもこだわってみました(特にグラフ) ・実はちょっとバグがあります。 ・問題は今後追加予定(現在110問収録) 個人的にはなりますが、他にもアプリ・Webサービスなど開発中です(2016年も宜しくお願いします) ・サイト等は次回のアップデートで公開予定 http://blog.just1factory.net/services/284 ・若干の中毒性を含みます
  4. 4. クイズアプリのサンプルからアレンジを �(ありきたりなアイデアでも最初はOK!) クイズアプリは工夫の余地がたくさんあるし、あとは開発に必要な知識を網羅するのにはとても良いネタ! ✦ 初心者から上級者まで応用範囲が広く取り組みがいがある! ① iOSアプリ開発を始めたてのころ ・XCodeの使い方やUILabel / UIButtonなどの基本的なパーツに関する理解 ② 色々こなれてきたら機能を追加してアレンジを加える時期 ・画面の遷移やSegueに関するしくみや理解 ・正解or不正解の判断のロジックの実装 XCodeそのものに対する理解や使い方、そして基本的なUIKitに関する理解が元になる ・時間制限とかつけてみたいな ・結果をグラフ表示したり履歴を見ることができるようにしてみたいな ・変数やクラスに関する基本的な理解 ・問題の管理をもっと楽にできないかな 基本となるアプリの中に自分なりのアレンジや拡張を加えてより面白くしたい思いが!
  5. 5. 時間制限を実装して難易度をUP! �(時間制限というアレンジは結構面白いと思われる) タイマー部分のデバッグは慣れないうちはしんどいけれどアプリができると結構面白く感じられるハズ。 ✦ 10秒虫食い算開発時にやってみた恐ろしいアレンジがきっかけ 虫食い算に10秒の時間制限をつけてみるとみんな解けなくなるという事態に… ようやくゲームアプリらしい形になる <Step1. 暗算アプリを虫食い算にする> ・結構難易度が上がる ・Timerの実装に関してはNSTimerクラスを活用して作成 タイマー処理の基本的な実装方法はAppleの公式ドキュメントやQiitaを参考にしてみて下さい。 Swift2.2とそれ以前では若干書き方が変わってくる部分があるのでご注意を。 NSTimerクラスで重要なのはタイマー生成・停止・再開の3つ(今回のサンプルで使うのはタイマー生成と停止) ただのサンプルだけじゃもったいない感じ 試作段階で「できるか!」というマサカリの嵐 <Step2. 10秒の時間制限をつけてみる> ・初見で全問正解がほとんど不可能 なかなかいい感じゲームの形が実現できた
  6. 6. 計算結果ページもライブラリでひと工夫 (ある程度基本的な事項が理解できてきたら便利なライブラリを使ってみよう) 自分でまったくゼロから実装が難しかったり、工数を短くしたい場合にはライブラリを活用して機能追加! ✦ これまでの結果やグラフの実装をすることでグレードアップ! ① Realm(データ永続化) ・CoreDataより扱いやすくドキュメントも多いデータ永続化用のライブラリ ② ios-charts(グラフ描画) ・ネイティブアプリでグラフを作成することができるライブラリ (Githubのページ) https://github.com/danielgindi/ios-charts (Realmのページ)https://realm.io/jp/docs/swift/latest/ 今回はゲームのデータを登録するために使用しました。 今回は直近のゲームデータの推移を表現するために使用しました。 ・CocoaPodsを使ってアプリに便利な機能を追加する CocoaPods対応のライブラリを探す:https://cocoapods.org/ CocoaPodsのPodfileの書き方色々:http://dev.digitrick.us/notes/PodfileSyntax CocoaPodsとはなんぞや&最初の導入など:http://qiita.com/satoken0417/items/479bcdf91cff2634ffb1
  7. 7. 画面の仕様と設計について �(シンプルだけどもクイズアプリの基本が網羅できる形にしました) 特に大事なのは「ゲーム部分」と「ゲーム結果」の画面。作りをしっかりと見ておくとよいかと思います。 ✦ 画面はシンプルに3画面(オープニング → ゲーム → 結果) オープニング ゲーム 結果 (履歴とグラフ) セグメントコントロールで切り替え 問題を解き終わったら遷移する
  8. 8. ゲームのフローチャート (ゲームのフローチャートがないと実装がこんがらがりやすい) 今回はタイマーによる時間制限も考慮しないといけないため、いきなりの実装はかなりリスキーです。 ✦ ゲームの流れをしっかりとあらかじめ作っておこう 前提条件: 10秒の時間制限がつくことでフローチャートのようなケースになる 10秒刻みのタイマー処理が必要になる ・10秒以内に解答をする必要がある ・ゲームは1セット5問 ・問題はあらかじめアプリの中に設定されている ・5問が終了したらこのゲームのセットを終了する ・途中で前の画面へ戻った場合は全てリセットされる ・10秒になったら不正解として次の問題へ 問題の正解・不正解・選択肢はあらかじめ設定が必要になる ゲーム結果を登録するためのデータベースが必要 戻る際にはタイマーを破棄する必要がある
  9. 9. サンプルとデモの紹介 (まずは是非サンプルをダウンロードして実機で確かめてみて下さい) ゲーム部分の挙動やプログラムの実装部分を前述のフローチャートと合わせて見てみてくださいませ。 ✦ 今回は時間制限付きの4択クイズアプリを作成してみました ① Github(サンプル資料)とQiita(解説資料) https://github.com/fumiyasac/TimerQuiz ② サンプルの使用にあたっての諸注意 ・今回のサンプル 一緒に見ていきましょう! ③ 実際の挙動や操作・詳細な解説に関して ・詳細な解説資料 http://qiita.com/fumiyasac@github/items/18ae522885b5aa507ca3 ・このサンプルはXCode7.3 + Mac OS X 10.11.4 (El Capitan) を使用しています。 ・El Capitan以前の方は正しく動かない可能性がありますのでご注意下さい。 ・問題とオープニングの文言に関してはプロジェクト内のCSVファイルに入っています。
  10. 10. 実際のポイント①:タイマー処理 ✦ NSTimerクラスを使って「時間制限」と「残り秒数の表示」をする �(タイマー処理は以外と簡単にできる) NSTimerのscheduledTimerWithTimeIntervalメソッドの引数に設定できるものを覚えておきましょう。 //タイマーをセットするメソッド func setTimer() { //毎秒ごとにperSecTimerDoneメソッドを実行するタイマーを作成する self.perSecTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(QuizController.perSecTimerDone), userInfo: nil, repeats: true) //指定秒数後にtimerDoneメソッドを実行するタイマーを作成する(問題の時間制限に到達した場合の実行) self.doneTimer = NSTimer.scheduledTimerWithTimeInterval(QuizStruct.timerDuration, target: self, selector: #selector(QuizController.timerDone), userInfo: nil, repeats: true) } //タイマー処理を全てリセットするメソッド func resetTimer() { self.perSecTimer!.invalidate() self.doneTimer!.invalidate() } 10秒刻みのタイマー処理(解答時間の制限) 「あと◯秒」の表示をするためのタイマー処理 ・役割の異なるタイマーを同時に走らせている部分がポイント ・問題を解いた時 / ゲームが終わった時 / 途中でゲームをやめた時にはタイマー処理を全てリセット QuizController.swift内
  11. 11. 実際のポイント②:CSVファイル読込 ✦ 問題文や選択肢の一覧はCSVファイルで管理しておく �(CSVの読み込み方法に関しては覚えておくと便利) 簡易的なデータベースの代わりとしても十分に活用可能。しかしカンマ区切りという点には注意が必要。 //問題を(CSV形式で準備)読み込む let csvBundle = NSBundle.mainBundle().pathForResource("problem", ofType: "csv") //CSVデータの解析処理 do { //CSVデータを読み込む var csvData: String = try String(contentsOfFile: csvBundle!, encoding: NSUTF8StringEncoding) csvData = csvData.stringByReplacingOccurrencesOfString("r", withString: "") //改行を基準にしてデータを分割する読み込む let csvArray = csvData.componentsSeparatedByString("n") //CSVデータの行数分ループさせる for line in csvArray { //カンマ区切りの1行を["aaa", "bbb", ... , "zzz"]形式に変換して代入する let parts = line.componentsSeparatedByString(",") self.problemArray.addObject(parts) } //配列を引数分の要素をランダムにシャッフルする(※Extension.swift参照) self.problemArray.shuffle(self.problemArray.count) } catch let error as NSError { print(error.localizedDescription) } , (カンマ) 区切りなので問題文や文章には注意 データの並び順についてはソースを確認ください。 QuizController.swift内
  12. 12. 実際のポイント③:配列のランダムソート ✦ NSMutableArrayクラスを拡張してメソッドを追加 �(拡張やプロトコル指向のプログラミングに関しては自分もまだまだ勉強している最中) 今回は簡単な機能でこんな風に既存クラスを拡張してメソッドを追加できるよという例を紹介しました。 //NSMutableArrayクラスのshuffleメソッドを実装 extension NSMutableArray { //NSMutableArrayの中身をランダムに並べ替えする処理 func shuffle(count: Int) { for i in 0..<count { let nElements: Int = count - i let n: Int = Int(arc4random_uniform(UInt32(nElements))) + i self.exchangeObjectAtIndex(i, withObjectAtIndex: n) } } } 配列をランダムソートするメソッドがないから追加 cf) PHPだとarray_shuffle() 関数みたいな感じ Extension.swift内 ・拡張はクラスの継承とはまた違った概念になります。 ・今回は簡単な例ですが、色々と使ってみると面白い部分というかSwiftの面白さの部分かと思います。 //既存の型に対してインスタンスメソッドを追加する場合 extension 拡張対象の型名 { //インスタンスメソッドを追加 func メソッド名(引数: 引数の型) { ..色々内容を記述していく } }
  13. 13. 実際のポイント④:ゲームに関する動き ✦ 今回のサンプルアプリでのメソッドが実行される順番について  (正解 or 不正解の判断処理と解答のアクション時のメソッドの流れに注目) 次の問題を表示する or 計算結果を保存して次の画面へ遷移する部分は少し追いにくいかもしれないです。 ※データ構造や並び順はproblem.csvを参照 1. 解答ボタンを押した際の正解・不正解の判定: どの選択肢が正解かのデータについては問題データのCSVファイルに定義してあり、 その部分の番号と突き合わせて判断をする 2. 解答をした場合: judgeCurrentAnswer() 解答ボタンが押される judgeCurrentAnswer() → reloadTimer() → compareNextProblemOrResultView() → createNextProblem() 3. 10秒が経過してしまった場合: 解答しないで10秒経過 timerDone() → reloadTimer() → compareNextProblemOrResultView() → createNextProblem() メソッドが読まれる順番 メソッドが読まれる順番
  14. 14. //登録日順のデータを最新から5件取得をする static func fetchGraphGameScore() -> [Double] { let gameScores: Results<GameScore> = realm.objects(GameScore).sorted("createDate", ascending: false) var gameScoreList: [Double] = [] for (index, element) in gameScores.enumerate() { if index < 5 { let target: Double = Double(element.correctAmount) gameScoreList.append(target) } } return gameScoreList } 実際のポイント⑤:グラフの実装 ✦ ios-chartsを使った実装例 �(グラフのライブラリを知っておくと何かと便利です) データ記録系のアプリでグラフがあると見た目にもカッコよくなるので、導入をしてみると良いかも。 Realmに格納されているデータを5件取得する GameScore.swift内 ・導入後のハウツーの参考:http://www.appcoda.com/ios-charts-api-tutorial/ ・実装部分の参考資料:http://qiita.com/touyu/items/4fbd6d8187eb74752ba0 //グラフに描画するデータを表示する let lineChartDataSet = LineChartDataSet(yVals: dataEntries, label: "ここ最近の得点グラフ") let lineChartData = LineChartData(xVals: xLabels, dataSet: lineChartDataSet) //LineChartViewのインスタンスに値を追加する self.lineChartView.data = lineChartData //UIViewの中にLineChartViewを追加する self.resultGraphView.addSubview(self.lineChartView) ScoreController.swift内 LineChartViewクラスのインスタンスを作成し、 プロパティに成型した値を追加していく。
  15. 15. 仕様決めからボタンやラベル要素の活用の基本・画面遷移からデータ永続化まで一通り実現できますよー ✦ クイズアプリを題材にしての学習はアプリ開発でもかなりよいプラクティス セッションのまとめ ✦ タイマーを利用した時間制限などのアイデアを入れると内容が面白くなる ✦ 画面の遷移や選択肢の出し方、ゲームの流れやロジックに関するものはフローチャー トなどにまとめておくと設計が破綻しにくいのでやっておくこと ✦ 今回はRealm(履歴データ保存)や ios-charts(グラフでの結果表示)などのライ ブラリを活用することでコンテンツの充実&学習にもなります ご静聴ありがとうございました! ✦ タイマー処理についてはNSTimerクラスを活用して制限時間を実現 ✦ クイズアプリは応用の幅も広いのでアイデア次第では大ヒットも!?

×