@available 与调用方进行沟通

12/5/2021 swiftios

# @available 与调用方进行沟通

保持代码不变很难,因为需求不断在变化,系统、框架不断在更新。那么项目实践中,往往会废弃掉一些类或方法。如果是自己独立维护代码,且不需要将代码给他人使用,废弃 API 对你来说是非常简单的,直接改动源码即可。但是对于多人合作的项目,特别是开源的库,废弃一个公开的 API 不是简单的改动下代码就可以,因为你的改动将会影响使用你这个库的所有代码。公开的 API 的更新换代,就相当于你改动了和别人约定的契约一样,这也侧面反映了作者的专业水平。

那么如果要废弃一个 API,在 Swift 中我们该如何做?

# 小案例

Swift 提供了 @available 注解。可以简单地将其附加到特定方法甚至整个类:

@available(*, deprecated)
func oldMethod(value: Int) {
    print(value)
}

这会就会出现以下警告:

-w394

如果我们要给废弃的 API,添加更多的废弃信息,我们可以这样:

@available(*, deprecated, message: "不要再使用该方法了")
func oldMethod(value: Int) {
    print(value)
}

message 设置为 不要再使用该方法了,提示效果如下:

-w639

通常,废弃了一个 API,如果能提示调用方可以使用的新 API 是什么,那就非常完美了。如需要将旧的 API 改名,就可以这么做:

@available(*, deprecated, renamed: "newMethod(number:)", message: "不要再使用该方法了")
func oldMethod(value: Int) {
    print(value)
}

func newMethod(number: Int) {
    print("值为:\(number)")
}

添加 renamed 后,我们的旧方法调用:

-w992

这种警告是可以展开的:

-w981

可以点击 Fix 按钮,代码将自动替换为新的 API。

# @available 归类

@available 有这么几种声明:

# 约束平台和版本

@available(platform version , platform version ..., *)

举例:

@available(iOS 14, *)
class AppIntro {
}

在调用的时候,我们需要通过 #available

if #available(iOS 14, *) {
    let appIntro = AppIntro()
} else {
    // .. 14以下的版本调用
}

当然我们也可以指定多个平台:

@available(iOS 14, macOS 11.0, *)
class AppIntro {
}

# 约束 swift 版本

@available(swift version)

比如需要 Swift 5.5 或更高版本才能使用 oldMethod

@available(swift 5.5)
func oldMethod(value: Int) {
    print(value)
}

# 约束指定平台的 introduced, deprecated, obsoleted 和 unavailable

// With introduced, deprecated, and/or obsoleted
@available(platform | *
          , introduced: version , deprecated: version , obsoleted: version
          , renamed: "..."
          , message: "...")

// With unavailable
@available(platform | *, unavailable , renamed: "..." , message: "...")
  • platform:平台名称
  • introduced:开始引进的版本号
  • deprecated:从指定平台开始过期的版本
  • obsoleted:从指定平台开始废弃的版本(注意弃用的区别,deprecated 是还可以继续使用,只不过是不推荐了,obsoleted 是调用就会编译错误)
  • message:给出一些附加信息
  • renamed:重命名后的新名称
  • unavailable:指定平台上是无效的

这些参数可以相互组合使用。下面列举几个常用案例:

@available(iOS 13, *)
@available(tvOS, unavailable)
@available(macCatalyst, unavailable)
func handleShakeGesture() {}

# 总结

正确的使用@available注解可以增强你和你的 API 使用者之间的沟通,新旧 API 替换体验会变得友好很多。

# 参考

上次更新: 6/18/2022, 10:39:15 AM