Workarounds are a fact of life for programmers. You rarely have the ability to fix all the buggy code you have to work with, and even if you do, it might not be worth the time and effort to find and validate a proper fix. But while a workaround allows you to move forward quickly, it also creates a maintenance burden. Creative solutions like this are usually more fragile and will need to be revisited occasionally. Here are a few ways you can use the compiler to help remind you.

Swift Deprecation Attribute

@available(swift, deprecated: 5.5, message: "Verify if workarounds are still needed")
func foo() {}

This attribute will produce a warning if the selected Swift version is available in the version of Xcode you’re using. For 5.5 for example, this would generate a warning in Xcode 13.0 but not Xcode 12.5. Downside: The warning is generate at the callsite, so there would be no warning if the method isn’t actively used, due to refactoring for example.

iOS Deprecation Attribute

@available(iOS, deprecated: 14.0, message: "Verify if workarounds are still needed")
func foo() {}

Looks similar to the Swift version above, but works very differently. This attribute will produce a warning if the selected iOS (or tvOS, or macOS) version is equal to or below your deployment target. In other words, it will not be triggered by changing the Xcode version you’re using, but after you remove support for older operating systems. For the above example, no warning will be generated until your deployment target is iOS 14 or higher. The same caveat about callsites applies.

Conditional Compilation Block

func foo() {
    #if compiler(>=5.5)
    #warning("Verify if workarounds are still needed")
    #endif    
}

By using the #warning statement, you can generate a compiler warning directly at the line you want to draw attention to, regardless of whether the enclosing method is actually used. By wrapping it in this condtional compilation check, you can get Xcode to ignore the statement until you’re using an Xcode version that ships with the given compiler version.

Alternatively, you can check for the Swift version specified in your build settings like this:

func foo() {
    #if swift(>=5.5)
    #warning("Verify if workarounds are still needed")
    #endif    
}

Build Phase Script

If you want to check for the latest iOS SDK the compiler supports, or really any other arbitrary condition, you can write a build phase script that emits a warning (or error). Optionally, you can even emit filenames and line numbers to make the warnings more actionable.

if [ "$SDK_VERSION" != "14.5" ]; then
    echo "warning: Verify if workarounds are still needed"
fi

You can see what envrionment variables the build system emits by exporting the full build log from the Report Navigator.

Make sure you uncheck “Based on dependency analysis” if the script checks more complex options and needs to run every time you build. A screenshot of an example smart banner