Detecting available API iOS vs. watchOS in Swift

时间:2015-09-01 22:58:47

标签: ios swift2 watch-os watch-os-2

#available does not seem to work when differentiating between watchOS and iOS.

Here is an example of code shared between 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 }

Seems that it just defaults to WatchOS and the #available is not considered by the compiler.

Am I misusing this API or is there any other way to differentiate in code between iOS and WatchOS?

Update: Seems like I was misusing the API as mentioned by BPCorp

Using Tali's solution for above code works:

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

Unfortunately there is no #if os(watchOS) .. as of Xcode 7 GM

Edit: Not sure when it was added but you can now do #if os(watchOS) on Xcode 7.2

2 个答案:

答案 0 :(得分:21)

如果您只想在iOS上执行该代码,请使用#if os(iOS)代替if #available(iOS ...)

这样,您不会对操作系统的版本使用动态检查,而是为一个操作系统或另一个操作系统编译不同的代码。

答案 1 :(得分:5)

Apple dev guide中,据说明星*(这是必需的)意味着它将为未指定但在最低部署中列出的操作系统执行if主体目标指定的目标。

因此,如果您的目标指定了iOS watchOS,那么您的语句if #available(iOS 9.0, *)意味着if正文可用于iOS 9及更高版本任何watchOS版本。

另外,如果您想使用本Apple guide中“构建配置”一章中描述的内容,请务必小心。它用于根据操作系统有条件地编译代码。这在运行时不是动态的。