【发布时间】:2019-04-20 04:58:41
【问题描述】:
上下文
目前正在解码包含以下元素的 JSON 数据:
{
"events": [
{
...
"rrule": "FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR",
...
}
]
}
我解析 JSON 数据并将rrule 的值收集到一个字符串中。到目前为止一切顺利,一切正常。
问题
但是,我想将 String 转换为复杂的 Swift 对象(枚举/结构)。本质上,我正在尝试根据RFC 5545 中定义的格式解析该字符串。
是否可以使用 Codable (Encodable, Decodable) 来做到这一点?我知道它与 json 数据的解析有些正交......
暂定解决方案(失败)
整个结构的简化版本(仅限于解码 FREQ)如下所示:
public struct ScheduledEventList: Codable {
public let events: [ScheduledEvent]
}
public struct ScheduledEvent: Codable {
public let title: String
public let rrule: RecurrenceSchema? = nil
public init(
title: String,
rrule: RecurrenceSchema?, <---- problem
) {
self.title = title
self.rrule = rrule
}
}
public enum RecurrenceFrequency: String, Codable {
case DAILY
case WEEKLY
case MONTHLY
case YEARLY
}
public enum RecurrenceSchema: Codable {
case FREQ(RecurrenceFrequency)
private enum CodingKeys: String, CodingKey {
case FREQ
}
public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
let value = try values.decodeIfPresent(String.self, forKey: .FREQ)
self = .FREQ(RecurrenceFrequency(rawValue: value!)!)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case .FREQ(let freq):
try container.encode(freq.rawValue, forKey: .FREQ)
}
}
}
问题是从 JSON 数据返回的元素(当然)是 String,所以它抱怨它:
错误:Playground.playground:99:12:错误:无法转换的值 将“字符串”键入预期的参数类型“RecurrenceSchema?” rrule:“频率=每周”, ^~~~~~~~~~~~~~~~
有什么建议吗?还是在解码之外构建解析器更好/更容易 - 并且只在编码/解码逻辑中处理字符串?
谢谢!
【问题讨论】:
-
Decodable 绝对不是解析重复规则的方法。如果你好奇,我写了一个 RRULE 解析器。见github.com/rmaddy/RWMRecurrenceRule
-
您需要提供自己的“编码”和“解码”路径来自定义读取/写入 JSON 的方式。首先查看Ultimate Guide to JSON Parsing with Swift 4 进行检查
-
@MadProgrammer,感谢您提供指向解析指南的指针。非常有帮助。我能够根据
RecurrenceSchema来定义ScheduledEvent:let rrule = try container.decode(RecurrenceSchema.self, forKey: .rrule)。然而,就目前而言,我需要使用解析器来提取 RRULE 值的每个成员。 -
@rmaddy,看起来
RWMRuleParser可以用parse(rule:)和rule(from:)来解决问题。是否无法通过 Carthage 进行安装? -
我不知道迦太基是什么,所以我猜不是。 :)