Description
Description
Working on a Swift package using C++ interoperability I am facing an issue handling optional values when compiling it with Mac Catalyst as target.
While principally it should be possible to use Swift Optionals in C++, the documentation also states regarding Mixing Swift and C++ Using Swift Package Manager:
Swift Package Manager does not yet provide support for using Swift APIs in C++.
Hence, I use a C++ proxy class that works around this limitation by returning a std::optional
from C++ to Swift instead:
public:
std::optional<DateTime> getDateTimeOriginal() const;
Accordingly, a Swift wrapper offers a computed getter with Optional return value:
public var dateTimeOriginal: DateTime? {
get { imageProxy.getDateTimeOriginal().value }
While targeting iOS, macOS and Linux this code compiles and runs without any issues, on MacCatalyst the compiler reports:
error: value of type 'std.__1.optional<DateTime>' has no member 'value'
get { imageProxy.getDateTimeOriginal().value }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~
Reproduction
Use above code to reproduce in a sample project.
Alternatively use my original SwiftExiv2 package to compile in Xcode with Mac Catalyst as target.
Expected behavior
Mac Catalyst should compile above code the same way successfully as it does with iOS, macOS and Linux as target.
Environment
- Swift:
swift-driver version: 1.115 Apple Swift version 6.0 (swiftlang-6.0.0.9.10 clang-1600.0.26.2) Target: arm64-apple-macosx15.0
- Xcode:
Xcode 16.0 Build version 16A242d
- Deployment target: Mac Catalyst
Additional information
The getter value
together with hasValue
are exposed by the Cxx
module most likely by calling their C++ stdlib std::optional pendants has_value()
and value()
:
extension CxxOptional {
/// Creates an instance initialized with `nil`.
public init(nilLiteral: ())
@inlinable public var hasValue: Bool { get }
@inlinable public var value: Self.Wrapped? { get }
}
In fact, above Swift getter could also be written as:
get {
let dateTime = imageProxy.getDateTimeOriginal()
return dateTime.hasValue ? dateTime.value : nil
}
This works for iOS, macOS and Linux as well.
Considering #73409 has been closed I would assume the CxxOptional
extension works for Mac Catalyst as well.
Trying to not use the extension, I was able to silence the compiler using:
get {
let dateTime = imageProxy.getDateTimeOriginal()
return dateTime.has_value() ? dateTime.pointee : nil
}
Though this code compiles for Mac Catalyst without issues, I was not able to test whether it runs due to another issue with Mac Catalyst C++ interoperability #77000 .