美文网首页swift相关
swift-协议关联类型实战应用(分离Response转模型)

swift-协议关联类型实战应用(分离Response转模型)

作者: mrkison | 来源:发表于2022-10-21 11:51 被阅读0次

前言

我们网络请求后得到数据需要转模型,一般项目就是使用一种解析数据的方式,常见的Codable、Swiftyjson、Handyjson等,一般的做法就是在定义方法时就传一个泛型,例如(T: Codable)这样然后解析。但是如果既有Codable又有Swiftyjson这样就不好同时让泛型T遵循2个协议。所以这里就可以用到关联类型来将处理。

1、抽离一个转模型的协议

protocol NetResponseParseAble {
    associatedtype NetResult
    func parse(_ response: Data) throws -> NetResult
}

NetResult关联类型就是需要解析的类型,遵循NetResponseParseAble来解析模型。

2、封装一个NetTool做网络请求

这里我们返回出去的就是NetResponseParseAble的关联类型NetResult,也就是我们处理好的模型

struct NetTool {
    // 一个request请求,这里是以moya为例
    @discardableResult
    static func request<R: TargetType, P: NetResponseParseAble>(_ request: R,
                                                               parser: P,
                                     progressClosure: NetProgressClosure? = nil,
                                     completion: OneResult<P.NetResult?>?,
                                     errorClosure: NetErrorClosure? = nil) -> Cancellable {
    // 这里用moya做网络请求获取到返回值Data
    // 做一些项目相关判断操作
    // 解析
    do {
      let result = P.parse(response.data)
      completion(result)
    } catch {
      处理错误
    }
  }
}

3、实现NetResponseParseAble不同的转模型方式

// 一般接口返回长这样
struct NetResponse<T: Decodable>: Decodable {
    let code: Int
    let message: String?
    let data: T?
}

1、Codable转模型

struct NetDecodableResponseParser<T: Decodable>: NetResponseParseAble {
    func parse(_ data: Data) throws -> T {
        do {
            let r = try response.map(NetResponse<T>.self)
            guard let data = r.data else {
                throw 错误
            }
            return data
        }catch {
            throw error
        }
    }
}

2、swiftyjson转模型

protocol SwiftyJsonType {
    init(json: JSON)
}

struct NetSwiftyJsonResponseParser<T: SwiftyJsonType>: NetResponseParseAble {
    func parse(_ data: Data) throws -> T {
        // 这里没写完整,大概这样
        let res = T(json: data)
        return res
    }
}

4、在NetTool中创建对应解析方法

struct NetTool {
    @discardableResult
    static func fetch<T: SwiftyJsonType>(_ request: TargetType,
                                  resultType: T.Type,
                             progressClosure: NetProgressClosure? = nil,
                             completion: OneResult<T?>?,
                             errorClosure: NetErrorClosure? = nil) -> Cancellable {
        
        return NetTool.request(
            request,
            parser: NetSwiftyJsonResponseParser<T>(),
            progressClosure: progressClosure,
            completion: completion,
            errorClosure: errorClosure)
    }
    
    @discardableResult
    static func fetch<T: Codable>(_ request: TargetType,
                                  resultType: T.Type,
                             progressClosure: NetProgressClosure? = nil,
                             completion: OneResult<T?>?,
                             errorClosure: NetErrorClosure? = nil) -> Cancellable {
        
        return NetTool.request(
            request,
            parser: NetDecodableResponseParser<T>(),
            progressClosure: progressClosure,
            completion: completion,
            errorClosure: errorClosure)
    }
    @discardableResult
    static func request<R: TargetType, P: NetResponseParseAble>(_ request: R,
                                                               parser: P,
                                     progressClosure: NetProgressClosure? = nil,
                                     completion: OneResult<P.NetResult?>?,
                                     errorClosure: NetErrorClosure? = nil) -> Cancellable {
    // 这里做网络请求获取到返回值Data
    // 做一些判断操作
    // 解析
    do {
      let result = P.parse(response.data)
      completion(result)
    } catch {
      处理错误
    }
  }
}

这样以后增加一种解析方式只需要再创建一个结构体或类遵循NetResponseParseAble协议实现协议方法就可以了。

如果喜欢或对你有用可以点赞

相关文章

  • swift-协议关联类型实战应用(分离Response转模型)

    前言 我们网络请求后得到数据需要转模型,一般项目就是使用一种解析数据的方式,常见的Codable、Swiftyjs...

  • swift 模型 协议 拓展 泛型 小实践

    协议支持关联类型 模型支持泛型 协议与模型组成复合体 以供外界遵守协议使用

  • Runtime(五) 实战

    实战一: 数据转模型 目标: 数据转模型考验知识点: 获取属性列表, 关联属性, 字典转模型 1, 获取类的属性列...

  • swift 关联类型

    关联类型 定义一个协议时,声明一个或多个关联类型作为协议定义的一部分将会非常有用。关联类型为协议中的某个类型提供了...

  • Swift 5.x 关联类型

    定义一个协议时, 有时在协议定义里声明一个或多个关联类型是很有用的. 关联类型给协议中用到的类型一个占位符名称. ...

  • Swift-泛型、关联类型

    一、泛型 我们可以在函数、类、结构体、枚举中使用泛型,在名称后使用来表示,例子如下: Sw...

  • OSI-体系结构

    一 OSI七层模型 OSI七层协议模型以及个模型协议 OSI七层协议模型主要是:应用层(Application)、...

  • swift4 字典->模型-相互转换

    1.swift4出现了Codable协议,只要继承该协议,便可使用系统的模型转换,字典转模型,模型转字典。 2.本...

  • 14-泛型

    泛型(Generics) 泛型类型 关联类型(Associated Type) 类型约束 协议类型的注意点 泛型解...

  • 2018-03-08

    Swift关键字 associatedtype: 协议-关联类型, 作用:为协议中的某个类型提供了一个占位名(或者...

网友评论

    本文标题:swift-协议关联类型实战应用(分离Response转模型)

    本文链接:https://www.haomeiwen.com/subject/rjkvzrtx.html