Currently there are some compilation conditions like #if SOME
, #if swift(..)
, #if os(..)
, but it is certainly not enough of them in some cases. Examples:
Example #1
Swift 4.2 brings us Arrays that conforms to Hashable
if Element
conforms to Hashable
. So, if we want our code to compile both in Swift 4.1 and 4.2 we must write something like this:
#if swift(>=4.2)
#else
extension Array: Hashable where Element: Hashable {
public var hashValue: Int { return ... }
}
#endif
But, if we compile it with compatibility mode, compiler will yell at us:
Conformance of 'Array<Element>' to protocol 'Hashable' was already stated in the type's module 'Swift'
And there is no way we can distinguish those two compilation configurations.
Example #2
Also, there is no condition for sdk we are compiling with. Consider this:
// SDK Version 1.0:
enum Foo: Int { case a, b }
// SDK Version 2.0:
enum Foo: Int { case a, b, c }
For our code to compile with both 1.0 and 2.0 sdks we must resort to barbaric constructs, for example:
let val: Foo = ...
switch val.rawValue {
case Foo.a.rawValue: ...
case Foo.b.rawValue: ...
case Foo.b.rawVaule + 1: ...
case default: fatalError()
}
So, good it has raw value, otherwise it needed to be implemented with else if .. {..} else if .. {..}
constructs.
As you propbably know, there are times, about a couple of months in a year, when we want our code to compile with both versions of sdk, to prepare our products for future os releases, but now, it's often not a trivial task to do. So, are there any plans to improve this situation?