Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 4 backwards compatibility

Tags:

ios

swift

swift4

I have the following code in my project in Xcode 8.3.3 (Swift 3.1):

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

But in Xcode 9 Beta (Swift 4), I get the following error:

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

The error is because the initializer for CGFont that takes a CGDataProvider now returns an optional.

But when I apply the fix of:

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

The code no longer compiles in Xcode 8.3.3 with Swift 3.1 since font is not an optional and thus doesn't play nicely with the !.

Is there a way to make this work in both versions of Xcode? Is Swift 4 supposed to be backwards compatible (compile with Swift 3 compiler)?

like image 826
Adam Johns Avatar asked Jun 20 '17 21:06

Adam Johns


People also ask

Can SwiftUI run on iOS 12?

SwiftUI runs on iOS 13, macOS 10.15, tvOS 13, and watchOS 6, or any future later versions of those platforms. This means if you work on an app that must support iOS N-1 or even N-2 – i.e., the current version and one or two before that – then you will be limited in terms of the features you can offer.

Is async await backwards compatible?

Discover page available: Concurrency With the above in place, the compiler error within our ModelLoader is now gone, as we're now able to easily perform URLSession -based network calls using async/await, even within a backward-compatible code base.

Which systems are backwards compatible?

Video games and consoles The Atari 2600 with the Atari 5200 and 7800. The Sega Genesis with the Sega Master System via add-on component. The Nintendo Game Boy Color with the original Game Boy. The Microsoft Xbox 360 and the Xbox One can support some games released for their predecessors with emulation functionality.

Can I use async await in iOS 14?

Curia Damiano. Swift 5.5 has initially introduced async/await for iOS 15. With a very welcome news, Xcode 13.2 has extended support of async/await to previous versions iOS 13 and 14.


2 Answers

This is a breaking change in Core Graphics not in Swift itself. API has changed, the initializer is now failable.

Use conditional compilation to make your code compile with both 3.1 and 4.0 compiler:

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

CTFontManagerRegisterGraphicsFont(font, &error)
like image 193
Andrii Chernenko Avatar answered Oct 13 '22 11:10

Andrii Chernenko


I ended up using the following method which allowed for backwards compatibility without conditional compilation (idea taken from this blog post):

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

This way in both Xcode 8 and Xcode 9 I could use:

guard let font = optionalize(CGFont(provider)) else {
    return
}
CTFontManagerRegisterGraphicsFont(font, &error)
like image 35
Adam Johns Avatar answered Oct 13 '22 11:10

Adam Johns