Xcode 8.0でOS_ACTIVITY_MODE = disableを指定すると、実機実行時にNSLogが出力されなくなるので注意


【追記】Xcode 8.1 beta2で修正されました

Xcode 8.0でシミュレーター実行時にログノイズが大量に出力されてしまうことは、やはり一時的なバグだったようで、修正されました

‎Xcode 8.1 beta 2 Release Notes

Xcode Debug Console no longer shows extra logging from system frameworks when debugging applications in the Simulator. (26652255, 27331147)

Xcode 8.0での開発中は以下の対処などでしのぎつつ、Xcode 8.1に移行したら速やかにOS_ACTIVITY_MODE = disable指定を消すのが良いかと思います。


Xcode 8.0でシミュレーター実行時にログノイズが大量に出力されてしまうことの対策として、Environment VariablesにOS_ACTIVITY_MODE = disableを設定する方法が、Xcode 8 の不要なログを非表示にする方法 - QiitaやTweetなどで広まっていますが、注意です。

問題は解決するものの、代わりに実機実行時にNSLogが出力されなくなってしまいます

printは出力されるものの、Swift: print() vs println() vs NSLog()などにあるように、printはデバイスコンソールに出力されないので、ログ目的だとNSLog使うことも多いです。

というわけで、まずこの挙動理解していないと、実機実行時にNSLogが出力されずハマることになると思います。

実際にけっこうハマっています:
xcode - iOS 10 doesn't print NSLogs - Stack Overflow

シミュレーターと実機実行時で設定を変える運用

普段、Environment VariablesにOS_ACTIVITY_MODE = disableを設定しておいて、適当に変えれば良いのでは?と思うかもしれませんが、実機実行時のログを無効化している状態で再現難しい系の問題が発生してログを遡れないのは辛いので、きちんとシミュレーターと実機実行時で設定を切り替えたいと思いました。

賢く切り替える方法は無さそうなので、下記のようにapplication(_:didFinishLaunchingWithOptions:)などでassertionかけるしかないかな、という感じです(´・ω・`)

let osActivityMode = ProcessInfo.processInfo.environment["OS_ACTIVITY_MODE"]
let isDisabled = osActivityMode == "disable"
let isSimulator = ObjcHelper.isSimulator()
assert((isDisabled && isSimulator) || (!isDisabled && !isSimulator))

シミュレーターでノイズ出まくるのは許容として、assert(isSimulator || (!isDisabled && !isSimulator))でも良いかもしれません。

シミュレーターかどうかは、以下のコードで判定しています。
(Swiftでも書けないことは無いですが、微妙な書き方しか見つからなかったので、これで判定していました。今改めて探しましたが、やはりObjective-C使った方がマシな感じがしました。)

@interface ObjcHelper : NSObject
+ (BOOL)isSimulator;
@end 
#import "ObjcHelper.h"
@import UIKit;

@implementation ObjcHelper

+ (BOOL)isSimulator {
#if (TARGET_IPHONE_SIMULATOR)
    return YES;
#endif
    return NO;
}

@end 

デフォルトはオフが良さそうです

以下のように思っています。

  • 「Xcode 8でシミュレーター実行時にログノイズが大量に出力されてしまうこと」→ バグ(【追記】Xcode 8.1 beta2で修正されました。)
    • 直り次第、OS_ACTIVITY_MODE = disableの設定は不要になる
  • OS_ACTIVITY_MODE = disableを設定すると実機実行時にNSLogが出力されなくなること」→ 正常動作

なので、shared schemeでバージョン管理している場合、以下の状態でコミットして、必要に応じてオンにするのが良いと思いました。