快速返回枚举,根据大小写类型为字符串或整数

时间:2018-07-01 09:34:28

标签: swift enums swift4 eureka-forms decodable

尝试使用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。

1 个答案:

答案 0 :(得分:0)

实际上,IntRowTextRow行将仅接受为其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

enter image description here

然后您可以如下更新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
}