SwiftでViewControllerに対してアスペクト的にログを出してみる
前回こんな記事を書いた
単純に呼べば使えるAOPライブラリMOAspectsを作った
http://qiita.com/__moai/items/efcd43016b9320cf6d63
このライブラリ自体Objective-C製なのでSwiftで使いづらいという課題があったのだけど、実はSwift用のインターフェース対応ということで2.0.0にバージョンを上げたので報告(ステマ)
MO-AI/MOAspects
https://github.com/MO-AI/MOAspects
MOAspectsのインターフェース
Objective-Cのときと同じで単純に下の二つだけ
インスタンスメソッド
MOAspects.hookInstanceMethodForClass(①CLASS, selector:②SEL , position:③POSITION) {
// ④HOOK
}
クラスメソッド
MOAspects.hookClassMethodForClass(①CLASS, selector:②SEL , position:③POSITION) {
// ④HOOK
}
必要なパラメータ
①CLASS
処理をフックしたいクラス
②SEL
処理をフックしたいクラスの持つフックしたいメソッド名
③POSITION
.Before
と.After
があり、フックの処理を前か後のどちらに置くかを選べる
④HOOK
フックしたときに実行する処理
実際に使って見た
仮定として以下の3画面のViewControllerをフックして画面の表示タイミングでログを出すのを例とする
- HogeViewController
- FugaViewController
- PiyoViewController
書くのはこれだけ
var classes: [AnyClass] = [HogeViewController.self, FugaViewController.self, PiyoViewController.self]
for viewControllerClass in classes {
MOAspects.hookInstanceMethodForClass(viewControllerClass, selector:"viewDidAppear:", position:.After) {
var className = NSStringFromClass(viewControllerClass)
NSLog("did appear \(className)")
}
}
やってることは画面のクラスの配列を用意してループで該当クラスのviewDidAppear:に対してフックをかけている
すると以下のようなログが出る
did appear PROJECT.HogeViewController
did appear PROJECT.FugaViewController
did appear PROJECT.PiyoViewController
課題
- Objective-Cと違いAnyObject型(id型)にクロージャが入らないので、メソッドのパラメーターの値をフック時にvoidポインタ型、パラメータの個数を0〜9決め打ちで受け取るようにしている、動的・Any型に全部変えたい
追記
'dynamic' keywordは完全に見落としてたなぁ、これでSwiftでもAOPできる! https://t.co/EJyv0bu3Yq
— MOAI (@__moai) 2015, 4月 9
Swiftでもdynamicを付けることでObjective-Cランタイム経由になるのでMOAspectsでのAOPが可能とのこと!