Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

2023 Developer Tools

WWDC23 · 14 min · Developer Tools

Debug with structured logging

Discover the debug console in Xcode 15 and learn how you can improve your diagnostic experience through logging. Explore how you can navigate your logs easily and efficiently using advanced filtering and improved visualization. We’ll also show you how to use the dwim-print command to evaluate expressions in your code while debugging.

Watch at developer.apple.com ↗

Transcript all transcripts

Chapters

  • 0:44 — Tour of the Debug Console
  • 3:28 — Live debugging
  • 7:25 — LLDB improvements
  • 9:04 — Tips for logging
  • 12:04 — Get the most out of your logging

Code shown on screen · 14 snippets

Calling setDisplayName from Edit Account page swift · at 5:17 ↗
.onSubmit {
    logger.info("Requesting to change displayName to \(displayName)")
    accountViewModel.setDisplayName(displayName)
}
Account Data Setters (Before Fix) swift · at 5:34 ↗
public func setDisplayName(_ newDisplayName: String) {
    logger.info("Sending Request to update DisplayName")

    Database.setValueForKey(Database.Key.displayName, value: newDisplayName, forAccount: account.id)

    logger.info("Updated DisplayName to '\(newDisplayName)'")
}

public func setEmailAddressName(_ newEmailAddress: String) {
    logger.info("Sending Request to update EmailAddress")

    Database.setValueForKey(Database.Key.emailAddress, value: newEmailAddress, forAccount: account.id)

    logger.info("Updated EmailAddress to '\(newEmailAddress)'")
}
Account Data Setters (After Fix) swift · at 6:04 ↗
public func setDisplayName(_ newDisplayName: String) {
    logger.info("Sending Request to update DisplayName")

    Database.setValueForKey(Database.Key.displayName, value: newDisplayName, forAccount: account.id)

    account.displayName = newDisplayName

    logger.info("Updated DisplayName to '\(newDisplayName)'")
}

public func setEmailAddressName(_ newEmailAddress: String) {
    logger.info("Sending Request to update EmailAddress")

    Database.setValueForKey(Database.Key.emailAddress, value: newEmailAddress, forAccount: account.id)

    account.emailAddress = newEmailAddress

    logger.info("Updated EmailAddress to '\(newEmailAddress)'")
}
po account bash · at 6:35 ↗
(lldb) po account
po account (with result) bash · at 6:39 ↗
(lldb) po account
<Account: 0x60000223b2a0>
p account bash · at 7:00 ↗
(lldb) p account
po account (with result) bash · at 7:04 ↗
(lldb) p account
(BackyardBirdsData.Account) =0x000060000223b2a0 {
	id = 3A9FC684-8DFC-4D7D-B645-E393AEBA14EE
	joinDate = 2023-06-05 16:41:00 UTC
	displayName = "Sample Account"
	emailAddress = "[email protected]"
	isPremiumMember = true
}
p account (after fix) bash · at 7:18 ↗
(lldb) p account
(BackyardBirdsData.Account) =0x000060000223b2a0 {
	id = 3A9FC684-8DFC-4D7D-B645-E393AEBA14EE
	joinDate = 2023-06-05 16:41:00 UTC
	displayName = "Johnny Appleseed"
	emailAddress = "[email protected]"
	isPremiumMember = true
}
Login Method Skeleton swift · at 9:43 ↗
func login(password: String) -> Error? {
    var error: Error? = nil

    //...

    loggedIn = true
    return error
}
Login Method with Print Statements swift · at 9:56 ↗
func login(password: String) -> Error? {
    var error: Error? = nil
    print("Logging in user '\(username)'...")

    

    if let error {
        print("User '\(username)' failed to log in. Error: \(error)")
    } else {
        loggedIn = true
        print("User '\(username)' logged in successfully.")
    }
    return error
}
Login Method with Extended Print Statements swift · at 10:18 ↗
func login(password: String) -> Error? {
    var error: Error? = nil
    print("🤖 Logging in user '\(username)'... (\(#file):\(#line))")

    //...

    if let error {
        print("🤖 User '\(username)' failed to log in. Error: \(error) (\(#file):\(#line))")
    } else {
        loggedIn = true
        print("🤖 User '\(username)' logged in successfully. (\(#file):\(#line))")
    }
    return error
}
Login Method with Partial OSLog Transition swift · at 10:40 ↗
import OSLog

let logger = Logger(subsystem: "BackyardBirdsData", category: "Account")

func login(password: String) -> Error? {
    var error: Error? = nil
    print("🤖 Logging in user '\(username)'... (\(#file):\(#line))")

    //...

    if let error {
        print("🤖 User '\(username)' failed to log in. Error: \(error) (\(#file):\(#line))")
    } else {
        loggedIn = true
        print("🤖 User '\(username)' logged in successfully. (\(#file):\(#line))")
    }
    return error
}
Login Method with OSLog Statements swift · at 11:00 ↗
import OSLog

let logger = Logger(subsystem: "BackyardBirdsData", category: "Account")

func login(password: String) -> Error? {
    var error: Error? = nil
    logger.info("Logging in user '\(username)'...")

    //...

    if let error {
        logger.error("User '\(username)' failed to log in. Error: \(error)")
    } else {
        loggedIn = true
        logger.notice("User '\(username)' logged in successfully.")
    }
    return error
}
Example Logging Statements swift · at 11:16 ↗
let logger = Logger(subsystem: "BackyardBirdsData", category: "Account")
logger.error("User '\(username)' failed to log in. Error: \(error)")
logger.notice("User '\(username)' logged in successfully.")

Resources