現状の問題点
Xcodeを使って開発していると、普通であれば開発中のアプリのログを見たくなることが多いと思います。そんなとき、Swift標準の print()
を使ってログを表示しようと、こんな感じのコードを書く人が多いのではないでしょうか。
print("hoge hoge hoge...")
これでも間違っているわけではないですが、この書き方だと実際に表示されるログが、
hoge hoge hoge...
のようになってしまい、正直に言って、とても見やすいとは言えないです。仮にログがこれだけなら問題ないのですが、実際に開発しているとログが1つだけなどという状況になるはずもなく、結果として、
hoge hoge hoge...
hoge hoge hoge...
hoge hoge hoge...
hoge hoge hoge...
hoge hoge hoge...
となり、どのログがどこで吐き出されたものか解らなくなり、ログの場所を見つけるためのログを仕込むという、終わりのないループに陥ってしまうことになりかねません。
というわけで、今回は普段から私が使っているログ出力を軽く紹介していきます。
ちなみに、NSLog()
を使えばいいんじゃね、と思ったあなた。あなたはとても正しいですが、この記事は、せっかくSwiftを使ってるんだからNS系の関数はできる限り使いたくないという人向けですので、予めご了承ください。
作ってみた
参考までにNSLog()
で出力した場合は、こうなります。
2019-12-31 12:00:00.000000+0900 HogeProject[0000:000000] hoge hoge hoge...
はい、とても見やすいですね。なので、なるべくこの形に近づけるようにログ出力を調整していきます。
ではログにどんな情報を乗せるのかを考えていきたいと思います。
NSLog()
を参考にしてみると、
・出力時間
・アプリ名
・メッセージ
といったところでしょうか。
この3つの要素に加えて、
・クラス名
・関数名
・行数
があれば、ログが見やすくなると思うので、今回はそれらを入れていきます。
そして出来上がったのが、こちら
class LogUtil {
/// 日付の出力フォーマット
private static let dateFormat = "yyyy-MM-dd HH:mm:ss.SSSZ"
/// ログ出力
class func log(_ message: String = "", file: String = #file, function: String = #function, line: Int = #line) {
let logMessage = createLogMessage(message, file: file, function: function, line: line)
print(logMessage)
}
/// ログ+エラー出力
class func errorLog(_ message: String = "", error: Error, file: String = #file, function: String = #function, line: Int = #line) {
let logMessage = createLogMessage(message, error: error, file: file, function: function, line: line)
print(logMessage)
}
/// 現在時刻の取得
private class func nowDateTime() -> String {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = dateFormat
return formatter.string(from: Date())
}
/// ログに表示する文字列を生成
private class func createLogMessage(_ message: String, error: Error? = nil, file: String, function: String, line: Int) -> String {
var logMessage = nowDateTime()
if let bundleName = Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String {
logMessage += " [\(bundleName)]"
}
if let swiftFile = file.split(separator: "/").last?.split(separator: ".").first {
logMessage += " [\(String(swiftFile))]"
}
logMessage += " <\(function)>"
logMessage += " [l: \(line)] "
logMessage += message
if let error = error {
logMessage += "\n\(error)"
}
return logMessage
}
}
これでひとまず、目的のログを出力することができるようになります。
使うときは、ログを出力したい箇所で、
LogUtil.log("hoge hoge hoge...")
と呼び出せば、ログが出力されます。
ログの見え方はこんな感じです。
2019-12-31 12:00:00.000+0900 [HogeProject] [HogeViewController] <hogeFunction()> [l: 14] hoge hoge hoge...
どうでしょうか。NSLog()
に近い表現になったと思います。少なくとも、print()
で出力するよりはだいぶ解りやすくなったのではないでしょうか。
#おわりに
以上が私が開発中に使っているログ出力です。もちろん、人によっては不要な情報も出力されているかもしれませんが、ひとつの例として受け取って貰えればと思います。