尝试使用Swift的Codable库返回JSON输出。我设置了一个结构以从JSON捕获“默认”值。当前,“默认”值具有两个数据类型输出,即字符串或整数。如果“默认”为字符串,则尝试返回字符串值,如果为int,则尝试返回int值。
struct Settings: Codable {
let configDefault: IntOrString
let name: String?
}
enum IntOrString: Codable {
case integer(Int)
case string(String)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let int = try? container.decode(Int.self) {
self = .integer(int)
return
}
if let string = try? container.decode(String.self) {
self = .string(string)
return
}
throw DecodingError.typeMismatch(IntOrString.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for Default"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .integer(let x):
try container.encode(x)
case .string(let x):
try container.encode(x)
}
}
}
所有这些都解码为值defaultValueHolder
let defaultValueHolder = try JSONDecoder().decode(Settings.self, from: jsonString)
我使用Eureka的表单库试图将表值设置为从JSON返回的默认String或Int。
form +++ Section ("Values")
// dynamically generates rows
for values in defaultValueHolder {
form.last! <<< IntRow() {
$0.tag = values.name
$0.title = values.name
$0.value = values.IntOrString
}
问题是当尝试向$ 0.value添加值时,我无法将其强制转换为IntORString枚举类型,而必须返回int或字符串,具体取决于是否声明了IntRow或TextRow。
答案 0 :(得分:0)
实际上,IntRow
和TextRow
行将仅接受为其cells定义的类型,如下所示,
open class IntCell: _FieldCell<Int>, CellType
open class TextCell: _FieldCell<String>, CellType
这就是为什么您必须从IntOrString
枚举type
中提取值以将其分配给相应的cell's
row
的原因。
如果,您希望有一行接受您的类型(IntOrString
),那么您就必须将新类型与Equatable
一样,作为尤里卡cell
'接受符合Equatable
的值类型。如下所示,
enum IntOrString: Codable, Equatable
然后,您应添加带有标记为cell
的新create xib file
,以创建如下所示的自定义view
,
然后您可以如下更新IntOrStringTableViewCell
,
import UIKit
import Eureka
class IntOrStringTableViewCell: Cell<IntOrString>, CellType {
@IBOutlet private weak var valueLabel: UILabel!
override func setup() {
super.setup()
self.updateValue()
}
override func update() {
super.update()
self.updateValue()
}
private func updateValue() {
guard let value = self.row.value else { return }
if case .integer(let int) = value {
self.valueLabel.text = "\(int)"
} else if case .string(let string) = value {
self.valueLabel.text = string
}
}
}
final class IntOrStringRow: Row<IntOrStringTableViewCell>, RowType {
required init(tag: String?) {
super.init(tag: tag)
self.cellProvider = CellProvider<IntOrStringTableViewCell>(nibName: "IntOrStringTableViewCell", bundle: Bundle.main)
}
}
现在,当您使用此行时,将可以按原样分配IntOrString
值,而无需进行任何强制转换
form +++ Section ("Values")
// dynamically generates rows
for values in defaultValueHolder {
form.last! <<< IntOrStringRow() {
$0.tag = values.name
$0.title = values.name
$0.value = values.IntOrString
}