How to silence a warning in Swift?

SwiftPragma

Swift Problem Overview


I have a piece of code which is generating lots of warnings (deprecated API)

Using clang* I could do:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    ...
#pragma clang diagnostic pop

However this does not work in Swift.

How to do it in Swift?

Note: I don't want to disable the warning globally, nor even file wide, but just disable a specific warning in a specific part of my source code.

I do not want conditional compilation (which is the proposed answer of the supposed duplicate). I just want to silence a warning WITHOUT using the new APIs.

Swift Solutions


Solution 1 - Swift

As of 2021, Xcode 13.0, the consensus is that there is no way to achieve that.

I'll update/edit this answer if Apple add the feature.

Put it in your wish list for WWDC 2022 !

Solution 2 - Swift

There is no general construct to silence deprecation warnings in Swift, but there is a workaround that can be applied in many cases.

Let's say you have a method getLatestImage() on class Foo which uses deprecated methods/classes.

Use @available as Daniel Thorpe described to silence all the warnings inside the method:

@available(iOS, deprecated: 9.0)
func getLatestImage() -> UIImage? {
    ...
}

Now you would like to call the method getLatestImage() without having a deprecation warning. You can achieve that by first defining a protocol and an extension:

private protocol GetLatestImage {
    func getLatestImage() -> UIImage?
}
extension Foo: GetLatestImage {}

And then call the method without a deprecation warning.

If foo is an instance of Foo:

(foo as GetLatestImage).getLatestImage() // no deprecation warning

If you want to call a static property/function of Foo:

(Foo.self as GetLatestImage.Type).someStaticProperty

The result is you have Swift code that uses deprecated API without any deprecation warnings.

Solution 3 - Swift

Actually, you can suppress these warnings by using @available in the enclosing logical structure (i.e. function/type).

For example, say you have some code which uses the AddressBook framework, but you're building against iOS 9.

@available(iOS, deprecated: 9.0)
func addressBookStatus() -> ABAuthorizationStatus {
    return ABAddressBookGetAuthorizationStatus()
}

As of Xcode 7.0.1 this will prevent the inline warnings from being displayed.

Solution 4 - Swift

I was having the issue for a top level function outside of a class or struct:

@available(*, deprecated)
func GetImage(url: URL) -> UIImage? { ... }

I've talked to an engineer at Apple and they told me that you can hide the implementation by a protocol and mark extensions as deprecated. Let's see how it works:

  1. Create a protocol that has a similar signature for the function you want to wrap.
  2. Use the protocol on any class or struct in an extension.
  3. Mark the extension as deprecated.

Everything that's within the extension does not bring up any deprecation warnings.

protocol ImageStoreProtocol {
    func imageFromURL(_ url: URL) -> UIImage?
}

class ImageStore {}

@available(*, deprecated)
extension ImageStore: ImageStoreProtocol {
    func imageFromURL(_ url: URL) -> UIImage? {
        return GetImage(url: url) // Warning does't show up
    }
}

Solution 5 - Swift

While there’s no way to silence deprecation warnings in Swift for now, technically you can do that for a particular symbol by editing the header file.

  • Copy the deprecated symbol name

  • Select File > Open Quickly

  • Paste the symbol and press Enter

    Make sure the Swift icon is disabled in the Open Quickly box

  • Select File > Show in Finder

  • Change file permissions to allow editing if necessary

  • Edit the deprecation macros for the symbol. See surrounding APIs for reference. E.g. replace:

> __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_10_10, __IPHONE_3_0, __IPHONE_8_0)

with

> __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)

Now there’s one less distracting warning you can do nothing about.

I know, it’s dirty. But if there’s no replacement API available in the current SDK, it should be safe. Once a new version of Xcode comes out, the change will get overwritten and you will see the warning again. Then you can test the new SDK and OS to make sure the deprecated API is still available and did not get a replacement.

Please comment if you can come up with any downsides.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAntziView Question on Stackoverflow
Solution 1 - SwiftAntziView Answer on Stackoverflow
Solution 2 - SwiftTammo FreeseView Answer on Stackoverflow
Solution 3 - SwiftDaniel ThorpeView Answer on Stackoverflow
Solution 4 - SwiftLukas WürzburgerView Answer on Stackoverflow
Solution 5 - SwiftpointumView Answer on Stackoverflow