I am the author of iOS 17 Fundamentals, Building iOS User Interfaces with SwiftUI, and eight other courses on Pluralsight.
Deepen your understanding by watching!
Swift Alternative to Objective-C Macros
I’ve previously written about using enumerations in Swift to encapsulate special values that could end up falling into the “magic string” category if they were to simply be scattered in-line throughout your code. The primary example I proposed for such a “magic string” replacement was Storyboard Segue Identifiers. These special identifiers have such a specific purpose that felt to me like a natural fit to create a Type in the form of an enumeration (which I called SegueIdentifier) to group them all together in one place so that I could easily find them and modify them, should I ever need to do so.
I still like that solution for groups of things, but it’s a lot of “ceremony” to use enumerations for encapsulating everything that may have been implemented as a macro expression or a static global constant in Objective-C.
I ran across this in the Swift developer documentation that I think will be of help to folks who want to avoid “magic values” throughout their code, but don’t want to employ enumerations where they’re not the best fit. Here’s a snippet:
So there you have it, folks! One easy alternative to your former #define
habits when you’re working in Swift is to simply declare a constant (using the let
keyword) instead. The word “constant” is key – the last thing you want to do is declare a variable in some global scope (using the var
keyword) where the value of the identifier could be changed somehow, if even by accident.
Organizing #define Replacement Constants
The question that naturally comes next is, “Where do I declare a constant that I’m using to replace a #define?”
The answer is not black and white – a few factors play into your decision of where to declare them.
In general, I would probably declare such a constant in the location that’s closest to the context in which it is used. Here are a few examples to consider:
Using a globally-defined constant is exactly what I did for checking the iOS version number of a user’s device. I simply created a new file called “iOSVersions.swift”, placed my global constant definitions in it, and was able to reference those constant names everywhere in my project that I needed to perform conditional logic based on the iOS version number.
Summary
A simple Swift alternative to a #define macro in Objective-C it to define a constant at a scope that’s appropriate for where you plan to use that constant.