How to use Swift's logging API
Learn how to log events and errors in your iOS app with Swift's logging API.
25 Mar 2024 · 4 min read
Logging is an essential aspect in software development, enabling developers to track and understand the behavior of their applications.
Swift's logging API is part of the os framework providing different logging levels, categories, persistence, formatting and privacy features.
Let's look at how to use it.

Let's directly jump in and look at the following example:
import oslet logger = Logger()logger.log("Starting video with title \(title, privacy: .public)")
We can log any type confirming to CustomStringConvertable. The log outputs appear in Xcode's console while running the app. With a connected device, we can use the Console.app from the Utilities folder.
Alternatively, we could initialize the logger as follows:
let logger = Logger(subsystem: "someSubsytem", category: "someCategory")
- the subsystem parameter can for example be the bundle identifier of your app.
- the category parameter can be used to structure logs from different parts of the app.
Logging Levels
The API provides five log levels:
The Logger instance provides corresponding methods such as debug, info etc. For example, to log an API error:
logger.error("Missing field \(field) in response from \(endpoint).")
Persistence
Logs are archived to retrieve them later from the device. To browse through persisted messages from your device, connect the device and open Console.app that is preinstalled in the Utilities folder.
Only logs that are persisted can be retrieved after execution. Whether or not a log message is persisted depends on the log level. The Notice, Error and Fault messages are persisted.
Performance
According to Apple, the logging system is very performant, so you can use it widely in your app without slowing it down. Unlike with print, log messages are not fully converted into a string representation. Instead, the compiler and the logging library work together to produce an optimized representation of the log message.
Privacy
Nonnumeric values in your logs are configured as private by default, so they are hidden in the message. This makes sure, that after shipping the app, the logs don't show any personal information. For example:
logger.log("Logging in user with email \(emailAddress)")
The statement above will produce the following log message:
Logging in user with email <private>
If the information you are logging should not be hidden, you have to explicitly mark it as public:
logger.log("Opening video \(videoId, privacy: .public)")
Conclusion
One thing I'm personally missing when comparing the API with third party libraries, is the ability to retrieve all messages from the Logger instance, for example to be able to show the logs directly within the application.



Newsletter
Like to support my work?
Say hi
Related tags
Articles with related topics
Latest articles and tips



