【问题标题】:how to create dynamic struct with optional generic type如何创建具有可选泛型类型的动态结构
【发布时间】:2020-01-29 12:13:47
【问题描述】:

我为 API 响应创建了一个可解码的基础结构。

struct ResponseBaseModel<T: Decodable>: Decodable {
    let status: Bool
    let message: String
    var result: T?

    private enum CodingKeys: String, CodingKey {
        case result, message, success,status,statusCode
    }

     init(from decoder: Decoder) throws {
           let values = try decoder.container(keyedBy: CodingKeys.self)
            if let result = try? values.decode(T.self, forKey: .result) {
                self.result = result
            }
        status = try  values.decode(Bool.self, forKey: .status)
        message = try  values.decode(String.self, forKey: .message)
       }
}

// 这里是 API 响应

{
    "status": true,
    "statusCode": 200,
    "message": "Theater list successfully",
    "result": [
        {
            "id": 1,
            "name": "Galaxy",
            "picture": "https://ctdemo.workpc.online/kshatrainfotech/abol-app/public/storage/images/theaters/default.png",
            "is_notify": false
        }
    ]
}

这是我如何使用它来调用 API

 apimanager.fetch { [weak self] (response: Result<ResponseBaseModel<[Theater]>, ApiError>) in
        self?.handelResponse(response: response) { response in
            switch response {
            case .success(let theaterList):
                self?.theaterViewModels = theaterList.map{ TheaterViewModel(theaterModel: $0)}
                self?.responseHandler(.success(self!.theaterViewModels))
            case .failure(let apiError):
                self?.responseHandler(.failure(apiError))
            }
        }
    }

但有些 API 没有结果如

{ “状态”:是的, “状态码”:200, “消息”:“api.DATA_UPDATED_SUCCESS” }

如何使用 ResponseBaseModel 模型处理上述响应。因为在使用 ResponseBaseModel 结构时我必须传递任何类型。

ResponseBaseModel<?>

我已经尝试过ResponseBaseModel&lt;nil&gt;,但没有成功。

【问题讨论】:

    标签: ios swift generics


    【解决方案1】:

    我试着把你的问题简单化一点,来说明为什么你想要的东西不可能这样。考虑以下结构:

    struct TestStruct<T> {
        let code:Int
        var value:T?
    
        init(code:Int) {
            self.code = code
        }
    } 
    

    通常你会这样使用它:

    var s = TestStruct<String>(code:42)
    s.value = "abc"
    
    print (s) // TestStruct<String>(code: 42, value: Optional("abc"))
    

    现在你说:“哦,我只需要一些代码的 TestStruct,没有任何价值”,然后尝试以下操作:

    var codeOnly = TestStruct<nil>(code:42)
    print (codeOnly)
    

    编译器会抱怨,因为它需要value 属性的专用类型。 为什么它不起作用?因为想到下面的说法:

    let v = codeOnly.value
    // or
    codeOnly.value = "String"
    

    在这里,编译器需要知道属性codeOnly.value 是什么类型。 因为现在不能,所以它不允许无类型的TestStruct

    【讨论】:

    • 是的,我知道编译器需要知道属性的类型。您能否建议一种替代方法来解码有结果和无结果的 API 响应?
    • 你可以使用枚举:一种情况有结果,另一种情况没有结果
    猜你喜欢
    • 2018-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多