为 URL 类型实现 KeyedDecodingContainerProtocol



我正在做一个项目,创建一个自定义Decoder来处理非JSON数据。

要解码的数据可以是URL秒或String秒。例如:

struct MyData: Decodable {
let server: URL
let version: String
}

为了处理这种类型的解码,我实现了一个名为KeyedContainer的类,它实现了KeyedDecodingContainerProtocol

对于String非常简单,因为我可以使用以下方法:

func decode(_ type: String.Type, forKey key: Key) throws -> String { }

对于URL,相反,我需要依靠以下内容:

func decode<T>(_ type: T.Type, forKey key: Key) throws -> T where T: Decodable { }

在其中,我执行以下操作:

func decode<T>(_ type: T.Type, forKey key: Key) throws -> T where T: Decodable {
try checkCanDecodeValue(forKey: key)
guard let value = configuration[key.stringValue] else {
let context = DecodingError.Context(codingPath: codingPath, debugDescription: "TODO")
throw DecodingError.typeMismatch(type, context)
}
guard let url = URL(string: value) else {
let context = DecodingError.Context(codingPath: codingPath, debugDescription: "TODO")
throw DecodingError.valueNotFound(type, context)
}
return url as! T
}

其中configuration是从自定义解码器直接传递给KeyedContainer的结构。

这是正确的方法吗?我不确定的是为了让编译器满意而as! T强制转换。

如果你这样做,我不相信你必须硬投到 T:

guard let url = URL(string: value) as? T else {
let context = DecodingError.Context(codingPath: codingPath, debugDescription: "TODO")
throw DecodingError.valueNotFound(type, context)
}

相关内容

  • 没有找到相关文章

最新更新