保持NSUserActivity向后兼容Xcode 9

问题描述 投票:1回答:2

使用Xcode 10(beta 6),我可以毫无困难地编写和运行以下代码:

import Intents

func test() {

    let activity = NSUserActivity(activityType: "com.activtiy.type")

    activity.title = "Hello World"
    activity.isEligibleForSearch = true
    activity.isEligibleForHandoff = false

    if #available(iOS 12.0, *) {
        activity.isEligibleForPrediction = true
        activity.suggestedInvocationPhrase = "Say something"
    }

    print(activity)
}

从iOS 12开始,添加了.isEligibleForPredictions.suggestedInvocationPhrase属性,因此Xcode 10可以使用if #available条件使代码本身向后兼容。

但是,我想确保此代码向后兼容早期版本的Xcode。在Xcode 9中运行时,我收到以下错误:

if #available(iOS 12.0, *) {
        // ERROR: Value of type 'NSUserActivity' has no member 'isEligibleForPrediction'
        activity.isEligibleForPrediction = true

        // ERROR: Value of type 'NSUserActivity' has no member 'suggestedInvocationPhrase'
        activity.suggestedInvocationPhrase = "Say something"
    }

这似乎是因为#available宏实际上是在运行时解析的,因此所有包含的代码仍然需要成功编译。

有没有办法告诉编译器在构建iOS 11或使用Xcode 9时忽略这两行代码?

ios swift xcode xcode10
2个回答
1
投票

Xcode 10使用Swift 4.2,而Xcode 9使用Swift 4.1。所以你可以在编译时使用这些知识:

func test() {
    let activity = NSUserActivity(activityType: "com.activtiy.type")

    activity.title = "Hello World"
    activity.isEligibleForSearch = true
    activity.isEligibleForHandoff = false

    #if swift(>=4.2) // compile-time check
    if #available(iOS 12.0, *) { // run-time check
        activity.isEligibleForPrediction = true
        activity.suggestedInvocationPhrase = "Say something"
        predictionApiAvailable = true
    }
    #endif

    print(activity)
}

(这个答案假设您在Xcode 10上使用Swift 4.2。)


1
投票

您正确使用的可用性条件(如果#available)在运行时进行评估,但编译器将使用此信息来提供编译时安全性(如果您调用的API不是,它会发出警告存在最小部署目标)。

对于有条件编译代码,您必须使用Conditional Compilation Block

#if compilation condition
statements
#endif

要根据Xcode版本有条件地构建代码,可以在构建设置中包含一个Active Compilation Condition(一个-D swift编译标志),它的名称是根据Xcode版本动态创建的。然后使用它作为编译条件。 Xcode已经提供了解析为当前Xcode版本的构建设置XCODE_VERSION_MAJOR(例如,Xcode 9的0900)。因此,您可以添加名为XCODE_VERSION _ $(XCODE_VERSION_MAJOR)的活动编译条件,该条件将解析为Xcode 9的标志XCODE_VERSION_0900。

enter image description here

然后您可以使用以下方法有条件地编译代码:

#if XCODE_VERSION_0900
statements
#endif

我有一个示例项目here

© www.soinside.com 2019 - 2024. All rights reserved.