タイトル
Game Programming Patterns ソフトウェア開発の問題解決メニュー (impress top gear)
著者
Robert Nystrom (著), 武舎 広幸 (監修), 阿部 和也 (翻訳), 上西 昌弘 (翻訳)
出版社
インプレス
Amazonで購入する

読了。後で書く。

タイトル
ゲームデザイナーのための空間設計 歴史的建造物から学ぶレベルデザイン
著者
クリストファー・トッテン (著), Christopher W. Totten (著), 渡邉 淳矢 (編集), 株式会社Bスプラウト (翻訳)
出版社
ボーンデジタル
Amazonで購入する

読了。後で書く。

CoreLocation を使って iBeacon の Ranging を行う場合、iOS だと 1秒間隔で通知されます。

[参考] iBeacon(3) - リージョン監視とレンジング - Enamel Systems

そこで、1秒間隔だと通知間隔が短すぎるので、5秒間隔とか1分間隔とかに変えたい時にどうするかですが、CLLocationManager クラスに設定があればよかったのですが、特になさそうなので、RxSwift を使ってストリームのフィルタで対応する方法のメモです。

CLLocationManager の初期設定とかは参考サイトを見てください。

ReactiveX/RxSwift

1
2
3
4
5
6
locationManager.rx_didRangeBeaconsInRegion
    .sample(interval(5, MainScheduler.sharedInstance))
    .subscribeNext { (tuple: ([CLBeacon]!, CLBeaconRegion!)) in
        debugPrint("beacons: \(tuple.0), region: \(tuple.1)")
    }
    .addDisposableTo(disposeBag)

Rxsample を使って、ストリームを interval 毎にサンプリングしてやるだけです。

Time-shifted sequences - Introduction to Rx

RxSwift も使いやすくて、めっちゃ便利です!

ReactiveCocoa が v.3.0-RC.1 がでて、そろそろ製品に Swift で ReactiveCocoa が使えるようになりそうな感じになってきました。

いつも Signal を自分で制御するイディオムを忘れてしまうので、メモ書きです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import Foundation
import UIKit
import ReactiveCocoa

class MyViewModel {
    let (changed, sink) = Signal<Void, NoError>.pipe()

    func doAction() {
        // do something
        sendNext(sink, ())
    }
}


class MyViewController : UIViewController {
    let viewModel = MyViewModel()

    override func viewDidLoad() {
        super.viewDidLoad()

        viewModel.changed |> observe(next: debugPrintln)

        viewModel.doAction()
    }
}

Swift のメモ書きです。

ankurp/Dollar.swift という JavaScript の Lo-Dash や Underscore と同じ感じでコレクションを扱うためのライブラリがありますが、 each が配列しか受け付けることが出来ないので、SequenceType を受け取れるように拡張する方法のメモです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import Dollar

extension $ {
    class func each<T: SequenceType>(array: T, callback: (T.Generator.Element) -> ()) -> T {
        for elem in array {
            callback(elem)
        }
        return array
    }
}

$.each(["a", "b", "c"]) { (s: String) in println(s) }
$.each(["key": "val"]) { (e: (String, String)) in println("\(e.0) = \(e.1)") }
// a
// b
// c
// key = val

Array に each を実装してみた。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
extension Array {
    func each(block: (T) -> ()) {
        for item in self {
            block(item)
        }
    }

    func each<U>(block: (U) -> ()) {
        for item in self {
            block(item as! U)
        }
    }

    func eachWithIndex(block: (T, Int) -> ()) {
        for (i, item) in enumerate(self) {
            block(item, i)
        }
    }

    func eachWithIndex<U>(block: (U, Int) -> ()) {
        for (i, item) in enumerate(self) {
            block(item as! U, i)
        }
    }
}

使い方はこんな感じ。

1
2
3
4
[1, 2, 3].each { (n: Int) in println(n) }
[1, 2, 3].each { println($0) }
[1, 2, 3].eachWithIndex { (n: Int, i: Int) in println("index \(i), n \(n)") }
[1, 2, 3].eachWithIndex { println("index \($1), n \($0)") }

配列の中身が AnyObject だった時に、型指定するときとしない時でどっちも動くようにするのに、メソッドを2つ定義しました。

このへん、Generics の達人のかたに、もっといい書き方あるよって教えて欲しいです。

Swift の Dictionary に map を実装してみた。

ついでに reduce も。

1
2
3
4
5
6
7
8
9
extension Dictionary {
    func map<T>(transform: (Key, Value) -> T) -> [T] {
        return Swift.map(self, transform)
    }

    func reduce<T>(initial: T, combine: (T, (Key, Value)) -> T) -> T {
        return Swift.reduce(self, initial, combine)
    }
}

使い方はこんな感じ。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var dict = [String: String]()
dict["hello"] = "world"

let array = dict.map { (k: String, v: String) -> String in
    return v
}
println(array)      // ["world"]


dict = [String: Int]()
dict["a"] = 1
dict["b"] = 2
dict["c"] = 3
dict["d"] = 4
dict["e"] = 5
let n = dict.reduce(0) { (n, d) -> Int in n + d.1 }    // 15

Ruby の map っぽい感じで使えるにしたかったので。