
A Comprehensive Guide to Logging on iOS: From print to Logger

Logging is a fundamental part of iOS development, helping developers debug, monitor, and maintain their apps. Over the years, Apple has introduced several logging APIs, and the community has created powerful open-source alternatives. In this article, we’ll cover the evolution of iOS logging, from print
and NSLog
to os_log
, Logger
, and popular open-source frameworks like CocoaLumberjack. Each section includes code examples, pros, and cons.
1. print (Swift) and NSLog (Objective-C)
print is the simplest way to log messages in Swift. It prints to the Xcode console and is great for quick debugging.
print("Hello, world! Value: \(myVar)")
NSLog is the Objective-C equivalent, and is still available in Swift. It automatically adds a timestamp and outputs to both the Xcode console and device logs.
NSLog("This is a log message: %@", myVar)
- Advantages: Simple, no setup, works everywhere, visible in device logs.
- Disadvantages: No log levels, no filtering, not suitable for production diagnostics,
print
output is not timestamped or persisted.
2. os_log (iOS 10+)
Introduced in iOS 10, os_log provides structured, performant logging with support for log levels, privacy, and log filtering in Console.app. It’s the modern standard for most apps prior to iOS 14.
import os
let log = OSLog(subsystem: "com.example.app", category: "network")
os_log("Network request started", log: log, type: .info)
- Advantages: Fast, supports log levels, privacy, and filtering. Logs are visible in Console.app and can be persisted.
- Disadvantages: API is verbose, string interpolation is limited, and the API is deprecated in favor of
Logger
in iOS 14+.
3. Logger (iOS 14+)
Logger is the modern Swift logging API, introduced in iOS 14. It improves on os_log
with a more Swift-friendly interface, better string interpolation, and the same performance and privacy features.
import os
let logger = Logger(subsystem: "com.example.app", category: "network")
logger.info("Network request started for user \(userId)")
The logger supports a variey of different functions to express different log levels.
logger.debug("Debug message")
logger.info("Info message")
logger.notice("Notice message")
logger.warning("Warning message")
logger.error("Error message")
logger.critical("Critical message")
The benefit of this is a much more readable and concise way to log and understand messages.
In XCode each function will be shown with a different color in the console. Also it is possible to filter logs by level in the console.
One more notable feature of Logger if the ability to automatically filter out security sensitive information.
logger.info("Network request started for user \(userId, privacy: .private)")
To output different data types in the best possible way the Logger also comes with multiple formatting options. This helps with numbers, durations, dates and more.
logger.info("Fetched \(count, format: .number) items in \(duration, format: .fixed(2))s")
- Advantages: Modern, Swift-native, supports log levels, privacy, and filtering. Great for production diagnostics.
- Disadvantages: iOS 14+ only, logs are not persisted by default (use Console.app or log collection tools).
4. Open Source: CocoaLumberjack
CocoaLumberjack is a popular open-source logging framework for Objective-C and Swift. It supports log levels, file logging, custom log formats, and asynchronous logging.
import CocoaLumberjackSwift
DDLogInfo("User logged in successfully")
- Advantages: Highly configurable, supports file logging, log rotation, custom formats, and works on older iOS versions.
- Disadvantages: Adds a dependency, more setup, and not as tightly integrated with Apple’s logging tools.
5. Other Notable Mentions
- SwiftyBeaver: Color-coded logs, cloud logging, and integrations for Slack and more.
- XCGLogger: Swift-native, supports log levels and file logging.
- Unified Logging System: Apple’s underlying system for
os_log
andLogger
, visible in Console.app.
Conclusion: Choosing the Right Logging Tool
The best logging tool depends on your app’s needs and target iOS version. For most modern apps, Logger
is the recommended choice. For older apps or advanced needs (like file logging), CocoaLumberjack or SwiftyBeaver are excellent. For quick debugging, print
and NSLog
are still useful.
Looking for More? Try LogDog
If you need real-time remote logging, session replay, and request monitoring for iOS and Android, check out LogDog. It’s designed for production debugging and team collaboration, going far beyond what’s possible with local logging alone.