当前位置: 首页 > article >正文

Moya 网络框架

Moya 网络框架

定义enum类型,有多种接口就定义多少种,然后实现TargetType协议

import Foundation
//导入网络框架
import Moya



enum DefaultService {
    //广告列表
    case ads(position : Int)
    
    case sheets(size:Int)
    
    case sheetDetail(data: String)
    
    case register(data : User)
}

// MARK: - 实现TargetType协议
extension DefaultService:TargetType {
    //返回API地址
    var baseURL: URL {
        return URL(string: Config.ENDPOINT)!
    }
    
    //返回每个请求的路径
    var path: String {
        switch self {
        case.ads(_):
            return "v1/ads"
            
        case .sheets :
            return "v1/sheets"
        
        case .sheetDetail(let data):
            return "v1/sheets/\(data)"
            
        case .register(_) :
            return "v1/users"
        
        default:
            fatalError("error")
        }
        
    }
    
    //请求方式
    var method: Moya.Method {
        switch self {
        case .register :
            return .post
        default:
            return .get
        }
    }
    
    var task: Moya.Task {
        switch self {
        case .ads(let position):
            return ParamUtil.urlRequestParamters(["position":position])
        case .sheets(let size):
            return ParamUtil.urlRequestParamters(["size":size])
        default :
            //不传递任何参数
            return .requestPlain
        }
    }
    
    var headers: [String : String]? {
        var headers: Dictionary<String,String> = [:]
        
        return headers
    }
    
    
}

使用方法

        let provider = MoyaProvider<DefaultService>()
        provider.request(.sheets(size: 10)) { result in
            print(result)
            
            switch result {
            case let .success(response) :
                let data = response.data
                let statusCode = response.statusCode
                let datastring = String(data: data,encoding: .utf8)!
                print(statusCode)
                print(datastring)
            case let .failure(error) :
                print(error)
            }
        }

可以看到,最后返回的形式为字符串,不方便使用,所以需要进一步进行封装,将其转换为对象

使用RxSwift框架请求网络
//rxSwift 方式
provider.rx.request(.sheets(size: 10))
    .debug("Request")
    .subscribe { event in
        switch event {
        case let .success(response) :
            print("hello ")
            let data = response.data
            let statusCode = response.statusCode
            let datastring = String(data: data,encoding: .utf8)!
            print(statusCode)
            print(datastring)
            if let r = SheetListResponse.deserialize(from: datastring){
                print(r.status)
                print(r.data.data[0].title!)
            }

        case let .failure(error) :
            print(error)
        }
    }.disposed(by: rx.disposeBag) //释放相关资源,防止内存泄露
使用框架解析JSON数据

使用第三方库HandyJSON

根据给出的JSON格式,建立相关的类即可

然后把字符串转换成相对应的格式即可

if let r = SheetListResponse.deserialize(from: datastring)
封装自动解析JSON功能

对Observable进行拓展

// MARK: - 扩展Observable
extension Observable{
    /// 将字符串解析为对象
    ///
    /// - Parameter type: 要转为的类
    /// - Returns: 转换后的观察者对象
    public func mapObject<T:HandyJSON>(_ type:T.Type) -> Observable<T> {
        map { data in
            //将参数尝试转为字符串
            guard let dataString = data as? String else {
                //data不能转为字符串
                throw IxueaError.objectMapping
            }
            
            guard let result = type.deserialize(from: dataString) else{
                throw IxueaError.objectMapping
            }
            
            //解析成功
            //返回解析后的对象
            return result
        }
    }
}

在 Swift 中,map 是一种高阶函数,通常用于对集合(如数组、字典、可选值等)中的元素进行转换或映射。在你的代码中,map 用于将某个数据转换为期望的类型。

map 的基本作用:

map 会对序列中的每个元素执行一个闭包,然后返回一个新序列,其中每个元素都经过闭包的处理。

let numbers = [1, 2, 3]
let doubledNumbers = numbers.map { $0 * 2 }
// doubledNumbers == [2, 4, 6]

在这个例子中,map 会遍历 numbers 数组中的每个元素,并将每个元素乘以 2,然后返回一个新的数组。

代码中 map 的使用:

代码中使用 map 似乎是在处理一些数据转换,具体是将某种类型的数据(data)尝试转为字符串类型,并解析成目标类型对象。详细讲解如下:

map { data in
    // 将参数尝试转为字符串
    guard let dataString = data as? String else {
        // data 不能转为字符串
        throw IxueaError.objectMapping
    }
    
    guard let result = type.deserialize(from: dataString) else {
        throw IxueaError.objectMapping
    }
    
    // 解析成功
    // 返回解析后的对象
    return result
}

分解讲解:

​ 1. map { data in … }

​ • map 会对集合中的每个元素执行闭包中的代码,并返回一个新集合。这里的闭包是 data in { … },它接受集合中的每个元素作为输入(在这里是 data)。

​ • data 可能是一个原始数据,可以是任何类型,但在此代码中,它最终被尝试转换为 String 类型。

​ 2. guard let dataString = data as? String else { throw IxueaError.objectMapping }

​ • 使用 guard let 尝试将 data 转换为 String 类型。如果转换失败(即 data 不是一个字符串),则会跳转到 else 语句,抛出错误(IxueaError.objectMapping),中断当前的操作并退出。

​ • guard let 语句是一种早期退出的方式,用来简化条件判断并在条件不满足时处理错误。

​ 3. guard let result = type.deserialize(from: dataString) else { throw IxueaError.objectMapping }

​ • 假设 type 是一个类型,它提供了 deserialize(from:) 方法,用来将 dataString 字符串解析成目标类型的对象。

​ • 如果解析失败(即 deserialize 返回 nil),同样会抛出一个错误。deserialize 可能返回一个 nil,表示无法从字符串中成功解析出对象。

​ 4. return result

​ • 如果 data 成功转换为字符串,并且字符串成功被解析为目标类型的对象,最终的 result 会被返回。这个 result 就是经过 map 处理后得到的新元素。

总结:

​ • map:遍历集合中的每个元素,并应用闭包中的代码,返回转换后的新集合。

​ • guard:用于提前退出函数,如果条件不成立则抛出错误(throw IxueaError.objectMapping)。

​ • deserialize:将字符串解析成目标类型,如果失败则抛出错误。

代码的核心目的是将原始数据转换为字符串,然后再将字符串解析为目标类型对象。如果过程中有任何失败的地方(如类型转换失败或解析失败),都会抛出错误并停止处理。

对网络部分进行封装

为了解决JSON中相同类型对复用,所以将一些公共部分对类型写成一个类去继承,这样就避免了对于每一个JSON格式都需要再进行定义该类型。

同理,我们不可能对于每一个JSON去创建一个对应的类,所以使用范型,定义一些公共部分,每次传入该JSON应该属于什么类型即可。即定义了详情网络解析类,解析列表网络请求类


http://www.kler.cn/a/549428.html

相关文章:

  • Transformer以及BERT阅读参考博文
  • python大恒相机保存RAW图和实时显示
  • Java ArrayList(单列集合)
  • 【CUDA】Pytorch_Extensions
  • 数据仓库与数据挖掘记录 二
  • 【Azure 架构师学习笔记】- Azure Databricks (11) -- UC搭建
  • 【ISO 14229-1:2023 UDS诊断(ECU复位0x11服务)测试用例CAPL代码全解析③】
  • Linux:深入了解进程信号(上)
  • DeepSeek与ChatGPT:AI语言模型的全面对决
  • 生成式大模型 怎么结合 知识库与 AI Agent
  • windows配置永久路由
  • Java运维实战:问题定位-CPU突增排查
  • 【动态规划】斐波那契数列模型
  • 聚铭网络入围2025年度江苏省政府采购信息安全设备协议供货名单
  • 【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第十七节】
  • 【LeetCode Hot100 矩阵】矩阵置零、螺旋矩阵、旋转图像、搜索二维矩阵II
  • matlab 柴油机冷却系统仿真计算
  • Python 自然语言处理(NLP)和文本挖掘的常规操作过程
  • PHP在线题库小程序
  • Large Language Model Distilling Medication Recommendation Model