Swift -如何通过Case Let访问模型变量

8ftvxx2r  于 2023-10-15  发布在  Swift
关注(0)|答案(2)|浏览(102)

需要一些帮助来获取json中的值。我想访问radioButton对象并访问description值(例如,竞争对手的其他产品有更好的产品)以分配给tileView.title,如下所示:

for viewContent in viewModel.contents {
            switch viewContent {
            case let .radioButtonGroup(radioButtonGroupModel):
                for i in 0..<radioButtonGroupModel.options.count {
                    let tileView = TileRadio()
                    tileView.title = radioButtonGroupModel.options...

打印此**print(radioButtonGroupModel.options[i])**得到:

radioButton(RadioButtonModel(description: "Other Products from Competitors have better product", identifier: "competitorReason"))

下面是JSON解码器的代码库:

enum ComponentModel: Decodable {

    case radioButtonGroup(RadioButtonGroupModel)
    case radioButton(RadioButtonModel)
    case emptyComponent

    enum CodingKeys: String, CodingKey {
        case radioButtonGroup
        case radioButton
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        do {
            switch container.allKeys.first {

            case .radioButtonGroup:
                let value = try container.decode(RadioButtonGroupModel.self, forKey: .radioButtonGroup)
                self = .radioButtonGroup(value)
            case .radioButton:
                let value = try container.decode(RadioButtonModel.self, forKey: .radioButton)
                self = .radioButton(value)
            case .none:
                self = .emptyComponent
            }
        } catch {
            self = .emptyComponent
        }
    }
}

struct RadioButtonGroupModel: Decodable {
    let options: [ComponentModel]
}

struct RadioButtonModel: Decodable {
    let description: String
    let identifier: String
}

下面是部分JSON文件:

"closureReasons": {
        "pageTitle": "Close account",
        "content": [
 
            {
                "heading": {
                    "title": "Why are you closing this account?"
                }
            },
            {
                "spacing": ".spacing3x"
            },
            {
                "radioButtonGroup": {
                    "options": [
                        {
                            "radioButton": {
                                "identifier": "competitorReason",
                                "description": "Other Products from Competitors have better product"
                            }
                        },
                        {
                            "radioButton": {
                                "identifier": "betterReason",
                                "description": "I found a better product"
                            }
                        },

任何关于如何检索radioButton属性的想法?谢谢你的帮助

0mkxixxg

0mkxixxg1#

for循环也可以与case let进行模式匹配:

for case let .radioButton(radioButtonModel) in radioButtonGroupModel.options {
    print(radioButtonModel.description)
}

这将遍历options中所有.radioButton s的ComponentModel s。
如果您出于某种原因需要索引:

for case let (i, .radioButton(radioButtonModel)) in radioButtonGroupModel.options.enumerated() {
    print(i, radioButtonModel.description)
}

也就是说,如果RadioButtonGroupModel.options只能包含.radioButton的情况,我建议将其类型改为[RadioButtonModel],并添加一些自定义解码逻辑来解码它:

struct RadioButtonGroupModel: Decodable {
    let options: [RadioButtonModel]
    
    enum OptionsCodingKey: String, CodingKey {
        case options
    }
    
    
    enum RadioButtonCodingKey: String, CodingKey {
        case radioButton
    }
    
    init(from decoder: Decoder) throws {
        var container = try decoder.container(keyedBy: OptionsCodingKey.self)
        var arrayContainer = try container.nestedUnkeyedContainer(forKey: .options)
        var options = [RadioButtonModel]()
        while !arrayContainer.isAtEnd {
            var radioButtonContainer = try arrayContainer.nestedContainer(keyedBy: RadioButtonCodingKey.self)
            if let model = radioButtonContainer.decodeIfPresent(RadioButtonModel.self, forKey: .radioButton) {
                options.append(model)
            }
        }
        self.options = options
        
    }
}
kq0g1dla

kq0g1dla2#

首先,您需要过滤对象,以便它们都共享为每个枚举选项绑定的相同模式。

  • 比如 *
switch viewContent.filter {if case ComponentModel. emptyComponent = $0 {return false}; return true} {

或者你可以像这样使用if let

if case ComponentModel.radioButtonGroup(let RBGMContent) = radioButtonGroupModel.options[i] {
    print(GMContent)
} else if case ComponentModel.radioButtonGroup(let RBMContent) = radioButtonGroupModel.options[i] {
} else { 
    //this is ComponentModel.emptyComponent
}

也就是说,我可能会使用结构体而不是枚举,但这完全取决于你。

相关问题