TOKOROM BLOG

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

Swiftのextensionでstored Propertyを追加する?(黒魔術は閉じ込める) はてなブックマーク - Swiftのextensionでstored propertyを追加する?(黒魔術は閉じ込める)

Permalink

extensionでstored propertyを追加したくなることありますか?

少なくともSwift 2.1時点ではextensionでstored propertyを追加することはできず、computed propertyのみに限られます。

でも、ヤダヤダ!ぼくは絶対stored property追加したいんだい!ってことありますか?

そう思っちゃうあなた、他に解決方法ありますよね?なんでそのやりかたにこだわるんですか?そういう思考になっちゃう時点でまだSwift脳に至ってはいないのではないでしょうか(建前)。

なお、ぼくはどうしても追加したんだい!ってことがあります(本音)。

Swiftでdeinitまで処理をdeferする はてなブックマーク - Swiftでdeinitまで処理をdeferする

Permalink

deferしてますか?

Swift2でみんな大好きdeferさんが導入されましたね!

guardと違いそんなに使う機会は訪れていないのですが、昨日、こんな感じで使いたい!という場面に遭遇しました。

CocoaLumberjackを使ってデバッグ用にUITextViewにログを吐くCustom Loggerを設定していたのですが、とあるViewControllerだけでそれを使いたく、ViewControllerがdeinitされたらそのCustom Loggerも当然外したい。

そんなコードを書く場合、defer大好きっ子ならCustom Loggerを登録した後にこんな感じで解除したくなりますよね(実際は僕はこのとき初めて実験でないところでdeferを使ったので、本当のdefer大好きっ子はこんな間違いはしないだろう)。

1
2
3
4
5
6
let logger = TextViewLogger(textView: textView)
DDLog.addLogger(logger)

defer {
    DDLog.removeLogger(logger)
}

defer使って、必要なくなったら漏れなくCustom Loggerを解放する俺様は超カッコいいぜ!と言いたかったのだが、当然のごとくこのコードは間違っていて、これを実行し終わるときにはdeferした処理も実行されて登録したCustom Loggerが即解除されるというお馬鹿な状況になるわけです。

でもdeferしたいよね?

とお馬鹿な前置きは置いておいても、上のような雰囲気で終処理書けたら便利な気はする。 普通にdeinitでやれば済む話なんだけど、今回のケースだとpropertyにloggerをもたせて、deinitloggerがあればremoveLoggerする的なことを書かないといけない。まあ普通のことではあるんだけど、できたら、

1
2
3
4
5
6
let logger = TextViewLogger(textView: textView)
DDLog.addLogger(logger)

deferToDeinit {
    DDLog.removeLogger(logger)
}

と、deinitまで処理を遅延させる的な書き方できたら面白いよね、ということで…

El CapitanでTotalTerminalが動かないならAppleScriptで代用すればいいじゃない? はてなブックマーク - El CapitanでTotalTerminalが動かないならAppleScriptで代用すればいいじゃない?

Permalink

El CapitanにしたらTotalTerminalが動かない!

Twitter上でもよくこの話題が出ていて、多くの人はiTerm2に移管しているようです。

しかし、ぼくは長年愛した(普通の)Terminalちゃんをそう簡単に捨てることはできないのです!

もともとTotalTerminalはTerminalの表示をカッコよくトグルするために使っているわけで、TotalTerminalというよりはTerminalちゃんをそのまま使いたいわけです。 (実際のところiTerm2を試してないので、iTerm2の良さについては全くの無知です)

であれば、そんなトグルくらいならAppleScriptで軽やかにできるはず!ぼくのAppleScriptでTerminalちゃんを救ってみせる! と思いたって試してみました。 (実際のところAppleScriptに無知すぎて全く軽やかにはできなかったわけですが、結果自体はシンプルです)

以下、試したことをまとめます。

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に書かれている話です