Prettier Debug Output Printing Swift Dictionary in Xcode

Prettier debug output printing Swift Dictionary in Xcode

⚠️ 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
}

Is there a way to pretty print Swift dictionaries to the console?

You could use dump, for example, if the goal is to inspect the dictionary. dump is part of Swift's standard library.

Usage:

let dictionary: [String : String] = ["A" : "alfa",
"B" : "bravo",
"C" : "charlie",
"D" : "delta",
"E" : "echo",
"F" : "foxtrot"]

dump(dictionary)

Output:

Sample Image


dump prints the contents of an object via reflection (mirroring).

Detailed view of an array:

let names = ["Joe", "Jane", "Jim", "Joyce"]
dump(names)

Prints:

▿ 4 elements

- [0]: Joe

- [1]: Jane

- [2]: Jim

- [3]: Joyce

For a dictionary:

let attributes = ["foo": 10, "bar": 33, "baz": 42]
dump(attributes)

Prints:

▿ 3 key/value pairs

▿ [0]: (2 elements)

- .0: bar

- .1: 33

▿ [1]: (2 elements)

- .0: baz

- .1: 42

▿ [2]: (2 elements)

- .0: foo

- .1: 10

dump is declared as dump(_:name:indent:maxDepth:maxItems:).

The first parameter has no label.

There's other parameters available, like name to set a label for the object being inspected:

dump(attributes, name: "mirroring")

Prints:

▿ mirroring: 3 key/value pairs

▿ [0]: (2 elements)

- .0: bar

- .1: 33

▿ [1]: (2 elements)

- .0: baz

- .1: 42

▿ [2]: (2 elements)

- .0: foo

- .1: 10

You can also choose to print only a certain number of items with maxItems:, to parse the object up to a certain depth with maxDepth:, and to change the indentation of printed objects with indent:.

Adding multiple arrays to form one final array. Debug swift xcode

I think you may have problem problem if you using List model regarding to playing sound of clicked Card one could be better is to modify the Card model with following way

import Foundation; import UIKit; import AVFoundation

var player: AVAudioPlayer?

class Card: NSObject
{
var image: UIImage
var soundUrl: String
var isActive: Bool

init(image: UIImage, soundUrl: String, isActive:Bool = true) {
self.image = image
self.soundUrl = soundUrl
self.isActive = isActive
}
func playSound()
{
guard let url = Bundle.main.url(forResource: self.soundUrl, withExtension: "m4a") else { return }
do
{
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)

player = try AVAudioPlayer(contentsOf: url)
guard let player = player else { return }
player.prepareToPlay()
player.play()
print("play")
} catch let error {
print(error.localizedDescription)
}
}
}

Usage
Replace your viewController code with this

 import UIKit

class SecondViewController: UIViewController , UIGestureRecognizerDelegate {

var imageIndex: Int = 0
var itemList:[Card] = []

func addlist(list:[String], flag:Bool)
{
for word in list
{
itemList.append(Card(image: UIImage(named: word)!, soundUrl: word,isActive:flag))
}
}
override func viewDidLoad() {
super.viewDidLoad()
let list1 = ["lake", "lamb", "lamp", "lark", "leaf", "leash", "left", "leg", "lime", "lion", "lips", "list", "lock", "log", "look", "love", "lunch"]
let list2 = ["ladder", "ladybug", "laughing", "lawnmower", "lemon", "leopard", "leprechaun", "letters", "licking", "lifesaver", "lifting", "lightbulb", "lightning",
"listen", "llama"]
let list3 = ["alligator", "balance", "ballerina", "balloon", "bowling", "cello", "colors", "curlyhair", "dollar", "dolphin", "elephant", "eyelashes", "gasoline",

"goalie", "hula", "jellyfish", "olive", "pillow", "pilot", "polarbear", "rollerskate", "ruler", "silly", "telephone", "television", "tulip", "umbrella", "valentine",
"violin", "xylophone", "yellow"]
let list4 = ["apple", "ball", "bell", "bubble", "castle", "fall", "fishbowl", "girl", "owl", "pail", "peel", "pool", "smile", "whale", "wheel"]
let list5 = ["planet", "plank", "plant", "plate", "play", "plum", "plumber", "plus"]
let list6 = ["black", "blanket", "blender", "blocks", "blond", "blood", "blow", "blue"]
let list7 = ["flag", "flipflop", "float", "floor", "flower", "fluffy", "flute", "fly"]
let list8 = ["glacier", "glad", "glasses", "glide", "glitter", "globe", "glove", "glue"]
let list9 = ["clam", "clamp", "clap", "claw", "clean", "climb", "clip", "cloud"]
let list10 = ["sled", "sleep", "sleeves", "slice", "slide", "slime", "slip", "slow"]
let list11 = ["belt", "cold", "dolphin", "elf", "golf", "melt", "milk", "shelf"]
addlist(list:list1,flag:true);
addlist(list:list2,flag:true);
addlist(list:list3,flag:true);
addlist(list:list4,flag:true);
addlist(list:list5,flag:true);
addlist(list:list6,flag:true);
addlist(list:list7,flag:true);
addlist(list:list8,flag:true);
addlist(list:list9,flag:true);
addlist(list:list10,flag:true);
addlist(list:list11,flag:true);

let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
imgPhoto.isUserInteractionEnabled = true
imgPhoto.addGestureRecognizer(tapGestureRecognizer)

imgPhoto.image = itemList[0].image

// Do any additional setup after loading the view.
imgPhoto.isUserInteractionEnabled = true

let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(Swiped(gesture:)))
leftSwipe.cancelsTouchesInView = false

let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(Swiped(gesture:)))
rightSwipe.cancelsTouchesInView = false

leftSwipe.direction = .left
rightSwipe.direction = .right

view.addGestureRecognizer(leftSwipe)
view.addGestureRecognizer(rightSwipe)

}

@IBAction func home(_ sender: Any) {
performSegue(withIdentifier: "home", sender: self)
}

@IBOutlet weak var imgPhoto: UIImageView!

func imageTapped(tapGestureRecognizer: UITapGestureRecognizer)
{

itemList[imageIndex].playSound()
// Your action
}
func Swiped(gesture: UIGestureRecognizer) {

if let swipeGesture = gesture as? UISwipeGestureRecognizer {

switch swipeGesture.direction {

case UISwipeGestureRecognizerDirection.right :
print("User swiped right")

// decrease index first

imageIndex -= 1

// check if index is in range

if imageIndex < 0 {

imageIndex = itemList.count - 1

}

imgPhoto.image = itemList[imageIndex].image

case UISwipeGestureRecognizerDirection.left:
print("User swiped Left")

// increase index first

imageIndex += 1

// check if index is in range

if imageIndex > itemList.count - 1 {

imageIndex = 0

}

imgPhoto.image = itemList[imageIndex].image
default:

break //stops the code/codes nothing.
}
}
}
}

Is there a better way to Pretty Print the json string than I'm using

A slightly prettier version of what you have:

if let json = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers),
let jsonData = try? JSONSerialization.data(withJSONObject: json, options: .prettyPrinted) {
print(String(decoding: jsonData, as: UTF8.self))
} else {
print("json data malformed")
}

How do I print the type or class of a variable in Swift?

Update September 2016

Swift 3.0: Use type(of:), e.g. type(of: someThing) (since the dynamicType keyword has been removed)

Update October 2015:

I updated the examples below to the new Swift 2.0 syntax (e.g. println was replaced with print, toString() is now String()).

From the Xcode 6.3 release notes:

@nschum points out in the comments that the Xcode 6.3 release notes show another way:

Type values now print as the full demangled type name when used with
println or string interpolation.

import Foundation

class PureSwiftClass { }

var myvar0 = NSString() // Objective-C class
var myvar1 = PureSwiftClass()
var myvar2 = 42
var myvar3 = "Hans"

print( "String(myvar0.dynamicType) -> \(myvar0.dynamicType)")
print( "String(myvar1.dynamicType) -> \(myvar1.dynamicType)")
print( "String(myvar2.dynamicType) -> \(myvar2.dynamicType)")
print( "String(myvar3.dynamicType) -> \(myvar3.dynamicType)")

print( "String(Int.self) -> \(Int.self)")
print( "String((Int?).self -> \((Int?).self)")
print( "String(NSString.self) -> \(NSString.self)")
print( "String(Array<String>.self) -> \(Array<String>.self)")

Which outputs:

String(myvar0.dynamicType) -> __NSCFConstantString
String(myvar1.dynamicType) -> PureSwiftClass
String(myvar2.dynamicType) -> Int
String(myvar3.dynamicType) -> String
String(Int.self) -> Int
String((Int?).self -> Optional<Int>
String(NSString.self) -> NSString
String(Array<String>.self) -> Array<String>

Update for Xcode 6.3:

You can use the _stdlib_getDemangledTypeName():

print( "TypeName0 = \(_stdlib_getDemangledTypeName(myvar0))")
print( "TypeName1 = \(_stdlib_getDemangledTypeName(myvar1))")
print( "TypeName2 = \(_stdlib_getDemangledTypeName(myvar2))")
print( "TypeName3 = \(_stdlib_getDemangledTypeName(myvar3))")

and get this as output:

TypeName0 = NSString
TypeName1 = __lldb_expr_26.PureSwiftClass
TypeName2 = Swift.Int
TypeName3 = Swift.String

Original answer:

Prior to Xcode 6.3 _stdlib_getTypeName got the mangled type name of a variable. Ewan Swick's blog entry helps to decipher these strings:

e.g. _TtSi stands for Swift's internal Int type.

Mike Ash has a great blog entry covering the same topic.

Can't Get ASP.NET MVC Form To Post

Ok, got the answer. And thanks Craig for having me look at the HTML again! My master page had generated a form tag in it without my knowing it, so I essentially had nested forms on the same page. After I removed the form from the Master Page, everything worked perfectly.

Initialising C structures in C++ code

If you can't add a constructor (which is the best solution in C++03 but you probably have compatibility constraint with C), you can write a function with the same effect:

MyStruct makeAMyStruct(int x, int y, int z)
{
MyStruct result = { x, y, z };
return result;
}

items.push_back(makeAMyStruct(5,rand()%100,items.size()));

Edit: I'd have checked now that C++0X offers something for this precise problem:

items.push_back(MyStruct{5,rand()%100,items.size()});

which is available in g++ 4.4.



Related Topics



Leave a reply



Submit