I am currently building a framework, and would like to conform SwiftUI Color
to the RawRepresentable
protocol only for iOS 14. I have the following code:
@available(iOS 14.0, *)
extension Color: RawRepresentable {
public init?(rawValue: Data) {
let uiColor = try? NSKeyedUnarchiver.unarchivedObject(ofClass: UIColor.self, from: rawValue)
if let uiColor = uiColor {
self = Color(uiColor)
} else {
return nil
}
}
public var rawValue: Data {
let uiColor = UIColor(self)
return (try? NSKeyedArchiver.archivedData(withRootObject: uiColor, requiringSecureCoding: false)) ?? Data()
}
}
However, this results in two similar errors:
Protocol 'RawRepresentable' requires 'init(rawValue:)' to be available in iOS 13.0.0 and newer
Protocol 'RawRepresentable' requires 'rawValue' to be available in iOS 13.0.0 and newer
Is this not possible? I am able to modify the code to:
extension Color: RawRepresentable {
public init?(rawValue: Data) {
let uiColor = try? NSKeyedUnarchiver.unarchivedObject(ofClass: UIColor.self, from: rawValue)
if let uiColor = uiColor {
self = Color(uiColor)
} else {
return nil
}
}
public var rawValue: Data {
if #available(iOS 14, *) {
let uiColor = UIColor(self)
return (try? NSKeyedArchiver.archivedData(withRootObject: uiColor, requiringSecureCoding: false)) ?? Data()
}
fatalError("do not use Color.rawValue on iOS 13")
}
}
This fixes the error, but it seems wrong and hack-y to call a fatalError
.
Thank you for any help!
It seems Swift hasn't officially(or fully) supported this feature at the moment (Swift 5.3).
Your codes can be reduced to the following lines:
The related feature was discussed in Swift forums: https://forums.swift.org/t/availability-checking-for-protocol-conformances/42066.
And hopefully when it lands in Swift 5.4 ( https://github.com/apple/swift/blob/main/CHANGELOG.md#swift-54), your problem would be solved.