最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Swift?Error重構(gòu)優(yōu)化詳解

 更新時間:2022年11月30日 09:21:28   作者:移動端小伙伴  
這篇文章主要為大家介紹了Swift?Error的問題解決及重構(gòu)優(yōu)化方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

背景現(xiàn)狀

項目每積累到一定程度,代碼的重構(gòu)優(yōu)化是必經(jīng)之路。

試卷項目初期,整體錯誤Code較少,直接使用更便于處理錯誤狀態(tài),因此便全部歸整到一個單獨的 NetWorkError.ResponseCodeType 中,但是隨著項目功能的豐富,各個功能模塊越來越多,模塊錯誤的處理也各不相同,每個模塊都關(guān)聯(lián)了所有的錯誤Code,后續(xù)還會持續(xù)增長,導(dǎo)致越來越難以維護。

enum ResponseCodeType: Int {
    case success = 0
    case tokenExpire = 11001
    case overVerifyCode = 11011
    case verifyCodeExpire = 11002
    case verifyCodeIncorrect = 11003
    case autoLoginFailed = 11004
    case appidLoginFailed = 11005
    case phoneIsRegisted = 11006
    case phoneHasBinded = 11010
    case joinedBeePlan = 11100002
    case uploadRepeate = 11020005
    case wechatHasBinded = 11010017
    case phoneHasBindedOtherWeChat = 11010022
    case todayIsSignIned = 11140003
    case subjectCountLimit = 11150004
    case invalidTagName = 11160002
    case alreadyExistsTagName = 11160003
    case outOfMaxTagsCount = 11160004
    case notRegisterHomework = 11010033
    case notSupportNumber = 11010028
    case wrongTeamCode = 11210005
    case classNotFound = 11210006
    case nicknameExists = 11210007
    case joinClassThreeTimes = 11210008
    case identityNickNameExists = 11210014
    case checkClassCodeMax = 11210016
    case createClassMAx = 11210015
    case joinTeamMax = 11210017
    case studentCountMax = 11210018
    case other = -99999
}

問題分析

提前分析、明確目標。

期望結(jié)果

  • 錯誤處理分為兩部分:通用、自定義模塊,二者各自處理
  • 拓展性強,各個模塊可自定義并處理錯誤,基類代碼保持穩(wěn)定不變
  • 支持點語法、窮舉校驗,使用清晰便捷

技術(shù)選型

根據(jù)期望結(jié)果,可以大致選定技術(shù)方向

  • 拓展性:泛型、協(xié)議
  • 類型窮舉:枚舉

優(yōu)化解決

前后對比,不斷調(diào)優(yōu)。

Error模型

  • 區(qū)分通用和自定義模塊
  • 將 ResponseCodeType 降為通用Code類型,可以將其類型固定
  • 替換 NetWorkError,使用 ModuleRespError 作為基類Error,通過泛型為外部模塊提供自定義能力

優(yōu)化前

struct NetWorkError: Error {
    var code: ResponseCodeType = .other
    var msg: String { code.errorString }
}

優(yōu)化后

/// 錯誤類型描述
public protocol ISErrorProtocol {
    var errorString: String { get }
}
public enum ModuleRespError<T: ISErrorProtocol>: Error {
    /// 對應(yīng)模塊自定義類型code
    case type(_ value: T)
    /// 基類請求code
    case baseType(_ value: ResponseCodeType)
    /// 錯誤提示歸整
    public var mapErrorString: String {
        switch self {
        case .type(let value):
            return value.errorString
        case .baseType(let value):
            return value.errorString
        }
    }
}

基類Request

使用協(xié)議的類型占位符 associatedtype,便于后續(xù)進行 rawValue 的枚舉映射

  • 分層處理錯誤類型,基類錯誤放到基類請求的回調(diào)中處理,拋出模塊的錯誤code

在ISTargetType協(xié)議中關(guān)聯(lián)錯誤碼類型 associatedtype ErrorCodeType: RawRepresentable

public protocol ISTargetType {
    /// 錯誤碼類型,由各模塊自定義
    associatedtype ErrorCodeType: RawRepresentable
}

優(yōu)化前

/// 根據(jù) ISTargetType 枚舉類型調(diào)用接口,返回 model
static func requestISType<T: ISTargetType>(_ server: T,
                                           completion: @escaping (_ model: NetworkModelResponse?, _ code: ResponseCodeType) -> Void) {
    // ...
    Network.IS.fetchDataDic(server) { dataDic in
        guard let dataDic = dataDic,
              let model: NetWorkResponseModel = NetWorkResponseModel.deserialize(from: dataDic) else {
            completion(nil, .other)
            return
        }
        // 判斷code 是否為token過期
        let codeValue = model.ret ?? ResponseCodeType.other.rawValue
        // errorType
        let codeType = ResponseCodeType(rawValue: codeValue) ?? .other
        // 基類Code處理,token過期
        NetWorkRequest.checkTokenDidExpire(codeType)
        // 拋出的code:基類、模塊混在一起
        completion(model, codeType)
    }
}

優(yōu)化后

/// T.ErrorCodeType: 遵循 RawRepresentable 協(xié)議的泛型
/// Result<Success, Failure> 拆分成功、失敗邏輯
static func requestISResultType<T: ISTargetType>(_ server: T,
                                                 result: @escaping ((Result<NetWorkResponseModel, ModuleRespError<T.ErrorCodeType>>) -> Void)) {
    // ...
    Network.IS.fetchDataDic(server) { dataDic in
        // 接口數(shù)據(jù)處理
        guard let dataDic = dataDic,
              let model: NetWorkResponseModel = NetWorkResponseModel.deserialize(from: dataDic),
              let retCode = model.ret else {
            // 接口錯誤,默認基類錯誤
            let error: ModuleRespError<T.ErrorCodeType> = .baseType(.other)
            result(.failure(error))
            return
        }
        if retCode == 0 {
            // 成功返回
            result(.success(model))
            return
        }
        // 請求失敗
        if let baseType = ResponseCodeType(rawValue: retCode) {
            result(.failure(.baseType(baseType)))
            // 優(yōu)先處理基類錯誤code,例如 token失效
            NetWorkRequest.checkTokenDidExpire(baseType)
        } else if let retValue = retCode as? T.ErrorCodeType.RawValue,
                  let moduleType = T.ErrorCodeType(rawValue: retValue) {
            // 解析并返回模塊錯誤碼
            result(.failure(.type(moduleType)))
        }
    }
}

模塊調(diào)用

  • 各模塊自定義ErrorCode,互不干涉
  • 通過泛型參數(shù)定義ErrorCode類型
  • 使用Result<Success, Failure>,消除結(jié)果可選值,成功失敗二選一,區(qū)分處理
  • 限制失敗Error類型,僅需處理當(dāng)前模塊和基礎(chǔ)錯誤,無需關(guān)注其他類型錯誤

優(yōu)化前

public func queryDemo(with params: [String: String], completionHandler: @escaping (_ model: DemoModel?, _ code: ResponseCodeType) -> Void) {
    NetWorkRequest.requestISType(GroupQueryServer.createGroup(params)) { model  in
        // ...
        let code = model.ret ?? -1
        let type = ResponseCodeType(rawValue: code) ?? .other
        guard type == .success,
              let result = DemoModel.deserialize(from: model.data) else {
            completionHandler(nil, type)
            return
        }
        completionHandler(.success(resultModel))
    }
}
logic.queryDemo(with: params) { model, code in
	// 只能通過解包model來判斷接口的成功或失敗
	guard let model = model else {
		// 失敗處理
		handleFail(code: code)
	return
}
	// 成功處理
	hanldeSuccess()
}
private func handleFail(code: ResponseCodeType) {
    // ...
	// 當(dāng)前模塊錯誤處理
	let showWarning = code == .wrongTeamCode || code == .classNotFound
	// UI處理
	warningLabel.isHidden = !showWarning
    // 提示
    CEProgressHUD.showTextHUD(code.errorString)
}

優(yōu)化后

public enum StudyGroupRespCode: Int, ISErrorProtocol {
    case wrongTeamCode = 11210005
    case classNotFound = 11210006
    case nicknameExists = 11210007
    case joinClassThreeTimes = 11210008
    case identityNickNameExists = 11210014
    case checkClassCodeMax = 11210016
    case createClassMAx = 11210015
    case joinTeamMax = 11210017
    case studentCountMax = 11210018
    case folderLevelLimit = 11210027
    case curIdentifierError = 11210011
    case clockFrequencyInvalid = 11210036
    case other
}
public func queryDemo(with params: [String: String], completionHandler: @escaping ((Result<ClassItemModel, ModuleRespError<StudyGroupRespCode>>) -> Void)) {
// 基類請求
NetWorkRequest.requestISResultType(GroupQueryServer.createGroup(params)) { result in
    switch result {
    case .success(let success):
        // 結(jié)果處理que
        if let resultModel = ClassItemModel.deserialize(from: success.data) {
            // 轉(zhuǎn)換模塊模型model
            completionHandler(.success(resultModel))
        } else {
            // 轉(zhuǎn)化失敗,默認other
            completionHandler(.failure(.type(.other)))
        }
    case .failure(let error):
        // 拋出的模塊錯誤
        completionHandler(.failure(error))
    }
}
logic.queryDemo(with: params) { result in
	// 通過 Result 劃分結(jié)果狀態(tài)
	switch result {
	case .success(let model):
		// 成功處理
		hanldeSuccess()
	case .failure(let error):
		// 失敗處理
		handleError(error)
	}
}
// 示例為簡單處理,若需精細化處理錯誤,拆分優(yōu)化后的代碼,邏輯明顯更加清晰
private func handleError(_ error: ModuleRespError<StudyGroupRespCode>) {
	switch error {
	case .type(let code):
		// ...
		// 當(dāng)前模塊錯誤處理
		let showWarning = code == .wrongTeamCode || code == .classNotFound
		// UI處理
		warningLabel.isHidden = !showWarning
		// 提示
		CEProgressHUD.showTextHUD(code.errorString)
	case .baseType(let error):
		// 基類錯誤處理
		CEProgressHUD.showTextHUD(error.errorString)
	}
}

總結(jié)

至此,我們已經(jīng)了解了有關(guān)ErrorCode的重構(gòu)優(yōu)化的大體邏輯,從后續(xù)的開發(fā)流程結(jié)果可以看出,確實對項目的Code混亂增長有了良好的控制,各模塊只需要關(guān)注處理自己的異常code,降低了維護代碼難度,后續(xù)也會持續(xù)關(guān)注和優(yōu)化。

參考資料

以上就是Swift Error重構(gòu)優(yōu)化詳解的詳細內(nèi)容,更多關(guān)于Swift Error重構(gòu)優(yōu)化的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 快速排序算法在Swift編程中的幾種代碼實現(xiàn)示例

    快速排序算法在Swift編程中的幾種代碼實現(xiàn)示例

    快速排序是一種不穩(wěn)定的排序,存在著優(yōu)化空間,這里我們來看快速排序算法在Swift編程中的幾種代碼實現(xiàn)示例:
    2016-07-07
  • Swift算法實現(xiàn)字符串轉(zhuǎn)數(shù)字的方法示例

    Swift算法實現(xiàn)字符串轉(zhuǎn)數(shù)字的方法示例

    最近學(xué)完了swift想著實踐下,就通過一些簡單的算法進行學(xué)習(xí)研究,下面這篇文章主要介紹了Swift算法實現(xiàn)字符串轉(zhuǎn)數(shù)字的方法,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-03-03
  • Swift中的命名空間詳解

    Swift中的命名空間詳解

    這篇文章主要給大家介紹了關(guān)于Swift中命名空間的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • swift實現(xiàn)顏色漸變以及轉(zhuǎn)換動畫

    swift實現(xiàn)顏色漸變以及轉(zhuǎn)換動畫

    這篇文章主要為大家詳細介紹了swift實現(xiàn)顏色漸變以及轉(zhuǎn)換動畫,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Swift利用CoreData實現(xiàn)一個上班簽到的小工具

    Swift利用CoreData實現(xiàn)一個上班簽到的小工具

    這篇文章主要給大家介紹了關(guān)于Swift利用CoreData實現(xiàn)一個上班簽到小工具的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-12-12
  • 使用?Swift?Package?插件生成代碼的示例詳解

    使用?Swift?Package?插件生成代碼的示例詳解

    這篇文章主要介紹了使用?Swift?Package?插件生成代碼,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-08-08
  • Swift?Error重構(gòu)優(yōu)化詳解

    Swift?Error重構(gòu)優(yōu)化詳解

    這篇文章主要為大家介紹了Swift?Error的問題解決及重構(gòu)優(yōu)化方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • Swift的開發(fā)環(huán)境搭建以及基本語法詳解

    Swift的開發(fā)環(huán)境搭建以及基本語法詳解

    這篇文章主要介紹了Swift的開發(fā)環(huán)境搭建以及基本語法詳解,是Swift入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-11-11
  • Swift面試題及答案整理

    Swift面試題及答案整理

    雖然Swift出現(xiàn)的時間不久,但是它已經(jīng)成為最流行的編程語言之一了。Swift的知識浩如煙海,但是怎么測試你掌握了多少?通過下面這篇整理關(guān)于Swift面試題及答案,可能會對你所掌握的Swift進行一個判斷,需要的朋友可以參考借鑒。
    2017-01-01
  • Swift教程之集合類型詳解

    Swift教程之集合類型詳解

    這篇文章主要介紹了Swift教程之集合類型詳解,Swift 提供兩種集合類型來存儲集合,數(shù)組和字典,本文詳細講解了數(shù)組的創(chuàng)建、讀取和修改數(shù)組、遍歷數(shù)組以及集合的操作等內(nèi)容,需要的朋友可以參考下
    2015-01-01

最新評論

新田县| 运城市| 潼关县| 恭城| 邳州市| 湖北省| 博乐市| 淮北市| 诸暨市| 惠安县| 上犹县| 白玉县| 平湖市| 德江县| 辉县市| 锡林浩特市| 遂川县| 栾川县| 大悟县| 沙湾县| 永年县| 新密市| 宁都县| 鸡泽县| 郁南县| 锡林郭勒盟| 台江县| 太湖县| 修文县| 宽城| 泸溪县| 建阳市| 临洮县| 电白县| 马龙县| 滨州市| 黄骅市| 吉林省| 巴南区| 襄汾县| 扎鲁特旗|