NSLog — Devil Behind It

Kerim Njuhovic
3 min readJul 5, 2018

NSLog is a great and most common iOS developer tool that is used to debug apps. It can be used to check network requests and its responses, check value of the variables or log any notes you need.

Even though it is handy tool, it is far away from being perfect. Some of the downsides:

  • it is slow, in other words it is synchronous. Try to log one big string 😈, it might lead to app crash because of the main thread being blocked
  • no log levels, it is difficult to differentiate between warning, error or simple debug information
  • no remote access, it works only when you have physical device attached

Overall, it is not bad, right!? But, what if I say that NSLog might lead to data leakage? 😱

NSLog does not only print the log information to Xcode console, but also sends the message to global system log (i.e. ASL, more information about Apple System Log you can find here). ASL offers ability to make queries to search existing data (unfortunately, it is deprecated as from macOS 10.12). In general, NSLog represents fusion of the syslog and printf. Data logged through NSLog could be retrieved by anyone who is in posession of physical device.

Data logged through NSLog remain on the device until it is rebooted. Furthermore, logs are not bounded with application sandbox, which means that logs can be read between the apps. 😈

So, without any tricks, connect your iOS device and open Xcode. Go to Window > Devices and Simulators > View Device Logs

What is even more “scary” is that you could read ASL for any app from your device programatically. There are even few paid application out there on the AppStore which offers reading the logs from the device.

With some looking around the web and playing with C language code, the result is here — printing all the logs coming from Xcode application (you can insert the name of the app you want to look for logs, instead of “Xcode”)

So, in order to avoid some future hackers to possibly steal the confident information from your app, you can disable the NSLog for production builds but still enjoy in log informations while you develop 😎.

  • Step 1 (create *.pch file)

If you do not have already .pch file, go to File > New File > PCH File (under the section Others)

PCH file is Pre-Compiled Header file. It stands there for making compiling faster. Instead of parsing the file over and over it gets parsed once, ahead of time.

  • Step 2 (defining PCH for project)

Go to Project Settings > Build settings. Search for prefix header and add following line

$(SRCROOT)/$(PRODUCT_NAME)/<nameOfFile>.pch

$(SRCROOT) — stands for the path of your Xcode project
$(PRODUCT_NAME) — name of the folder of your project.

  • Step 3 (redefening NSLog)

Add in your .pch file following

#ifndef DEBUG
#define NSLog(...)
#endif

In case the DEBUG flag is undefined in release mode, it will be redefined as nothing to be run. Xcode by default defines the DEBUG flag for debug build (check this by going to Project Settings > Build Settings tab > Preprocessor Macros and verify you see the DEBUG=1 is only set for Debug mode.

So, be careful next time and use NSLog with caution balancing between how often you log the info and whether you will need that logged data. Or at least, disable it on your release app. Happy coding 🐵

--

--