Xcode Debugging hint

A lightweight, zero-cost debugging utility for Swift projects that automatically strips debug statements from release builds.

## Overview

The `DebugHelpers.swift` file provides debug logging macros that are completely removed during release builds, ensuring zero performance impact in production.

## Features

– **Zero runtime cost in release builds** – All debug code is stripped at compile time

– **Simple API** – Drop-in replacement for `print()`

– **File and line tracking** – Optional detailed logging with source location

– **Debug assertions** – Catch issues early in development

## Usage

### Basic Debug Logging

Replace `print()` with `DLOG()`:

“`swift

// Old way (appears in release builds):

print(“User logged in:”, username)

// New way (stripped from release builds):

DLOG(“User logged in:”, username)

“`

### Debug Logging with Source Location

When you need to know exactly where a log came from:

“`swift

DLOG_TRACE(“Error occurred”)

// Output: [ViewController.swift:42] Error occurred

“`

### Debug Assertions

Catch programming errors during development:

“`swift

DASSERT(user.age > 0, “User age must be positive”)

// Only fires in DEBUG builds

// In release: completely removed

“`

## API Reference

### `DLOG(_ items: Any…, separator: String = ” “, terminator: String = “\n”)`

Basic debug print that works exactly like Swift’s `print()` but only in DEBUG builds.

**Parameters:**

– `items` – Values to print

– `separator` – String to separate values (default: ” “)

– `terminator` – String to end the line (default: “\n”)

**Example:**

“`swift

DLOG(“Processing”, itemCount, “items”)

“`

### `DLOG_TRACE(_ items: Any…, file: String = #file, line: Int = #line)`

Debug print with file and line number information.

**Parameters:**

– `items` – Values to print

– `file` – Source file (automatically captured)

– `line` – Line number (automatically captured)

**Example:**

“`swift

DLOG_TRACE(“Unexpected state”)

// Output: [MyView.swift:127] Unexpected state

“`

### `DASSERT(_ condition: Bool, _ message: String = “”, file: String = #file, line: Int = #line)`

Debug-only assertion that crashes the app if condition is false.

**Parameters:**

– `condition` – Boolean condition to check

– `message` – Description of the assertion

– `file` – Source file (automatically captured)

– `line` – Line number (automatically captured)

**Example:**

“`swift

DASSERT(array.count > 0, “Array should not be empty”)

“`

## How It Works

The macros use Swift’s `#if DEBUG` preprocessor directive:

“`swift

func DLOG(_ items: Any…) {

    #if DEBUG

    print(items)

    #endif

}

“`

When you build for release (without the DEBUG flag), the compiler completely removes all code inside `#if DEBUG` blocks. This means:

– No runtime overhead

– No string allocations

– No function calls

– Zero bytes in the binary

## Setting Up in New Projects

### Option 1: File Template

1. Create the template directory:

“`bash

mkdir -p ~/Library/Developer/Xcode/Templates/File\ Templates/Custom/Debug\ Helper.xctemplate

“`

2. Copy the template files to that directory

3. Restart Xcode

4. New file → Custom → Debug Helper

### Option 2: Code Snippet

1. In Xcode, select the `DebugHelpers.swift` code

2. Right-click → Create Code Snippet

3. Set completion shortcut: `debughelpers`

4. In any project, type `debughelpers` + Enter

### Option 3: Manual Copy

Simply drag `DebugHelpers.swift` into your new project.

## Best Practices

### DO:

– Use `DLOG()` for temporary debugging during development

– Use `DLOG_TRACE()` when you need to track execution flow

– Use `DASSERT()` to catch programming errors early

– Remove debug statements once issues are resolved

### DON’T:

– Don’t use for production logging (use OSLog or a logging framework)

– Don’t log sensitive information (even in debug builds)

– Don’t use as a permanent logging solution

## Benefits Over `print()`

| Feature | `print()` | `DLOG()` |

|———|———–|———-|

| Works in DEBUG | ✅ | ✅ |

| Works in RELEASE | ✅ | ❌ (intentional) |

| Runtime cost in release | ⚠️ Yes | ✅ Zero |

| Binary size impact | ⚠️ Increases | ✅ None |

| String evaluation cost | ⚠️ Always | ✅ DEBUG only |

## Migration Guide

### Finding print statements to replace:

“`bash

# Find all print() calls in Swift files

grep -r “print(” –include=”*.swift” .

“`

### Replace with DLOG:

“`swift

// Before:

print(“Loading data…”)

print(“Items:”, items.count)

print(“Error:”, error.localizedDescription)

// After:

DLOG(“Loading data…”)

DLOG(“Items:”, items.count)

DLOG(“Error:”, error.localizedDescription)

“`

## Advanced Usage

### Custom Debug Helpers

You can extend the pattern for specific needs:

“`swift

#if DEBUG

func DLOG_NETWORK(_ url: URL, _ response: HTTPURLResponse?) {

    print(“🌐 Network: \(url)”)

    if let status = response?.statusCode {

        print(”   Status: \(status)”)

    }

}

#else

func DLOG_NETWORK(_ url: URL, _ response: HTTPURLResponse?) {}

#endif

“`

### Conditional Compilation Flags

Check your build configuration:

– Xcode → Target → Build Settings → Swift Compiler – Custom Flags

– DEBUG should be in “Other Swift Flags” for Debug configuration: `-D DEBUG`

## Troubleshooting

### “DLOG is showing in release builds”

Check your build configuration:

1. Select your target

2. Build Settings → Swift Compiler – Custom Flags

3. Debug configuration should have `-D DEBUG`

4. Release configuration should NOT have `-D DEBUG`

### “Cannot find DLOG in scope”

Make sure `DebugHelpers.swift` is included in your target’s compile sources:

1. Select the file in project navigator

2. File Inspector → Target Membership

3. Check your app target

## Performance Notes

In DEBUG builds, these macros have the same performance as `print()`.

In RELEASE builds:

– **Zero CPU cost** – Code doesn’t exist

– **Zero memory cost** – Strings not allocated

– **Zero binary size** – Completely stripped

Example binary size comparison on a real project:

– With 100 `print()` statements: +8KB

– With 100 `DLOG()` statements: +0KB i