Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prettier debug output printing Swift Dictionary in Xcode

When I use print() on a dictionary in Swift, it comes out nice and pretty in the console, with a key and a value.

object = Optional({
customerId = 111;
transactionId = 333;
extraId = 444;
})

When I run po on that same dictionary, it spits out this nonsense dump which is incredibly hard to read.

▿ Optional<Any>
▿ some : 3 elements
▿ 0 : 2 elements
  ▿ .0 : transactionId
  - .1 : 333
▿ 1 : 2 elements
  ▿ .0 : customerId
  - .1 : 111
▿ 2 : 2 elements
  ▿ .0 : extraId
  - .1 : 444

Using just p is even worse

(Any?) $R8 = some {
  payload_data_0 = 0x0000000170e679c0 {
  Swift._SwiftNativeNSDictionary = {}
  _heapBufferBridged_DoNotUse = 0x0000000170e679d0 {}
  nativeStorage = {
    buffer = 0x00000001703e4300 {
      Swift.ManagedBuffer = {}
    }
    initializedEntries = (values = 0x00000001703e4328, bitCount = 4)
    keys = 0x00000001703e4330
    values = 0x00000001703e4390
    }
  }
  payload_data_1 = 0x0000000000000000
  payload_data_2 = 0x0000000000000000
  instance_type = 0x0000000105ffc3f8
}

What can I do in the console to see my variables in a way that I can actually read them without having to sift through all this nonsense?

PS - In this case I am printing an Optional<Any> object that happens to be a dictionary, but it's the same with a non-optional Dictionary.

like image 836
teradyl Avatar asked Feb 14 '17 21:02

teradyl


People also ask

How do I display print in Xcode?

Press ⇧⌘Y or choose View > Debug Area > Show Debug Area to show the console output (or ⇧⌘C / Activate Console). Usually, this window will open automatically when your program produces output (this is controlled by the Behaviors section of Xcode's Preferences). Save this answer. Show activity on this post.

How do I debug a Swift code in Xcode?

When you run an application in Xcode, the debugger is automatically started and attached to the process of the application. Click the Run button in the top left or press Command + R. From the moment the application is up and running, we can start inspecting the process and, if necessary, debug it.

What is debug print in Swift?

debugPrint(_:separator:terminator:)Writes the textual representations of the given items most suitable for debugging into the standard output.


1 Answers

⚠️ The (previously) accepted answer only provided the dictionary as a non-formatted single line string like so:

Optional(["transactionId": 333, "customerId": 111, "extraId": 444])

➡️ As soon as you get more keys and embedded objects/dictionaries it becomes difficult to read.


PrettyPrint JSON solution

  • To get a nice json formatting (indentations, newlines, etc) you can define an alias (I named mine pjson) by running this command in your lldb terminal (source):
command regex pjson 's/(.+)/expr print(NSString(string: String(data: try! JSONSerialization.data(withJSONObject: %1, options: .prettyPrinted), encoding: .utf8)!))/'
  • You probably don't want to re-define the alias everytime you open Xcode, so run the following command to append the alias definition to ~/.lldbinit:
echo "command regex pjson 's/(.+)/expr print(NSString(string: String(data: try! JSONSerialization.data(withJSONObject: %1, options: .prettyPrinted), encoding: .utf8)!))/'" >> ~/.lldbinit
  • This will create the pjson alias which you can use in your lldb terminal in Xcode:
pjson object

Comparing the outputs for the following Swift object:

let object: Any? = [
    "customerId": 111,
    "transactionId": 333,
    "extraId": 444,
    "embeddedDict": [
        "foo": true
    ]
]

❌ Output of po print(data)

Optional(["transactionId": 333, "embeddedDict": ["foo": true], "customerId": 111, "extraId": 444])

✅ Output of pjson

{
  "transactionId" : 333,
  "embeddedDict" : {
    "foo" : true
  },
  "customerId" : 111,
  "extraId" : 444
}
like image 138
agirault Avatar answered Dec 03 '22 11:12

agirault