Edited at

MOAspects - SwiftでViewControllerに対してアスペクト的にログを出してみる

More than 3 years have passed since last update.


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型に全部変えたい


追記

Swiftでもdynamicを付けることでObjective-Cランタイム経由になるのでMOAspectsでのAOPが可能とのこと!