什么是Swift预处理器相当于iOS版本检查比较?

Ess*_*dad 18 macros ios swift

我正进入(状态

yld: Symbol not found: _OBJC_CLASS_$_UIUserNotificationSettings
Run Code Online (Sandbox Code Playgroud)

这是当应用程序在iOS7设备上运行时甚至根本没有在代码中调用该函数导致错误的函数.

func reigsterForRemoteUserNotifications(notificationTypes: UIUserNotificationType, categories: NSSet) {
        let userNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: categories)
        (UIApplication.sharedApplication()).registerUserNotificationSettings(userNotificationSettings)
        UIApplication.sharedApplication().registerForRemoteNotifications()
    }
Run Code Online (Sandbox Code Playgroud)

我不希望在iOS7设备上运行时可以访问此方法.我不希望在其中进行选择检查,因为这意味着该方法可用于开始.

我想要的是一个构建配置参数来检查版本:我无法找到一种方法来编写一个快速等效的预处理器宏来检查正确的iOS版本并忽略新的和未声明的iOS 8库函数.

#if giOS8OrGreater
// declare the functions that are iOS 8 specific
#else 
// declare the functions that are iOS 7 specific

#endif
Run Code Online (Sandbox Code Playgroud)

在文档中,apple建议使用函数和泛型来替换复杂的宏,但在这种情况下,我需要构建配置预编译检查以避免处理未声明的函数.有什么建议.

The*_*Art 18

其他答案没有提到检查系统版本的正确方法.您绝对不应该使用:Device.systemVersion 您不应该使用自定义宏来检查版本号,并且您不应该超越Apple专门为此任务定义的库.

这里有一篇很好的文章详细介绍了这一点.

请注意,Swift 2.0允许您通过以下方式直接检查OS版本号是否可用:

if #available(iOS 10.0, *) {
    // modern code
} else {
    // Fallback on earlier versions
}
Run Code Online (Sandbox Code Playgroud)

在Swift 2.0之前,推荐的方法是通过提供的系统宏:

    if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_9_0) {
    // do stuff for iOS 9 and newer
} else {
    // do stuff for older versions than iOS 9
}
Run Code Online (Sandbox Code Playgroud)

或通过:

    if NSProcessInfo().isOperatingSystemAtLeastVersion(NSOperatingSystemVersion(majorVersion: 10, minorVersion: 0, patchVersion: 0)) {
    // modern code
}
Run Code Online (Sandbox Code Playgroud)

对于系统宏之外的任何遗漏.

任何其他方法都被认为是不可靠的,而不是Apple推荐的方法.实际上有一种方法会在iOS 10中破解.

请注意,如果您在检查中需要宏功能,并且您想要使用#available,则可以使用本文中@available定义的内容:

 @available(iOS 7, *)
func iOS7Work() {
    // do stuff

    if #available(iOS 8, *) {
        iOS8Work()
    }
}

@available(iOS 8, *)
func iOS8Work() {
    // do stuff
    if #available(iOS 9, *) {
        iOS9Work()
    }
}

@available(iOS 9, *)
func iOS9Work() {
    // do stuff
}
Run Code Online (Sandbox Code Playgroud)

有关Swift中属性的更多信息,可以参考Apple的文档.


Chi*_*buZ 12

Constants.swift:

斯威夫特1:

let Device = UIDevice.currentDevice()
private let iosVersion = NSString(string: Device.systemVersion).doubleValue
Run Code Online (Sandbox Code Playgroud)

斯威夫特2:

let Device = UIDevice.currentDevice()
private let iosVersion = Double(Device.systemVersion) ?? 0 

let iOS8 = iosVersion >= 8
let iOS7 = iosVersion >= 7 && iosVersion < 8
Run Code Online (Sandbox Code Playgroud)

然后在其他文件中

if iOS8
{

}
else
{

}
Run Code Online (Sandbox Code Playgroud)


Gle*_*Ray 3

据苹果公司称,Swift 中没有预处理器调用,但可以根据两个函数中构建配置的评估来有条件地编译 Swift 代码。目前,我们可以 os()选择 OSX 或 iOS,也arch()可以选择 x86_64、arm、arm64 或 i386。因此,您可以评估#if os(iOS),但不能评估#if os(iOS8)(尽管这对于 Swift 的后续版本来说确实是一个好主意)。