如何使 Swift 中的警告静音?

How to silence a warning in Swift?

我有一段代码生成了很多警告(已弃用 API)

使用 clang* 我可以做到:

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

但是这在 Swift 中不起作用。

如何在Swift中完成?

注意:我不想全局禁用警告,甚至不想在整个文件范围内禁用警告,而只是在源代码的特定部分禁用特定警告。

想要条件编译(这是假设重复的建议答案)。 我只想在不使用新的 APIs.

的情况下使警告静音

截至 2021 年,Xcode 13.0,共识是无法实现。

如果 Apple 添加此功能,我会 update/edit 这个答案。

将它放入 WWDC 2022 的愿望清单中!

实际上,您 可以 通过在封闭的逻辑结构(即 function/type)中使用 @available 来抑制这些警告。

例如,假设您有一些使用 AddressBook 框架的代码,但您是针对 iOS 9.

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

从 Xcode 7.0.1 开始,这将阻止显示内联警告。

在 Swift 中没有消除弃用警告的通用构造,但有一个可以在许多情况下应用的解决方法

假设您在 class Foo 上有一个方法 getLatestImage(),它使用已弃用的 methods/classes.

按照 Daniel Thorpe 的描述使用 @available 来消除 方法中的所有警告:

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

现在您想 调用 方法 getLatestImage() 而没有弃用警告。您可以通过首先定义协议和扩展来实现:

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

然后在没有弃用警告的情况下调用该方法。

如果fooFoo的实例:

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

如果你想调用 Foo 的静态 property/function:

(Foo.self as GetLatestImage.Type).someStaticProperty

结果是您有 Swift 使用已弃用 API 的代码,没有任何弃用警告。

虽然目前无法消除 Swift 中的弃用警告,但从技术上讲,您可以通过编辑头文件为特定符号做到这一点。

  • 复制已弃用的符号名称
  • Select File > Open Quickly
  • 粘贴符号并按Enter

    确保“快速打开”框中的 Swift 图标已禁用

  • Select File > Show in Finder

  • 更改文件权限以允许在必要时进行编辑
  • 编辑符号的弃用宏。请参阅周围的 API 以供参考。例如。替换:

__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6, __MAC_10_10, __IPHONE_3_0, __IPHONE_8_0)

__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)

现在有一个不那么令人分心的警告了,您无能为力。

我知道,它很脏。但是,如果当前 SDK 中没有可用的替代品API,它应该是安全的。一旦 Xcode 的新版本发布,更改将被覆盖,您将再次看到警告。然后您可以测试新的 SDK 和 OS 以确保已弃用的 API 仍然可用并且没有得到替代。

如果您能提出任何缺点,请发表评论。

我遇到了 class 或结构之外的顶级函数的问题:

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

我与 Apple 的一位工程师谈过,他们告诉我您可以通过协议隐藏实现并将扩展标记为已弃用。让我们看看它是如何工作的:

  1. 为要包装的函数创建一个具有相似签名的协议。
  2. 在扩展中的任何 class 或结构上使用协议。
  3. 将扩展标记为已弃用。

扩展中的所有内容都不会出现任何弃用警告。

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
    }
}