Of course, there is a newer LoggerAPI since iOS 14. But maybe, you can not yet set iOS 14 as a minimum version yet since it was just released in 2020.
There are some reasons why you may not want to log anything or not log certain messages in your released (aka production) builds, even if you use the privacy features of the os_log API.
Apple has thought about this topic so there is a great deal if ways to prevent sensitive data being leaked through logging already. For some reason, you might end up logging a password or, more likely, a user-specific API token. The best practice is probably not to do this at all, but if you just have to at least for a while during development, then it will still be better to do this in a way where if you forget to remove that log statement from your code, it will not be a catastrophe or where you could even leave it there without leaking sensitive info to the log.
So you could start off like this:
let apiToken = API.token(user: "johnny@example.com")
os_log_debug(OS_LOG_DEFAULT, "Obtained API token: %@.", apiToken)
This may however expose the API token. The user could for example attach their Mac to the phone, view the logs and then they see the API key. Theoretically, this should not give you goosebumps, but consider that malware could also do this and steal the API token.
That is why Apple introduced this extension:
os_log_debug(OS_LOG_DEFAULT, "Obtained API token: %{private}@.", apiToken)
Now, the API token will only show up in Xcode’s logger, but not to the macOS Console application. You can only see the API token while debugging your own app with Xcode, but not in production and somebody else than your dev team can not see the tokens. Instead of the API token, they will see a message like this in the log:
Obtained API token: <private>.
If you want to make reverse engineering harder, you may stop logging certain messages at all, even if it is now about runtime data like API tokens. So you might want to not log the steps that an app goes through at all in production to make it impossible for someone to simply start up the Console app and see what your app does. This of course does not prevent anyone from disassembling your code, but at least it switches off an easier variant of that.
In the os_log methods, you can specify which log you want to use. One use case of that is having multiple logs for different parts of your app. Now if you give os_log the special log constant OSLog.disabled it will simply disable the logging.
So to deactivate the production logging entirely you basically have to ensure that you always plug OSLog.disabled into os_log for your production builds. One way is to use Swift’s compiler macros aka Active Compilation Conditions.
So you could end up having a global function like
func customLog(_ category: String) -> OSLog {
#if DEBUG
return OSLog(subsystem: Bundle.main.bundleIdentifier!, category: category)
#else
return OSLog.disabled
#endif
}
and then you can use the OSLog returned from that function in all your logs.
In the Build Settings in Xcode you then specify DEBUG in the Active Compilation Conditions for the appropriate builds et voila. No more log messages in your production builds.