TOKOROM BLOG

iOSとかVimとかその他日々の雑多な技術情報

SwiftTask、PromiseKit、Boltsを比較する(2015年3月版) はてなブックマーク - SwiftTask、PromiseKit、Boltsを比較する(2015年3月版)

Permalink

  • ※2015/3/11時点での比較結果ですので、今後、各ライブラリともにパワーアップしていくと思われます
  • ※いまはできないことでも各ライブラリのIssuesでは実装の検討が進んでいるものも多くあるようです

次の案件で(Swiftで)Promiseライクなフロー制御を実現するために利用するライブラリを選定するため、2015/3/11時点の

を(表面だけ)使って比較してみました。

なお、昨年の7月時点では(Swiftで使うぶんには)PromiseKitが将来性があると判断し、しばらくはPromiseKitを使っていました。

その後、SwiftTaskも登場して気になっていたので、今回改めて新案件で採用するライブラリを選定したという経緯になります。

以下にそれぞれ使ってみた結果を紹介させていただきます。

AlamofireでGenericにModelオブジェクトを取得する はてなブックマーク - AlamofireでGenericにModelオブジェクトを取得する

Permalink

※この記事のコードはXcode 6.3 beta(Swift 1.2)で試しています

Swiftいいですね!

これまでSwiftの案件を2つほどやってきたのですが、どちらも開発スタートが2014年7月だったため新しめのSwiftライブラリもリスクが高そうで、利用できるライブラリはある程度限定されてしまいました。 例えば、Alamofire のInitial Commitも2014/7/31だったりと。。。

今となっては(2015年3月)Swift公開から早9ヶ月が経過しており、ライブラリの選択肢もだいぶ広がりました。 また、まだSwiftのライブラリを管理する環境もだいぶ整ってきました(ちょうど本日3/11にCocoaPodsのDynamic Framework対応版が公開されました!)。

ということで、3月からはじめる新案件ではAlamofireの採用を決め、APIアクセスまわりのインターフェースをいろいろと検討してみました。 やはりSwiftを使うからには、Genericsを使ってModelオブジェクトに変換された状態のレスポンスを受け取れるインターフェースになっていて欲しいですよね!

※基本的にはAlamofireのREADMEに書かれている話です

NSTimeZoneから取得できる表示用文字列のサンプル はてなブックマーク - NSTimeZoneから取得できる表示用文字列のサンプル

Permalink

さっき、画面上に現在設定されているTime Zoneを表示するって機能を実装していたのですが、NSTimeZoneからどういう文字列が取れるかのサンプルが意外と見つからなかったのでメモします。

abbreviation

1
GMT+9

name

1
Asia/Tokyo

description

1
Asia/Tokyo (GMT+9) offset 32400

localizedName(_:locale:)

NSLocale NSTimeZoneNameStyle 出力結果
en_US Standard Japan Standard Time
en_US ShortStandard GMT+9
en_US DaylightSaving Japan Daylight Time
en_US ShortDaylightSaving GMT+9
en_US Generic Japan Standard Time
en_US ShortGeneric Japan Time
ja_JP Standard 日本標準時
ja_JP ShortStandard JST
ja_JP DaylightSaving 日本夏時間
ja_JP ShortDaylightSaving JDT
ja_JP Generic 日本標準時
ja_JP ShortGeneric JST

上記を試したコード

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
let timeZone = NSTimeZone.systemTimeZone()

println("#### abbreviation, \(timeZone.abbreviation)")
println("#### name, \(timeZone.name)")
println("#### description, \(timeZone.description)")

let en = NSLocale(localeIdentifier: "en_US")
println("#### Standard, \(timeZone.localizedName(.Standard, locale: en))")
println("#### ShortStandard, \(timeZone.localizedName(.ShortStandard, locale: en))")
println("#### DaylightSaving, \(timeZone.localizedName(.DaylightSaving, locale: en))")
println("#### ShortDaylightSaving, \(timeZone.localizedName(.ShortDaylightSaving, locale: en))")
println("#### Generic, \(timeZone.localizedName(.Generic, locale: en))")
println("#### ShortGeneric, \(timeZone.localizedName(.ShortGeneric, locale: en))")

let ja = NSLocale(localeIdentifier: "ja_JP")
println("#### Standard, \(timeZone.localizedName(.Standard, locale: ja))")
println("#### ShortStandard, \(timeZone.localizedName(.ShortStandard, locale: ja))")
println("#### DaylightSaving, \(timeZone.localizedName(.DaylightSaving, locale: ja))")
println("#### ShortDaylightSaving, \(timeZone.localizedName(.ShortDaylightSaving, locale: ja))")
println("#### Generic, \(timeZone.localizedName(.Generic, locale: ja))")
println("#### ShortGeneric, \(timeZone.localizedName(.ShortGeneric, locale: ja))")

SwiftでiOSシミュレータのときだけAFNetworkActivityLoggerを使う はてなブックマーク - SwiftでiOSシミュレータのときだけAFNetworkActivityLoggerを使う

Permalink

だいぶ小ネタ。

コード

1
2
3
4
#if (arch(i386) || arch(x86_64)) && os(iOS)
    AFNetworkActivityLogger.sharedLogger().level = .AFLoggerLevelDebug
    AFNetworkActivityLogger.sharedLogger().startLogging()
#endif

UIDeviceを使う方法もあるが、そちらは実際に動いたときに判別することになる。
こちらだとそもそもiPhone用のアプリからはこのコード自体省かれる形になる。

意味

  • arc(i386)
    • 32bitのMac(シミュレータ)用のビルド
  • arc(x86_64)
    • 64bitのMac(シミュレータ)用のビルド
  • os(iOS)
    • ターゲットがMacじゃなくてiOS

オマケ

ぼくの手元では、デバッグ実行時に

1
2
3
#if DEBUG
    println("DEBUG")
#endif

DEBUG が出力されない。普通は出力されるはず??

Swiftで部分適用(カリー化) はてなブックマーク - Swiftで部分適用(カリー化)

Permalink

Swiftオフィシャルの部分適用

まず、Swiftオフィシャルな構文として

1
2
3
func addTwoNumbers(a: Int)(b: Int) -> Int {
  return a + b
}

というように引数を1つ1つ別の括弧で囲ってfunctionを定義すると

1
2
let add1 = addTwoNumbers(1)
add1(b: 2) //< 3

というかんじに、

  • まず、1つめの引数だけ部分適用(ここでは a
  • 部分適用したものに後から次の引数を適用(ここでは b

というのができる。

専用の書き方じゃなくてふつうのfunctionに部分適用できないの?

使うかどうかは別としてHaskellみたいに全ての関数に部分適用できたら面白いなーと。

また、上のような専用の定義にしちゃうと addTwoNumbers(1, 2) みたいな普通の呼び方ができなくなっちゃうし。

そんなとき、 Swiftの関数の引数は、常に一つ という記事に出会い、勉強になるなーと眺めていたら、あれ?ふつうのfunctionに部分適用するための関数作れるかもなーと思い立った。

実装

https://github.com/tokorom/partial-swift

1
2
3
func partial<A, B, R>(function: (A, B) -> R, a: @auto_closure () -> A) -> (B) -> R {
    return { function(a(), $0) }
}