swift-協(xié)議關(guān)聯(lián)類型實(shí)戰(zhàn)應(yīng)用(分離Response轉(zhuǎn)模型)

前言

我們網(wǎng)絡(luò)請(qǐng)求后得到數(shù)據(jù)需要轉(zhuǎn)模型,一般項(xiàng)目就是使用一種解析數(shù)據(jù)的方式,常見的Codable、Swiftyjson、Handyjson等,一般的做法就是在定義方法時(shí)就傳一個(gè)泛型,例如(T: Codable)這樣然后解析。但是如果既有Codable又有Swiftyjson這樣就不好同時(shí)讓泛型T遵循2個(gè)協(xié)議。所以這里就可以用到關(guān)聯(lián)類型來(lái)將處理。

1、抽離一個(gè)轉(zhuǎn)模型的協(xié)議

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

NetResult關(guān)聯(lián)類型就是需要解析的類型,遵循NetResponseParseAble來(lái)解析模型。

2、封裝一個(gè)NetTool做網(wǎng)絡(luò)請(qǐng)求

這里我們返回出去的就是NetResponseParseAble的關(guān)聯(lián)類型NetResult,也就是我們處理好的模型

struct NetTool {
    // 一個(gè)request請(qǐng)求,這里是以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做網(wǎng)絡(luò)請(qǐng)求獲取到返回值Data
    // 做一些項(xiàng)目相關(guān)判斷操作
    // 解析
    do {
      let result = P.parse(response.data)
      completion(result)
    } catch {
      處理錯(cuò)誤
    }
  }
}

3、實(shí)現(xiàn)NetResponseParseAble不同的轉(zhuǎn)模型方式

// 一般接口返回長(zhǎng)這樣
struct NetResponse<T: Decodable>: Decodable {
    let code: Int
    let message: String?
    let data: T?
}

1、Codable轉(zhuǎn)模型

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 錯(cuò)誤
            }
            return data
        }catch {
            throw error
        }
    }
}

2、swiftyjson轉(zhuǎn)模型

protocol SwiftyJsonType {
    init(json: JSON)
}

struct NetSwiftyJsonResponseParser<T: SwiftyJsonType>: NetResponseParseAble {
    func parse(_ data: Data) throws -> T {
        // 這里沒(méi)寫完整,大概這樣
        let res = T(json: data)
        return res
    }
}

4、在NetTool中創(chuàng)建對(duì)應(yīng)解析方法

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 {
    // 這里做網(wǎng)絡(luò)請(qǐng)求獲取到返回值Data
    // 做一些判斷操作
    // 解析
    do {
      let result = P.parse(response.data)
      completion(result)
    } catch {
      處理錯(cuò)誤
    }
  }
}

這樣以后增加一種解析方式只需要再創(chuàng)建一個(gè)結(jié)構(gòu)體或類遵循NetResponseParseAble協(xié)議實(shí)現(xiàn)協(xié)議方法就可以了。

如果喜歡或?qū)δ阌杏每梢渣c(diǎn)贊

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容