Swift预处理器与iOS版本检查比较的等效性是什么?
我越来越Swift预处理器与iOS版本检查比较的等效性是什么?,ios,macros,swift,Ios,Macros,Swift,我越来越 yld: Symbol not found: _OBJC_CLASS_$_UIUserNotificationSettings 当应用程序在iOS7设备上运行时,甚至没有在代码中调用该函数,这就是导致错误的函数 我不希望在iOS7设备上运行时可以访问此方法。我不希望在它里面有一个select检查,因为这意味着该方法可以从一开始就使用 我需要一个build config参数来检查版本: 我想不出一种方法来编写一个等效于swift的预处理器宏来检查iOS版本是否正确,而忽略新的和未声明的
yld: Symbol not found: _OBJC_CLASS_$_UIUserNotificationSettings
当应用程序在iOS7设备上运行时,甚至没有在代码中调用该函数,这就是导致错误的函数
我不希望在iOS7设备上运行时可以访问此方法。我不希望在它里面有一个select检查,因为这意味着该方法可以从一开始就使用
我需要一个build config参数来检查版本:
我想不出一种方法来编写一个等效于swift的预处理器宏来检查iOS版本是否正确,而忽略新的和未声明的iOS 8库函数
#if giOS8OrGreater
// declare the functions that are iOS 8 specific
#else
// declare the functions that are iOS 7 specific
#endif
在文档中,苹果建议用函数和泛型来代替复杂的宏,但在这种情况下,我需要进行构建配置预编译检查,以避免处理未声明的函数。任何建议。根据苹果公司的说法,Swift中没有预处理器调用,但Swift代码可以根据两个函数中构建配置的评估有条件地编译。现在,我们得到 操作系统可选择OSX或iOS,arch可选择x86_64、arm、arm64或i386。因此,您可以评估osiOS是否可用,但不能评估osiOS8是否可用,尽管这对于Swift的后续版本来说似乎是个好主意。更新:这在Xcode 6 beta 6 build 6A280e中得到了修复 这里有一个可能不是很好的解决方法:显式链接到UIKit。我知道import语句应该已经链接到框架了,但我们还是显式链接到框架 单击Xcode中的项目 在左上角的下拉列表中选择目标 转到“常规”选项卡 向下滚动到链接的框架和库 添加UIKit.framework 将状态从必需更改为可选 这可能会导致所有UIKit都弱链接,从而影响性能。不确定 在Objective-C中,即使使用Required,编译器也会自动弱链接可用性高于部署目标的符号,并使其他符号保持强链接。我不知道为什么这不适用于Swift。在常量中。Swift: Swift 1: Swift 2:
var systemVersion=UIDevice.currentDevice.systemVersion您可以通过以下方式检查iOS版本-
let iosVersion = UIDevice.currentDevice().systemVersion
并使用NSStringCompareOptions.NumericSearch进行比较
switch iosVersion.compare("8.0.0", options: NSStringCompareOptions.NumericSearch)
{
case .OrderedSame, .OrderedDescending:
//iOS>=8.0.0
return LAContext()
case .OrderedAscending:
//iOS<8.0.0
return nil
}
你可以看到更多的细节。希望这能解决您的疑问。其他答案没有提到检查系统版本的正确方法。绝对不要使用:Device.systemVersion 您不应该制作自定义宏来检查版本号,也不应该挖掘超出Apple为此任务专门定义的库之外的内容 有一篇很棒的文章详细介绍了这一点 请注意,Swift 2.0允许您通过以下方式直接检查操作系统版本号是否可用:
if #available(iOS 10.0, *) {
// modern code
} else {
// Fallback on earlier versions
}
在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
}
或通过:
if NSProcessInfo().isOperatingSystemAtLeastVersion(NSOperatingSystemVersion(majorVersion: 10, minorVersion: 0, patchVersion: 0)) {
// modern code
}
查找系统宏以外缺少的任何内容
任何其他方法都被低估为不可靠,苹果也不推荐。实际上有一种方法将在iOS 10中突破
请注意,如果检查中需要类似宏的功能,并且希望使用available,则可以使用中定义的@available:
有关Swift属性的更多信息,请参考 有什么理由不在运行时检查它吗?事实上,我不确定您是否可以在编译时检查它,因为否则它只能在iOS8及更高版本或iOS7及更低版本上运行。您不应该使用版本比较来检查Objective-C各种方案中的可选功能,包括检查nil和respondsToSelector,或者在swift中使用可选检查和可选链接。NSHipster在NSProcessInfo.isoperatingSystemMatleAstVersionOsemite上的帖子似乎在检查OS X是否为约塞米蒂。不确定它是否适用于iOS。您可以将:var systemVersion=UIDevice.currentDevice.systemVersion作为NSString.floatValue执行,但它无论如何不会在iOS 7上工作,因为如果编译的代码对新框架API有任何引用,它将崩溃,并且找不到符号:_OBJC_CLASS_$_UIUserNotificationSettings底线是您不能在运行时检查它//cc@mihot这似乎在Xcode 6 beta 6中得到了修复,这本来是不错的,但不幸的是,如果osiOS没有降低操作系统版本,您就不能使用这种情况。但是,如果我调用一些仅在iOS8上可用的方法,当我尝试为目标iOS 7构建时,它会显示错误,例如:skShareNodeBu立…请尝试swift 2版本很可怕,不推荐。参考我的回答。很好。我需要@available语法使一个类符合苹果相关协议的新登录,这些协议只能从iOS 13上获得,而不需要放弃对旧版本操作系统的支持。您只需使用此标记标记符合协议的扩展,如@availableiOS 13,*扩展名MyClass:ASAuthorizationC 遥控器遥控门。工作完美。
switch iosVersion.compare("8.0.0", options: NSStringCompareOptions.NumericSearch)
{
case .OrderedSame, .OrderedDescending:
//iOS>=8.0.0
return LAContext()
case .OrderedAscending:
//iOS<8.0.0
return nil
}
if NSProcessInfo().isOperatingSystemAtLeastVersion(NSOperatingSystemVersion(majorVersion: 8, minorVersion: 0, patchVersion: 0)) {
//iOS>=8.0.0
}
if #available(iOS 10.0, *) {
// modern code
} else {
// Fallback on earlier versions
}
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_9_0) {
// do stuff for iOS 9 and newer
} else {
// do stuff for older versions than iOS 9
}
if NSProcessInfo().isOperatingSystemAtLeastVersion(NSOperatingSystemVersion(majorVersion: 10, minorVersion: 0, patchVersion: 0)) {
// modern code
}
@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
}