Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/102.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift预处理器与iOS版本检查比较的等效性是什么?_Ios_Macros_Swift - Fatal编程技术网

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
}