Swift: Pretty in print() Pt. 1

Logs are fashion, and you’re the designer

When the Swift beta landed on our laps, the most curious developers within our community immediately jumped onboard and started experimenting with the capabalities of the language and began to write and talk about their experiences.

There were so so many references to Taylor Swift on Twitter I can’t even list the best ones, but somehow even today, it’s still quite funny and no one knows why either, it just is (lel…). Another thing people mentioned a lot was that Swift code can now handle emojis.

func combinedWeatherConditions(lhs: Int, _ rhs: Int) -> Int {
return lhs + rhs
}
let 🌨 = -10, 🌤 = 10, 💧 = 0
if combinedWeatherConditions(🌨, 🌤) == 💧 {
print(“😔 — No 🏂 Today.”)
}
“I started writing Swift purely for the emoji functionality” — No one, ever

It’s such a novel feature/enhancement, but you’re probably never going to need an emoji inside your code or even print statements. But since we’re speaking of print statements, the new console print statement has been graciously simplified and from it’s oldschool predecessor, otherwise known as NSLog.

NSLog

The workhorse of the junior debugger, NSLog was simple enough to use and the go-to tool for discovering values or notifying the developer of events during runtime. Just place a message or an object to print as much as your heart’s desire. But in my opinion, by default NSLog messages contained a lot of garbage:

2016–04–02 09:15:25.660 Blog_Print[13053:3567169] Hello, cruel world. Why don’t you love me? Whyyy!!!

Don’t get me wrong, I’m sure the original engineer/s that wrote NSLog put great thought into what makes a good log message. Here’s a breakdown:

[Date stamp] [Time stamp] [Project name] [Process ID: Thread ID] [Message]

But yea, this is typically too much information for the much of the type logging we would want to do. The date and time stamp combined with the thread and process identifiers take up a lot of space, especially if you have your console window docked to the bottom center-right of Xcode, because that space is tiny, way too tiny for such verbosity.

print

Gratuitously simplified from NSLog, print strips away generally redundant information sticks with the original message.

Hello, beautiful world! I love you.

But maybe, just maybe, sometimes it’s a little too simplified… I know what you’re thinking. But bear with me here.

“This guy complains about NSLog being too much and now print being too little? Pfff... Such a Goldielocks diva.” — You

Just like clothing, you have different outfits for different occasions or purposes. You wouldn’t wear shorts and a singlet out in the snow, right?

print shouldn’t be any different. Sometimes you need to log dates, or API calls, and maybe sometimes you just want your logs to stand out from the rest, and trust me, your want your logs to stand out. This is fashion we’re talking about.

If you’ve ever used a few third party libraries in your project, you would have probably noticed that they fill your console with junk, lots of junk, the kind junk that makes Wall-E depressed. I’m looking at you, Urban Airship.

Too many emojis are never enough

Just before I mentioned that the use of emojis was a novel feature, but it’s actually an amazingly useful feature. Emojis inside your print statements are actually an enormous enhancement to debugging by reducing the amount of cognitive load when your analysing everything inside your console output.

Pro tip:
Pressing Ctrl + Cmd + Space within any textfield on macOS will open a emoji popover.

Strings

let string = "Emojis are life"
print("🔹 " + string)
// 🔹 Emojis are life

NSDate

let date = NSDate()
print("🕒 " + String(date))
// 🕒 2016-04-02 00:14:18 +0000

NSURL

let url = NSURL(string: "http://www.andyyhope.com")
print("🌏 " + String(url))
// 🌏 http://www.andyyhope.com

NSError

let userInfo = [NSLocalizedDescriptionKey: "File not found"]
let error = NSError(domain: "Domain", code: 404, userInfo: userInfo)
print(“❗️ “ + “\(error.code): “ + error.localizedDescription)
// ❗️ 404: File not found

AnyObject

let anyObject = UIColor.redColor()
print("◽️ " + String(anyObject))
// ◽️ UIDeviceRGBColorSpace 1 0 0 1

A nice joke for your colleagues

let joke = "What is this... A center for ANTS?!"
print("🏫🐜 " + joke)
// 🏫🐜 What is this... A center for ANTS?!

As of iOS 9.1 there are now 184 emoji’s to choose from, and even more coming in the future. So there’s most likely an emoji for most of your logging needs.

Implementation

Don’t get me wrong, the implementation above kinda sucks… actually it sucks so hard Hoover is sending me a cease and desist letters. Wrapping anything that isn’t a string inside String parentheses, and also finding the right emoji is an incredible pain and usually impossible if the one you’re looking for isn’t within the “Frequently Used” section.

I think the system is deceptively intuitive enough to know which emoji you’re looking for, and hide it inside some abstract fifth dimension just to mess with you and make you feel like you’re going crazy.

“Maybe the poop emoji doesn’t exist anymore? Or maybe it never existed?” — You
“Oh wait, there it is. I swear I looked there though? …What is life?” — You (ten minutes later)

However, this first post was only to demonstrate the effectiveness of using emojis inside your logs to distinguish the different forms of logging and reducing cognitive load when reading them.

If you can bare with me for this first half, the next and final part of this post will go into proper implementation and show you neat tricks on how to make this emoji logging way, way more useful.


Sample code of this post can be found on GitHub.


Swift: Pretty in print() Pt. 2
Logs are fashion, and you’re the designer

Part 2 includes code implementation of logging with emojis. Enjoy!


If you like what you’ve read today you can check our my other articles or want to get in touch, please send me a tweet or follow me on Twitter, it really makes my day. I also organise Playgrounds Conference in Melbourne, Australia and would to see you at the next event.