首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在swift中检查类型并将其强制转换为Decodable

如何在swift中检查类型并将其强制转换为Decodable
EN

Stack Overflow用户
提问于 2020-08-27 11:12:17
回答 2查看 285关注 0票数 1

我想发出一个网络请求,在其中我可以控制响应是JSON原始值[String: AnyDecodable

示例如下:

代码语言:javascript
复制
func reqest<T>(endpoint: EndPoint, completion: @escaping (Result<T, Error>) -> Void) {
   session.dataTask(with: request) { (data, response, error) in

       if T.self is Decodable.Type {
           try? JSONDecoder().decode(T.self, from: data)
       } else {
           try? JSONSerialization.jsonObject(with: data, options: .mutableLeaves)
       }
   }.resume()
}

然后,当我想要JSON值时,我只需要调用T作为[String: Any],或者使用任何型号的确认Decodable协议。

问题是这一行:

代码语言:javascript
复制
try? JSONDecoder().decode(T.self, from: data)

如何将T转换为Decodable

我知道如何使用:

代码语言:javascript
复制
func reqest<T: Decodable >(endpoint: EndPoint, completion: @escaping (Result<T, Error>) -> Void)

但是[String: Any]不是Decodable

或者有什么更好的解决方案来实现我想要的?谢谢。

EN

回答 2

Stack Overflow用户

发布于 2020-08-27 17:41:39

我建议对reqest(endpoint:completion:)函数使用重载来实现您想要的功能。

例如,我想要的结构是这样的:

代码语言:javascript
复制
enum ResponseError: Error {
    case noData
    case typeMismatch
}

func reqest<T>(endpoint: EndPoint, completion: @escaping (Result<T, Error>) -> Void) {
    baseReqest(endpoint: endpoint) { result in
        switch result {
        case .success(let data):
            do {
                guard let json = try JSONSerialization.jsonObject(with: data) as? T else {
                    completion(.failure(ResponseError.typeMismatch))
                    return
                }
                completion(.success(json))
            } catch {
                completion(.failure(error))
            }
        case .failure(let error):
            completion(.failure(error))
        }
    }
}

func reqest<T: Decodable>(endpoint: EndPoint, completion: @escaping (Result<T, Error>) -> Void) {
    baseReqest(endpoint: endpoint) { result in
        switch result {
        case .success(let data):
            do {
                let response = try JSONDecoder().decode(T.self, from: data)
                completion(.success(response))
            } catch {
                completion(.failure(error))
            }
        case .failure(let error):
            completion(.failure(error))
        }
    }
}

private func baseReqest(endpoint: EndPoint, completion: @escaping (Result<Data, Error>) -> Void) {
    session.dataTask(with: request) { (data, response, error) in
        if let error = error {
            completion(.failure(error))
            return
        }
        guard let data = data else {
            completion(.failure(ResponseError.noData))
            return
        }
        completion(.success(data))
    }.resume()
}

这样,您就可以在baseReqest(endpoint:completion:)函数中使用通用的响应处理代码,并在其他两个函数中仅分离响应解析。

那么调用reqest(endpoint:completion:)函数可以是

使用[String: Any]作为响应类型的

代码语言:javascript
复制
reqest(endpoint: endpoint) { (result: Result<[String: Any], Error>) in
    // Handle result
}

使用[[String: Any]]作为响应类型的

代码语言:javascript
复制
reqest(endpoint: endpoint) { (result: Result<[[String: Any]], Error>) in
    // Handle result
}

  • ,并使用Decodable对象作为响应类型:

代码语言:javascript
复制
struct Response: Decodable {}

reqest(endpoint: endpoint) { (result: Result<Response, Error>) in
    // Handle result
}
票数 1
EN

Stack Overflow用户

发布于 2020-08-27 18:13:43

用Swift的方式来做。使用struct Codable (这给你提供了Decodable一起)。

例如:

代码语言:javascript
复制
 struct testStruct: Codable {
   public var testString:String!
   public var testAny:Any!
   init(
          testString:String!,
          testAny:Any!
       )
   {
       self.testString = testString
       self.testAny = testAny
   }

然后使用以下代码对其进行初始化:

代码语言:javascript
复制
var testStructToUse:[testStruct] = []

在这里,您可以使用append方法填充它:

代码语言:javascript
复制
testStructToUse.append(testStruct(testString: "any String", testAny: "any value"))

并使用JSONencoder编码

代码语言:javascript
复制
let jsonData = try JSONEncoder().encode(testStruct)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63608606

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档