PIYO - Tech & Life -

iOSでデバッグ実行できないときにプリントデバッグする方法

iOS Swift

iOSアプリの開発において、デバッガーをアタッチできないときのデバッグは骨が折れます。その最たる例がPush通知から起動するときだと個人的には思います。

アプリが起動していない状況から起動するときに挙動を検証する際には、そもそもアプリが起動しておらずプロセスが存在しないためデバッガーをアタッチすることもできません。

そこでせめてもの抵抗でprintデバッグをしようと組み込みのprint関数でログを出してみるのですが、実機ログをみると色々なログがごちゃまぜになっていて必要なログだけに絞り込むのがなかなか難しいです。

この際作っちゃろかと一瞬思ったんですが、ちょっと調べたらすぐに見つかったんでそれを使いました。

ログを記録するクライアントライブラリと、それを受け取るサーバーをセットで使います。

自分のローカル環境だけ、しかも一時的に使えれば良いという前提で今日の話をします。

ログを受け取って標準出力に出すサーバー

rubyで書かれた、rack-http-loggerなるものを使えます。後述するiOS側のクライアントアプリと同じ人が書いてて、すぐ使えます。

GitHub - mattt/rack-http-logger: Log metrics from HTTP request parameters according to l2met conventions
Log metrics from HTTP request parameters according to l2met conventions - GitHub - mattt/rack-http-logger: Log metrics from HTTP request parameters according to l2met conventions
% git clone https://github.com/mattt/rack-http-logger
% cd rack-http-logger/example
% bundle install
% thin start

これでlocalhost:3000にサーバーが立ち上がります。

ログを記録するためのクライアントライブラリ

Antennaというライブラリを使います。cocoapodsで導入可能。

GitHub - mattt/Antenna: Extensible Remote Logging for iOS
Extensible Remote Logging for iOS. Contribute to mattt/Antenna development by creating an account on GitHub.

すごく古いですがちゃんと使えます。

Podfileにpod "Antenna"と書いてpod installします。

で、AppDelegate.swiftに初期化処理を書いておきます。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
  // さきほどのサーバーを指定
  Antenna.sharedLogger()?.addChannel(with: URL(string: "http://localhost:3000")!, method: "LOG")

  // 略
}

初期化後は必要な箇所でメッセージを渡して呼び出せばOK。

Antenna.sharedLogger()?.log("記録したいメッセージ")

さっきthin startしたコンソールに次のようなログが出ているかと思います。

source=rack-http-logger locale=ja_US message=記録したいメッセージ uuid=xxxxxxxxxxx

実際こんな感じで流れてきます。

これらを使えばデバッガーをつなぐことができなくても、変数をある程度確認したり、想定通りのコードを通るかどうかを確認したりできるわけです。

だいぶ古いツール郡なので新しいのがありそうだと思うのと、これだけシンプルな使い方しかしないならもっと簡単に作れてもいいんじゃないかと思ったりしています。

RELATED

SwiftでJSのsetTimeoutみたいなことをする

iOSで仕方なく少し待ってから処理を実行するてのを時々やりたくなるんですが、毎度書き方を忘れるので、自分用にメソッドを定義して使っています。 どこかグローバルなところに定義しとくとアプリ全体で使えるので

UIImageの明るさをCIFilterで調整するSwiftコード

CIFilterを使う CIColorControls inputBrightnessに値を設定 値は−1.0〜1.0 import CoreImage extention UIImage { func adjustBrightness(brightness: Double) -> UIImage? { let ciImage = CIImage(cgImage: self.cgImage!) let filter = CIFilter(name: "CIColorControls") filter?.setValue(ciImage, forKey: kCIInputImageKey) filter?.setValue(brightness, forKey: "inputBrightness") guard let newCIImage = filter?.outputImage else { return nil } let context = CIContext(options: nil) guard let cgImage = context.createCGImage(newCIImage, from: newCIImage.extent) else { return nil } return UIImage(cgImage: cgImage, scale:

Swiftデバッグビルドでの最適化オプション

React Nativeで使うために高速フーリエ変換のためのコードをJSで書いていたんですが、色々とあってiOSネイティブで作り直してみるということがありました。 同様のコードをSwiftに移植して、さぞ速くなる