在Swift中检测可用的API:iOS与watchOS。

39

#available 在区分 watchOS 和 iOS 时似乎无法正常工作。

以下是在 iOS 和 watchOS 之间共享的代码示例:

lazy var session: WCSession = {
    let session = WCSession.defaultSession()
    session.delegate = self
    return session
}()

...

if #available(iOS 9.0, *) {
    guard session.paired else { throw WatchBridgeError.NotPaired } // paired is not available
    guard session.watchAppInstalled else { throw WatchBridgeError.NoWatchApp } // watchAppInstalled is not available
}

guard session.reachable else { throw WatchBridgeError.NoConnection }

看起来它只默认为WatchOS,并且编译器不考虑#available

我是不是在错误地使用这个API,或者还有其他区分iOS和WatchOS的方法吗?

更新:正如BPCorp所提到的,似乎我误用了API

使用Tali的解决方案可以解决上述代码:

    #if os(iOS)
        guard session.paired else { throw WatchBridgeError.NotPaired }
        guard session.watchAppInstalled else { throw WatchBridgeError.NoWatchApp }
    #endif

    guard session.reachable else { throw WatchBridgeError.NoConnection } 

很遗憾,在Xcode 7 GM版本中没有#if os(watchOS) ..

编辑:不确定是何时添加的,但你现在可以在Xcode 7.2中使用#if os(watchOS)


1
如果有错误,您可以等待“稳定的Xcode 7”,无论如何,您将无法从beta Xcode上传应用程序到App Store。 - Aks
@Aks,我误用了API,这不是一个 bug。看一下BPCorp的回答。 - Cezar
4个回答

28
如果您只想在iOS上执行该代码,则请使用#if os(iOS)而不是if #available(iOS ...)
这样,您不会对操作系统版本进行动态检查,而是为一个操作系统或另一个操作系统编译不同的代码。

6
Apple dev guide中提到,星号*(必须)表示它将执行未指定但列在目标最低部署目标中的操作系统的if体。
因此,如果您的目标指定了iOSwatchOS,则语句if #available(iOS 9.0, *)的意思是if体可用于iOS 9及更高版本任何watchOS版本。
此外,如果您想使用本Apple guide中描述的“构建配置”章节中的内容,请注意。它用于根据操作系统有条件地编译您的代码。这不是运行时动态的。

4

我认为,在 Xcode 7 的 GM 版本中,他们解决了这个问题。对我来说:

if #available(watchOS 2,*) {
    // Only if using WatchOS 2 or higher
}

在GM版本中运行良好。

1
对于我来说,交叉编译的代码无法工作。相反,使用#if os(iOS)可以解决问题。 - Cezar
我也无法使用,而且 #if os(watchOS) 可以工作。 - vicegax

1

这个问题已经过去了一段时间。如果还有人在寻找答案,需要说明的是:
#if os(watchOS)
现在在Xcode 13及更高版本中可用


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接