As Objective-C developers, we often forget that we can overload functions by return type. This can often help us create neat APIs. This is best illustrated by an example.
I posted a wrapper for timer dispatch sources yesterday. While I was doing it I noticed a discrepancy with GCD. When creating a timer dispatch source, times were passed as nanoseconds as a
UInt64, but the
dispatch_after() function took nanoseconds as an
Int64. Such things are what cause hair-pulling and fighting with the type system.
But most of the time we just want to pass times around as
NSTimeIntervals as seconds, but we have to convert this to a
UInt64 or an
Int64. It’s a better idea to wrap these creating methods, and function overloading lets us use the same descriptive name for these functions with different return types. So, here is some code which you can put in a playground that demonstrates this:
NSTimeInterval which is a typealias for
Double just to make it clear that these new functions apply to times.
Note that there are two functions called
nSecs(), but they return different values. And the strong type system ensures the correct function is used.
dispatch_source_set_timer() uses the
nSecs() -> UInt64 values, and the
nSecs() -> Int64 function
This example also demonstrates that we should write functions for such translations, which separates the concerns of creating and transforming values from the use of those values. It’s something that I don’t do enough of, and I encourage you do try and do this where you can.
Sometimes we want to format some JSON. Here’s an easy way to set up a Service in Automator to make this easier.
Let’s create a service. Open Automator and choose to create a new Service
From the Library, select the “Run Shell Script” action and drag it to the right.
In the action box type:
json_pp | pbcopy
This is what actually does the formatting.
json_pp comes with OS X
. This runs the selected text through the tool and puts the result in the pasteboard.You can paste your formatted output wherever you like.
Save the action with a name - I’ve called mine JSON Pretty Print. You should see the new service installed under
Rather than have to paste the result, we can define another service that replaces the selected text with the result. Create another service as before except that the action doesn’t put the results on the pasteboard.
Note that the “Output replaces selected text” option is checked.
Save this action with a name - I’ve called mine JSON Pretty Print In Place.
An advantage of using the service is that it is intelligent about when to make the service available. If there is no selection, then the Service is not listed:
If the selection is in a place where the text cannot be pasted, then only the service that copies the result is presented.
But if the text can be pasted in place, the Service is shown.
You can see a gif of this in action at this link - I’m linking to this so there isn’t a constantly repeating animation while you read this.
Of course, if you are using Emacs, you don’t want to be grabbing the mouse to get to the action, here’s a lisp function I use to format JSON in place:
(defun json-format ()
"Reformats the JSON in the region for humans."
(shell-command-on-region (mark) (point) "python -m json.tool" (buffer-name) t)))
Thanks to Chris Ridd for pointing out that I could use
We frequently (excuse the pun) need to schedule a repeated action.
The way to do this was usually to use
scheduledTimerWithTimeInterval(_:,target:,selector:,userInfo:,repeats:), which needed a callback, and had the hidden pitfall of the target being strongly referenced by the runloop that this timer was scheduled on. There are extensions to NSTimer that allow the used of blocks instead (I even wrote one myself), but there is another way.
Grand Central Dispatch provides dispatch sources for efficient interaction with the underlying system. One such source type is
DISPATCH_SOURCE_TYPE_TIMER. So here as a Swift function that creates and starts such a timer.
Since I’m passing in
NSTimeIntervals this is probably best used for short lived timers, but it extracts a lot of the C boilerplate that is needed to create the dispatch source.
In the last iOSDevWeekly Dave Verwer listed Art Sabintsev’s PrintLnMagic - a small function that reproduces the common DLog pattern that many use which not only prints a value, but the filename, the function name and the line of the call. Which is really handy in debugging.
I use a version of Dlog myself, which has the added benefit of only outputting to the console when in Debug configurations, which PrintLnMagic does not do.
So, I wrote this
I’m not overriding
printLn() because I’m not sure clobbering such a widely used system function is a good idea.
Of course Swift projects don’t work the same way as Objective-C projects, so it isn’t enough to just have the debug configuration, this needs to have the
-D DEBUG flag set in the “Other Swift Flags” section under Debug.
Installation is simple enough, this is just a single bare function, so just download the file and add it to your project. Call
loggingPrintln() just as you would
println(), only passing a value for the first parameter; the defaults will take care of the rest.
Update Feb 5, 2015
Rather than just passing an object or a value, the function can now take an expression for the first parameter. That way, the expression is only evaluated if the function body runs. Laziness is a virtue.
Update Oct 8, 2015
Changed to support Swift 2.
Thanks to rob_rix and jl_hfl for the suggestion.
In August 2014 I gave a talk at NSLondon about various approaches to solving Fizz Buzz in Swift. The video is available on Vimeo and proved to be reasonably popular and even gained me my first mention in iOS Dev Weekly.
Just to make this more complete here is a link to the slides and a Swift Playground that you can use to play around with the examples.