【问题标题】:Protocol 'RawRepresentable' requires 'init(rawValue:)' to be available in iOS 13.0.0 and newer协议“RawRepresentable”要求“init(rawValue:)”在 iOS 13.0.0 及更高版本中可用
【发布时间】:2021-03-16 01:13:22
【问题描述】:

我目前正在构建一个框架,并希望使 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()
    }
}

但是,这会导致两个类似的错误:

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

这不可能吗?我可以将代码修改为:

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")
    }
}

这修复了错误,但调用fatalError 似乎是错误的和hack-y。

感谢您的帮助!

【问题讨论】:

  • 你项目的最低部署目标版本是13.0吗?
  • @Sweeper 是的,它是一个针对 iOS 13 的框架,但我想为在 iOS 14 上使用它的人添加它
  • @YulkyTulky 你的问题不是 iOS14。您的问题是在 iOS 13 中没有将 Color 转换为 UIColor 的传统方法。有一些 hackie 解决方案,但可能不值得使用它们。

标签: ios swift swiftui protocols rawrepresentable


【解决方案1】:

目前看来 Swift 还没有正式(或完全)支持这个功能(Swift 5.3)。

您的代码可以简化为以下几行:

// 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.

Swift 论坛讨论了相关功能:https://forums.swift.org/t/availability-checking-for-protocol-conformances/42066

希望当它登陆 Swift 5.4 (https://github.com/apple/swift/blob/main/CHANGELOG.md#swift-54) 时,你的问题会得到解决。

【讨论】:

    猜你喜欢
    • 2017-07-11
    • 2017-08-24
    • 2021-11-15
    • 2016-03-28
    • 1970-01-01
    • 2016-04-30
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    相关资源
    最近更新 更多