简体   繁体   English

协议“RawRepresentable”要求“init(rawValue:)”在 iOS 13.0.0 和更高版本中可用

[英]Protocol 'RawRepresentable' requires 'init(rawValue:)' to be available in iOS 13.0.0 and newer

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:我目前正在构建一个框架,并希望将 SwiftUI Color仅用于 iOS 14 的RawRepresentable协议。我有以下代码:

@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 .这修复了错误,但调用fatalError似乎是错误的和 hack-y 。

Thank you for any help!感谢您的任何帮助!

It seems Swift hasn't officially(or fully) supported this feature at the moment (Swift 5.3).似乎 Swift 目前尚未正式(或完全)支持此功能(Swift 5.3)。

Your codes can be reduced to the following lines:您的代码可以简化为以下几行:

// for example: in project with minimum deploy target of iOS 13.0

struct A {}

protocol B {
  var val: Int { get }
}

@available(iOS 14.0, *)
extension A: B {   
  var val: Int {  // <- Compiler Error 
    0
  }
}

// The compiler says: Protocol 'B' requires 'val' to be available in iOS 13.0.0 and newer.

The related feature was discussed in Swift forums: https://forums.swift.org/t/availability-checking-for-protocol-conformances/42066 .相关功能在 Swift 论坛中进行了讨论: https://forums.swift.org/t/availability-checking-for-protocol-conformance

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.希望当它登陆 Swift 5.4 ( https://github.com/apple/swift/blob/main/CHANGELOG.md#swift-54 ) 时,您的问题将得到解决。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM