All skills

Code generator skills that produce production-ready Swift code for common app components. Use when user wants to add logging, analytics, onboarding, review prompts, networking, authentication, paywalls, settings, persistence, error monitoring, CI/CD pipelines, localization, push notifications, deep linking, testing, accessibility, widgets, feature flags, app icons, image caching, pagination, HTTP caching, share cards, social export, subscription lifecycle, referral systems, watermarks, streak tracking, milestone celebrations, what's new screens, lapsed user re-engagement, usage insights, variable rewards, consent flows, account deletion, permission priming, force updates, state restoration, debug menus, offline queues, feedback forms, announcement banners, quick win sessions, Spotlight indexing, App Clips, screenshot automation, background processing, app extensions, data export, or SwiftUI preview sample data and variant matrices.

Use this Skill: https://skilld.dev/gh/rshankras/claude-code-apple-skills/generators

This session only. Nothing lands on disk.

logging-setuplogger-patterns.md

≈1.6k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Logger Patterns and Best Practices

Log Levels

Use appropriate log levels for different situations:

Level Use Case Release Behavior
.debug Development only, verbose Compiled out
.info General information Visible
.notice Important events Visible, persisted
.warning Potential issues Visible, persisted
.error Errors that need attention Visible, persisted
.fault Critical failures Visible, persisted, highlighted

Privacy Annotations

.public

Data safe to log in production:

AppLogger.network.info("Request ID: \(requestId, privacy: .public)")
AppLogger.data.info("Items count: \(items.count, privacy: .public)")

.private (default)

Redacted in release builds, visible in debug:

AppLogger.auth.info("User: \(email, privacy: .private)")
AppLogger.network.debug("Response: \(responseBody, privacy: .private)")

.sensitive

Always redacted, even in debug:

AppLogger.auth.info("Token: \(token, privacy: .sensitive)")

.hash

Shows hash of value (useful for correlation without exposing data):

AppLogger.auth.info("User hash: \(userId, privacy: .private(mask: .hash))")

Category Organization

Recommended Categories

enum AppLogger {
    // Core
    static let general = Logger(subsystem: subsystem, category: "General")

    // Networking
    static let network = Logger(subsystem: subsystem, category: "Network")
    static let api = Logger(subsystem: subsystem, category: "API")

    // User
    static let auth = Logger(subsystem: subsystem, category: "Auth")
    static let user = Logger(subsystem: subsystem, category: "User")

    // Data
    static let data = Logger(subsystem: subsystem, category: "Data")
    static let cache = Logger(subsystem: subsystem, category: "Cache")

    // UI
    static let ui = Logger(subsystem: subsystem, category: "UI")
    static let navigation = Logger(subsystem: subsystem, category: "Navigation")

    // System
    static let performance = Logger(subsystem: subsystem, category: "Performance")
    static let lifecycle = Logger(subsystem: subsystem, category: "Lifecycle")
}

Common Patterns

Network Request Logging

func fetch(_ endpoint: Endpoint) async throws -> Data {
    AppLogger.network.debug("Request: \(endpoint.method) \(endpoint.path)")

    do {
        let (data, response) = try await session.data(for: endpoint.request)
        let statusCode = (response as? HTTPURLResponse)?.statusCode ?? 0
        AppLogger.network.info("Response: \(statusCode, privacy: .public) for \(endpoint.path)")
        return data
    } catch {
        AppLogger.network.error("Request failed: \(error.localizedDescription)")
        throw error
    }
}

Authentication Logging

func signIn(email: String, password: String) async throws {
    AppLogger.auth.info("Sign in attempt for: \(email, privacy: .private)")

    do {
        let user = try await authService.signIn(email: email, password: password)
        AppLogger.auth.notice("Sign in successful for user: \(user.id, privacy: .private(mask: .hash))")
    } catch {
        AppLogger.auth.warning("Sign in failed: \(error.localizedDescription)")
        throw error
    }
}

Data Operations Logging

func save(_ items: [Item]) throws {
    AppLogger.data.debug("Saving \(items.count, privacy: .public) items")

    let start = CFAbsoluteTimeGetCurrent()
    try context.save()
    let duration = CFAbsoluteTimeGetCurrent() - start

    AppLogger.data.info("Saved \(items.count, privacy: .public) items in \(duration, format: .fixed(precision: 3))s")
}

Error Logging

func handleError(_ error: Error, context: String) {
    if let appError = error as? AppError {
        switch appError {
        case .networkError(let underlying):
            AppLogger.network.error("\(context): \(underlying.localizedDescription)")
        case .authError(let reason):
            AppLogger.auth.error("\(context): \(reason)")
        case .dataError(let underlying):
            AppLogger.data.error("\(context): \(underlying.localizedDescription)")
        }
    } else {
        AppLogger.general.fault("Unexpected error in \(context): \(error)")
    }
}

Anti-Patterns to Avoid

Don't Log Sensitive Data as Public

// Bad
AppLogger.auth.info("Password: \(password, privacy: .public)")

// Good
AppLogger.auth.debug("Password provided: \(password.isEmpty ? "no" : "yes", privacy: .public)")

Don't Use Wrong Log Levels

// Bad - Using debug for errors
AppLogger.network.debug("Critical error: \(error)")

// Good
AppLogger.network.error("Request failed: \(error)")

Don't Skip Privacy for User Data

// Bad - No privacy annotation for email
AppLogger.auth.info("User email: \(email)")

// Good
AppLogger.auth.info("User email: \(email, privacy: .private)")

Don't Log Excessively in Loops

// Bad
for item in items {
    AppLogger.data.debug("Processing: \(item)")
}

// Good
AppLogger.data.debug("Processing \(items.count, privacy: .public) items")
// Log individual items only at trace level or when debugging specific issues

Performance Considerations

Deferred String Interpolation

Logger uses deferred interpolation - the string is only constructed if the log will be emitted:

// This is efficient - string only built if debug logs enabled
AppLogger.data.debug("Complex object: \(expensiveDescription())")

Signposts for Performance

For performance profiling, use OSSignposter:

import OSLog

let signposter = OSSignposter(logger: AppLogger.performance)

func loadData() async {
    let signpostID = signposter.makeSignpostID()
    let state = signposter.beginInterval("LoadData", id: signpostID)

    // ... perform work ...

    signposter.endInterval("LoadData", state)
}

Console.app Tips

Filtering

  • By subsystem: subsystem:com.yourapp
  • By category: category:Network
  • By level: type:error
  • Combined: subsystem:com.yourapp AND category:Auth AND type:error

Streaming Logs

# Terminal command to stream logs
log stream --predicate 'subsystem == "com.yourapp"' --level debug

Exporting Logs

# Export logs to file
log collect --device --output ~/Desktop/app-logs.logarchive

Source: SKILL.md on GitHub

1 alert16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The 'generators' skill provides a robust set of templates and workflows for generating Swift code for iOS and macOS applications. Security analysis identified a surface for indirect prompt injection because the skill reads local project files to adapt its generation logic. It also utilizes dynamic execution by generating and running local Swift scripts to create application icons and uses shell commands to process images and audit project code. All external references are to well-known, established services.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: MEDIUM · 1 issue

  • Runlayer7mo

    59/179 files flagged

  • ZeroLeaks5mo

    Scan incomplete

Signed by skilld at 30e898f. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Steadyupdated 2 months ago
What it can do
Reads files Edits files Runs commands
last_verified
2026-07-16
review_by
2027-06-22
os_version
iOS 27 / macOS 27
All 7 allowed tools
ReadWriteEditGlobGrepBashAskUserQuestion

README badge

README badge for rshankras/claude-code-apple-skills/generators