Swift @autoclosure: How SwiftyBeaver uses @autoclosure

In this lesson

In this lesson, I will discuss SwiftyBeaver’s use of the Swift @autoclosure annotation and the impact it has on logging.

Transcript

Tap on time to skip ahead

00:11

Hello everyone! In this lesson, I want to talk about a Swift language thatSwiftyBeaver uses that may go unnoticed by many people. But it’s a really important feature. To show you this, I’ve navigated here to the SwiftyBeaver class in the HitHub repo. And I’m going to navigate down to the functions that are used took to actually log statements to the destinations; that being the verbose, debug, info, warning and error functions. And I want to call your attention to this annotation on the message argument called @autoclosure. And that’s the focus of this lesson.

00:58

I am here in XCode in one of the classes in one of my dynamic frameworks that’s used in my sample application. I’m in the SQLUpdateOperation. And this is a class that perform SQL insert, updates and deletes. And you may have noticed in other lessons that I’m logging all of that because as I indicated, I log everything. So here, notice that I’m calling SwiftyBeaver’s debug() function. And I’m passing a string which gets assembled. And since I’m logging at the .Debug level, these statements will be ignored if I set my minimum level higher than .Debug. For some logging statements, that might be fine but some of these might be expensive to assemble and that’s just waste. So that’s where the @autoclosure comes in.

02:03

To further illustrate, I’m in another dynamic framework used by my sample application and this framework is responsible for executing a bunch of network operations. Again following my own advice, I log everything. I log every single network request. And you can see here that it assembles a fairly complicated statement to be logged at the .Debug level using SwiftyBeaver. And then down here I’ll have a function which logs responses. And you can see again, using .Warning or .Debug depending upon the status code of the response. I assemble a fairly complicated log statement that could be expensive to assemble. And again, if my min logging level is set higher than one of these, then the expense of assembly is wasted.

03:04

I’m back here again at the SwiftyBeaver GitHub repo when I’m looking at the @autoclosure annotation for all of these functions, just so you get another look at what’s going on. So everyone of these logging functions annotates the message argument as an @autoclosure. So what does that actually mean?

03:28

To illustrate what that means, I’ve gone back to a place in one of my classes where I’m doing some logging and I want to show you what that means. So this is the message argument to the debug(), which is annotated with an @autoclosure. And what that means is that the swift compiler will wrap this argument as a closure for you. So in essence, it is the equivalent of doing this. But what does that really mean? Well what that means is that this, the contents off this, actually, it means this, I forgot the return.. so what this means is that the compiler will wrap the argument automatically in a closure and pass the closure as an argument to the function. And what that does, is it delays… it allows you to delay evaluating this potentially expensive code until it’s actually needed. And that’s very important when it comes to logging. Because if this statement actually isn’t going to be logged because of some filter or because of a min level, there’s no reason to go through the expense of assembling this log statement. The @autoclosure allows this to be wrapped as a function and then that is called later after it has been determined that this statement will in fact appear somewhere in a logged destination. So let me summarize what that means. You do not have to be concerned with how expensive necessarily, it is to assemble a log statement because SwiftyBeaver annotates all of the logging API with an @autoclosure annotation. And this code will not run until later. It does not run at the point that this function is called, but later inside the function after it has been determined that this statement will in fact be logged. So there you have it. It’s a small little feature taking advantage of a Swift language feature that probably a lot of people aren’t aware of, but it’s really important. 

Additional Info

Register to get access to additional resources and info.