LoginSignup
12
10

More than 5 years have passed since last update.

Swiftで細かいこと気にせずログを出したい

Last updated at Posted at 2015-02-26

Objective-CとSwiftとの大きな違いの一つとしてマクロの扱いが挙げられます。
そのためマクロ前提のロギングなどのObjective-CライブラリはSwiftでは利用できなくなりました。

ネット上でよく見かける擬似コードは以下のようになります。

func MyLog(message: String, function: String = __FUNCTION__, line: Int = __LINE__) {
#if DEBUG
    println("")//省略
#endif
}

上記の場合、以下の2点が気になります。

  1. DEBUGではない場合もmessageが評価される
    • MyLog("\(fibonacci(100))")のような重い処理が表示されなくても実行されてしまう
  2. MyLog(1, 2, "3")のように複数の値を同時に表示することができない

1の対策

Swiftのassert関数のように@autoclosureで包み込む

func MyLog(message: @autoclosure () -> String, _ function: String = __FUNCTION__, _ line: Int = __LINE__) {
#if DEBUG
    println("\(message())")//省略
#endif
//DEBUGではない場合、message内部は評価されない
}

2の対策

こちらはGenericsとオーバーロードの力技で対応します。

func MyLog<T>(message: T, _ function: String = __FUNCTION__, _ line: Int = __LINE__) {
#if DEBUG
    println("")//省略
#endif
}


func MyLog<T1, T2>(t1: T1, _ t2: T2, _ function: String = __FUNCTION__, _ line: Int = __LINE__) {
    MyLog((t1, t2), function, line)
}

func MyLog<T1, T2, T3>(t1: T1, _ t2: T2, _ t3: T3, _ function: String = __FUNCTION__, _ line: Int = __LINE__) {
    MyLog((t1, t2, t3), function, line)
}

//以下、必要な個数分続く

MyLog(1) //MyLog<T>(...)が呼ばれる
MyLog(1, "2") //MyLog<T1, T2>(...)が呼ばれる

1はともかく2は単純に手間なので、それらを踏まえ実装した自作ライブラリがこちらになります。

LoggingKit

Swift1.1の記法に対応しました。
LoggingKit tag:swift/1.1

使い方

AppDelegate.swift
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

#if DEBUG
    LOGGING_VERBOSE() //デバッグ時は全てのログを表示
#endif
}
Logging.e(someError)

let v: String! = nil
Logging.v(1, "2", 3.0, v, Optional(5)) //(1, 2, 3.0, nil, 5)

補足

Swift1.2 Beta1で作成しているためSwift1.1では今のところ利用できません。
週末にSwift1.1に対応したいと思います。

12
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
10