斯威夫特4向后兼容性

问题描述:

我有我在Xcode 8.3.3(雨燕3.1)项目下面的代码:斯威夫特4向后兼容性

let font = CGFont(provider!) 
CTFontManagerRegisterGraphicsFont(font, &error) 

但在Xcode 9 Beta版(斯威夫特4),我收到以下错误:

Value of optional type 'CGFont?' not unwrapped; did you mean to use '!' or '?'?

错误是因为现在需要CGDataProviderinitializer for CGFont返回一个可选项。

但是当我申请的修复:

let font = CGFont(provider) 
CTFontManagerRegisterGraphicsFont(font!, &error) 

的代码在Xcode 8.3.3不再编译与雨燕3.1,因为字体是不可选的,因此不与!发挥很好。

有没有办法让这两个版本的Xcode工作? Swift 4是否应该向后兼容(使用Swift 3编译器编译)?

+0

我想说这是Core Graphics中的一个突破性的变化(初始化器已经成为failable),所以它与Swift 4无关。但我认为你可以使用条件编译来解决这个问题。 –

最后我用它允许向后兼容性没有条件编译(想法来自this blog post采取)以下方法:

func optionalize<T>(_ x: T?) -> T? { 
    return x 
} 

这样在Xcode 8和9的Xcode我都可以使用:

guard let font = optionalize(CGFont(provider)) else { 
    return 
} 
CTFontManagerRegisterGraphicsFont(font, &error) 
+1

伤害了这个,但我赞成这个。 –

这是Core Graphics中非Swift本身的突破性变化。 API已经改变,初始化程序现在已经失效。

使用conditional compilation,使你的代码编译两个3.1和4.0编译器:

#if swift(>=4.0) 
let font = CGFont(provider!) 
#else 
let font = CGFont(provider)! 
#endif 

CTFontManagerRegisterGraphicsFont(font, &error) 
+0

如果我使用这个,那么即使在Xcode 9中我也注意到了我正在打'else'的情况。所以我去了我的项目设置,并将Swift语言版本更改为Swift 4.0。但现在如果我打开Xcode 8然后它抱怨一个不支持的迅速版本 –

+0

@AdamJohns也许问题是,新的编译器仍处于测试阶段,所以它可能有一个像4.0.beta版本...尝试将条件编译语句中的版本更改为3.3(或其他不存在的3.x版本)。 或者,为避免猜测,运行'swiftc --version'作为构建阶段脚本之一,以查看Xcode 9和8.3中Swift编译器的确切版本。 也许Xcode 9使用旧版本的命令行工具(检查Xcode设置中的位置选项卡)。 –