美文网首页
iOS Moya网络重试机制

iOS Moya网络重试机制

作者: lczalh | 来源:发表于2019-12-03 09:41 被阅读0次
    /// 网络请求&重用机制
    /// - Parameters:
    ///   - target: target description
    ///   - model: model description
    ///   - delay: delay description
    ///   - max: max description
    ///   - callbackQueue: callbackQueue description
    ///   - progress: progress description
    ///   - completion: completion description
    static func cz_request<T: BaseMappable>(target: TargetType,
                                            model: T.Type,
                                            delay: Double = 3,
                                            max: Int = 3,
                                            callbackQueue: DispatchQueue? = .none,
                                            progress: ProgressBlock? = .none,
                                            completion: @escaping (_ result: Result<T, CZError>) -> Void) {
        cz_provider.request(MultiTarget(target), callbackQueue: callbackQueue, progress: progress) { (result) in
            switch result {
            case let .success(response):
                do {
                    let _ = try response.filterSuccessfulStatusCodes()
                } catch {
                    completion(.failure(CZError("数据获取失败")))
                }
                do {
                    let jsonDict = try response.mapJSON()
                    if let model = Mapper<T>(context: nil).map(JSONObject: jsonDict) {
                        completion(.success(model))
                    } else {
                        completion(.failure(CZError("数据解析失败")))
                    }
                } catch {
                    completion(.failure(CZError("json格式有误")))
                }
                
            case .failure(_):
                if max == 1 {
                    completion(.failure(CZError("似乎已断开与互联网的连接")))
                } else { // 重试
                    DispatchQueue(label: "com.request.queue", attributes: .concurrent).asyncAfter(deadline: DispatchTime.now() + delay) {
                        cz_request(target: target, model: model, delay: delay, max: max - 1, completion: completion)
                    }
                }
            }
        }
    }
    
    /// 网络请求&重用机制(RxSwift)
    /// - Parameters:
    ///   - target: target description
    ///   - model: model description
    ///   - delay: delay description
    ///   - max: max description
    ///   - callbackQueue: callbackQueue description
    ///   - progress: progress description
    static func cz_request<T: BaseMappable>(target: TargetType,
                                            model: T.Type,
                                            delay: Double = 3,
                                            max: Int = 3,
                                            callbackQueue: DispatchQueue? = .none,
                                            progress: ProgressBlock? = .none) -> Single<T>  {
        return Single.create { single in
            let cancellableToken = cz_provider.request(MultiTarget(target), callbackQueue: callbackQueue, progress: progress) { result in
                switch result {
                case let .success(response):
                    do {
                        let _ = try response.filterSuccessfulStatusCodes()
                    } catch {
                        single(.error(CZError("数据获取失败")))
                    }
                    do {
                        let jsonDict = try response.mapJSON()
                        if let model = Mapper<T>(context: nil).map(JSONObject: jsonDict) {
                            single(.success(model))
                        } else {
                            single(.error(CZError("数据解析失败")))
                        }
                    } catch {
                        single(.error(CZError("json格式有误")))
                    }
                case .failure(_):
                    single(.error(CZError("似乎已断开与互联网的连接")))
                }
            }

            return Disposables.create {
                cancellableToken.cancel()
            }
        }.retryWhen(retryHandler(delay: Int(delay),max: max))
        
    }

/// 重试
/// - Parameter delay: 每几秒重试
/// - Parameter max: 最大重试次数
public func retryHandler(delay: Int = 5, max: Int = 5) -> ((Observable<Error>) -> Observable<Int>) {
    return { error in
        return error.enumerated().flatMap { (index, error) -> Observable<Int> in
            guard index < max else {
                return Observable.error(error)
            }
            return Observable<Int>.timer(.seconds(delay), scheduler: MainScheduler.instance)
        }
    }
}

相关文章

网友评论

      本文标题:iOS Moya网络重试机制

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