Swift 4 向后兼容

Swift 4 backwards compatibility

我在 Xcode 8.3.3 (Swift 3.1) 的项目中有以下代码:

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

但在 Xcode 9 Beta (Swift 4) 中,我收到以下错误:

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

错误是因为 initializer for CGFont 需要一个 CGDataProvider 现在 returns 一个可选的。

但是当我应用修复时:

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

代码不再在 Xcode 8.3.3 和 Swift 3.1 中编译,因为字体不是可选的,因此不能很好地与 !.[=17 一起使用=]

有没有办法在 Xcode 的两个版本中都使用此功能? Swift 4 是否应该向后兼容(使用 Swift 3 编译器编译)?

这是 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)

我最终使用了以下允许在没有条件编译的情况下向后兼容的方法(想法取自 this blog post):

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

这种方式在 Xcode 8 和 Xcode 9 中我可以使用:

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