元ネタ
Javaの講義、試験が「自作関数を作り記述しなさい」って問題だったから
— てくも (@kumiromilk) 2016年3月9日
「ズン」「ドコ」のいずれかをランダムで出力し続けて「ズン」「ズン」「ズン」「ズン」「ドコ」の配列が出たら「キ・ヨ・シ!」って出力した後終了って関数作ったら満点で単位貰ってた
ReactiveCocoaで書くまで
しばらくReactiveCocoa使っていなくて、Swift版の勉強のために書いてみました。まずはPlayGroundでReactiveCocoaを簡単に使うWorkSpaceを作ったことがなかったので、それに取り組みました。 @bricklife さんの
ズンドコキヨシ with RxSwift - Qiitaのエントリーを見て、GitHubのリポジトリをダウンロードしてみると、RxSwiftの環境がCarthage update
で簡単に作成できるので、これをやりたいと思いました。
おなじにようにCartfileを作って、carthage update
しても同じようにリンクを作れなくて、おかしいなと思ったら、carthageはバイナリでダウンロードする機能ができたのですね。そのため、プロジェクトをWorkSpaceに取り込むことができませんでした。
以下の方法で出来ます。
carthage update --no-use-binaries
要するに、バイナリを使用せず、コードをダウンロードするようにということです。その代わりビルドにすごく時間がかかりました。コードをダウンロードできれば、そのプロジェクトをWorkSpaceに取り込んで、スキームをReactiveCocoa-Mac>MyMacにして、一度ビルドすれば使えるはずです。
tomohisa/reactive_cocoa_zundokoでGitHubに公開しましたのでぜひ使ってみてください。
ReactiveCocoaでの実装
すでに ReactiveCocoaでズンドコキヨシ - Qiita で @rizumita さんがReactiveCocoaで実装していたのですが、ストリームの流れがもう少し自然にできるかなと思って、作ってみました。
import Foundation
import Result
import ReactiveCocoa
enum Zundoko: UInt32 {
case ズン
case ドコ
}
timer(0.5, onScheduler: QueueScheduler())
.map {
_ in Zundoko(rawValue: arc4random_uniform(2))!
}.on(next: {
print($0)
}).scan([]) { (array, value) in
Array(array + [value]).suffix(5)
}.takeWhile { $0 != [.ズン, .ズン, .ズン, .ズン, .ドコ] }
.startWithCompleted {
print("キ・ヨ・シ!")
}
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
基本の流れは @bricklife さんの最初のものとほぼ同じで、後、ReactiveCocoaの使い方は @rizumita さんのを参考にさせていただきました。
- timer - 0.5秒ごとに時間をおくる
- map - ランダムでズンかドコを生成
- on - プリントする
- scan - 直近5個をまとめた配列に変換
- takeWhile - 終了条件を満たすか判断
- startWithCompleted - SignalProducerからスタートしてSignalを生成し、Completedイベントでキヨシとプリントする
の流れとなっています。
コードの最後の2行はPlayGroundでコードの継続実行を許可する方法です。これをしないとコードが逐次終了してしまいます。PlayGroundで、アプリ上やターミナルではなくて、開発環境のコンソールでテストできるのいいですね。
ReactiveCocoa / RxSwift
これを見て思ったのは、Swift良くなったなと。以前ReaciveCocoa Swift版が出た頃は
->
で無理やりつないだりして、きれいでなかったですが、今は書き方もきれいですし、配列の比較なども簡単にできるようになったので、きれいに書けるようになりました。Enumをprintで文字としてプリントできるのも嬉しいですね。あと、ReacriveCocoaとRxSwiftのコードを見比べてみると、RxSwiftはSignalProducer - Signalを気にしないでいい分、シンプルにかけている気がします。新規プロジェクトだったらRxSwiftでもいいかなと思いました。
課題
ズンドコキヨシ with RxSwift 最終版と試行錯誤の歴史 - Qiitaのように書くところまでできなかったので、もうちょっとやってみたいなと思います。