Logging in Swift Applications: Best Practices for Beginners

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Logging in Swift Applications: Best Practices for Beginners

\n\n

Logging is not just about writing messages to the console. For a beginner iOS/macOS developer, a proper logging system can be a lifesaver when debugging, monitoring, and analyzing application performance. In this article, we will cover best practices for logging in Swift, from simple approaches to professional tools.

\n\n

Why is Proper Logging Important?

\n

When your application runs on a user's device or on a server, you cannot simply "see what went wrong." Logs are the only source of information about program behavior in a production environment. Proper logging helps you:

\n
    \n
  • Quickly find and fix errors
  • \n
  • Track the sequence of events
  • \n
  • Analyze performance
  • \n
  • Understand user actions (while respecting privacy)
  • \n
\n\n

Logging Levels: Debugging Without Chaos

\n

One of the main mistakes beginners make is using print() for everything. Instead, introduce a system of logging levels. Standard levels (in increasing order of importance):

\n
    \n
  • Debug — detailed information for the developer (variable values, function calls)
  • \n
  • Info — important events (screen load, successful request)
  • \n
  • Warning — potential issues (deprecated API, unexpected value)
  • \n
  • Error — critical failures requiring attention
  • \n
\n\n

Example of a simple implementation in Swift:

\n
enum LogLevel: String {\n    case debug = "🔍 DEBUG"\n    case info = "ℹ️ INFO"\n    case warning = "⚠️ WARNING"\n    case error = "❌ ERROR"\n}\n\nfunc log(_ message: String, level: LogLevel = .debug, file: String = #file, function: String = #function, line: Int = #line) {\n    #if DEBUG\n    let fileName = (file as NSString).lastPathComponent\n    print("[\\(level.rawValue)] [\\(fileName):\\(line)] \\(function) -> \\(message)")\n    #endif\n}\n
\n\n

Using OSLog (Unified Logging System)

\n

Starting with iOS 10 and macOS Sierra, Apple recommends using OSLog instead of NSLog and print(). This is a built-in logging system that:

\n
    \n
  • Automatically categorizes messages
  • \n
  • Supports dynamic enabling/disabling of levels
  • \n
  • Works in production without performance degradation
  • \n
  • Integrates with Instruments and Console.app
  • \n
\n\n

Basic OSLog setup:

\n
import OSLog\n\nextension Logger {\n    static let network = Logger(subsystem: "com.yourapp.network", category: "network")\n    static let ui = Logger(subsystem: "com.yourapp.ui", category: "ui")\n    static let database = Logger(subsystem: "com.yourapp.database", category: "database")\n}\n\n// Usage:\nLogger.network.info("API request completed successfully")\nLogger.ui.error("Error displaying controller: \\(error.localizedDescription)")\n
\n\n

The advantage of OSLog is that debug and info level messages are automatically disabled in release builds unless configured otherwise. This prevents cluttering production logs.

\n\n

Frameworks for Advanced Logging

\n

If you need additional features (file logging, log rotation, remote collection), check out popular libraries:

\n\n

CocoaLumberjack

\n

One of the most popular frameworks for Swift/Objective-C. It supports:

\n
    \n
  • Multiple "receivers" (console, file, remote server)
  • \n
  • Asynchronous logging
  • \n
  • Message formatting
  • \n
  • Dynamic log level changes
  • \n
\n\n
import CocoaLumberjack\n\n// Setup in AppDelegate\nDDLog.add(DDOSLogger.sharedInstance) // Console\nlet fileLogger = DDFileLogger()\                

Blogs

Book Recommendations