Conditionally compile based on iOS version? (previewCGImageRepresentation broke)

There are plenty of conditional compile options in Swift, but none seem to address my need:

I’ve run into an issue where Xcode 13b2 (iOS 15 SDK) changed the Swift return type of AVCapturePhoto.previewCGImageRepresentation(). In Xcode 12.5.1 (iOS 14 SDK), this method returns Unmanged<CGImage>. In 13b2 - 13b4, it returns CGImage?.

I need my code to compile under both Xcode versions, since Xcode 13 has other issues, and can’t be used to submit builds to the App Store. I thought I was clever writing this, but it won’t compile, because it’s not conditional code compilation check but rather a runtime check:

extension AVCapturePhoto {
    func stupidOSChangePreviewCGImageRepresentation() -> CGImage? {
        if #available(iOS 15, *) {
            return self.previewCGImageRepresentation()
        } else {
            return self.previewCGImageRepresentation()?.takeUnretainedValue()
        }
    }
}

Another possibility might be to create a user-defined Xcode setting, but I don’t think that can be done conditionally based on Xcode or SDK version.

There might be some unsafe pointer histrionics one can do…

Any other ideas?

Since both the SDK version and the compiler version are tied to an Xcode release, you can use the #if compiler directive as a stand-in for the SDK version:

import AVFoundation

extension AVCapturePhoto {
  func stupidOSChangePreviewCGImageRepresentation() -> CGImage? {
    #if compiler(>=5.5)
      // iOS 15+ SDK, macOS 12+ SDK
      return self.previewCGImageRepresentation()
    #else
      return self.previewCGImageRepresentation()?.takeUnretainedValue()
    #endif
  }
}
3 Likes

Ahh, thank you!

1 Like

I've used setValue(forKey:) for some new Xcode 13 APIs. You would use value(forKey:).