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

IOS 14 封装网络请求框架

本文基于IOS 13 网络请求和Moya框架 ,对网络请求框架Moya的二次封装,并实现JSON对象解析等。

添加依赖

  # 网络请求框架
  # https://github.com/Moya/Moya
  pod 'Moya/RxSwift'

  #避免每个界面定义disposeBag
  #https://github.com/RxSwiftCommunity/NSObject-Rx
  pod "NSObject+Rx"
  
  # JSON解析为对象
  # https://github.com/alibaba/HandyJSON
  pod "HandyJSON"

还不了解如何使用 CocoaPods 管理依赖的,建议先看前面的文章:IOS 01 CocoaPods 安装与使用 

添加完依赖后,看一下Pods文件夹里面是否添加成功。

Observable扩展

对Observable扩展,增加JSON对象解析。

//
//  ObservableMoyaExtension.swift
//  对Observable扩展moya网络相关功能
//
//  Created by jin on 2024/8/23.
//

import Foundation

//导入JSON解析框架
import HandyJSON

//导入网络框架
import Moya

//响应式编程框架
import RxSwift

/// 自定义错误
///
/// - objectMapping: 表示JSON解析为对象失败
enum NetError : Swift.Error{
    case objectMapping
}

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

封装DefaultService

//
//  DefaultService.swift
//  网络API
//
//  Created by jin on 2024/8/22.
//

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{
    
    /// 返回网址
    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("DefaultService path is null")
        }
    }
    
    /// 请求方式
    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
    }
    
    
}

封装BaseModel

由于使用HandyJSON框架解析JSON ,要求对象必须继承自HandyJSON,故统一封装。

//
//  BaseModel.swift
//  通用模型
//
//  Created by jin on 2024/8/23.
//

import Foundation

import HandyJSON

class BaseModel : HandyJSON{
    
    required init() {}
    
    func mapping(mapper: HelpingMapper) {
    }
}

封装BaseResponse

本文使用的接口会统一返回格式{"status":xxx,"message":xxx},故统一封装

//
//  BaseResponse.swift
//  通用网络请求响应模型
//
//  Created by jin on 2024/8/23.
//

import Foundation

class BaseResponse : BaseModel{
    
    /// 状态码
    var status:Int = 0
    
    /// 错误信息
    var message:String?
}

封装DetailResponse

本文使用的详情接口会统一返回格式{"status":xxx,"message":xxx,"data":xxx},故统一封装

//
//  DetailResponse.swift
//  详情网络请求解析类
//
//  Created by jin on 2024/8/23.
//

import Foundation

import HandyJSON

/// 继承BaseResponse
/// 定义了一个泛型T
/// 泛型实现了HandyJSON协议
/// 因为我们希望用户传递的类要能解析为JSON
class DetailResponse<T:HandyJSON> : BaseResponse{
    
    /// 真实数据
    /// 他的类型就是泛型
    var data:T?
    
    init(_ data:T) {
        self.data = data
    }
    
    required init() {
        super.init()
    }
}

封装ListResponse

本文使用的列表接口会统一返回格式{"status":xxx,"message":xxx,"data":{"size":xxx,"page":xxx,"data":[] }},故统一封装

//
//  ListResponse.swift
//  解析列表网络请求
//
//  Created by jin on 2024/8/23.
//

import Foundation

import HandyJSON

class ListResponse<T:HandyJSON> : BaseResponse{
    
    /// 分页元数据
    var data:MetaResponse<T>!
}

封装MetaResponse

//
//  MetaResponse.swift
//  分页模型
//
//  Created by jin on 2024/8/23.
//

import Foundation

import HandyJSON

class MetaResponse<T:HandyJSON> : BaseModel{
    
    /// 真实数据
    var data:[T]?
    
    /// 有多少条
    var total:Int!

    /// 有多少页
    var pages:Int!

    /// 当前每页显示多少条
    var size:Int!

    /// 当前页
    var page:Int!

    /// 下一页
    var next:Int?
}

封装Ad广告对象

//
//  Ad.swift
//  广告模型
//
//  Created by jin on 2024/8/23.
//

import Foundation

class Ad:BaseModel{
    
    var title:String!
    var icon:String!
    var uri:String!
    
    /// 类型,0:图片;10:视频;20:应用
    var style: Int = 0
}

使用封装接口

let provider = MoyaProvider<DefaultService>()

// 广告列表
provider.rx.request(.ads(position: VALUE0))
            .asObservable()
            .mapString()
            .mapObject(ListResponse<Ad>.self)
            .subscribe { event in
                switch(event){
                case .next(let data):
                    print(data.data.data?[0].title!)
                case .error(let error):
                    print("error \(error)")
                case .completed:
                    print("completed")
                }
            }.disposed(by: rx.disposeBag)


//详情
provider.rx.request(.sheetDetail(data: "1"))
            .asObservable()
            .mapString()
            .mapObject(DetailResponse<Sheet>.self)
            .subscribe { event in
                switch(event){
                case .next(let data):
                    print(data.data?.title!)
                case .error(let error):
                    print("error \(error)")
                case .completed:
                    print("completed")
                }
            }.disposed(by: rx.disposeBag)


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

相关文章:

  • AUTOSAR_EXP_ARAComAPI的7章笔记(3)
  • docker构建jdk11
  • HAproxy 详解
  • C++编程:利用环形缓冲区优化 TCP 发送流程,避免 Short Write 问题
  • ssm100医学生在线学习交流平台+vue(论文+源码)_kaic
  • C#发票识别、发票查验接口集成、电子发票(航空运输电子行程单)
  • 银河麒麟高级服务器操作系统(Host版)V10 安装
  • Java算法之梳排序(Comb Sort)
  • Spring Security基于token的极简示例
  • Django 框架中F和Q的作用
  • Stable Diffusion 必备插件推荐,菜鸟轻松成高手!
  • unsloth的微调示例学习-model的构建
  • 70.爬楼梯
  • python-flask-上传文件时表单提交报错:Method Not Allowed
  • 【软件测试】术语定义
  • 【微信小程序】小程序的 MobX 绑定辅助库
  • CSS 实现 两栏布局、三栏布局,以及常见的水平居中的方法
  • C++实现堆排序
  • 电脑丢失dll文件一键修复之dll确实损坏影响电脑运行
  • Ubuntu下安装和配置MQTT服务器Mosquitto
  • hdfs dn锁拆分
  • 【记忆回溯】【深度搜索】【动态规划】【字符串】【力扣】单词拆分
  • Hive SQL 练习
  • 2024 年的 Web3 游戏:演变、趋势和市场动态
  • 【云游戏】点量云流赋能大型游戏新体验
  • MP条件构造器之常用功能详解(or、and、exists、notExists)