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 安装与使用 

IOS 14 封装网络请求框架_第1张图片

添加完依赖后,看一下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(_ type : T.Type) -> Observable {
        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 = [:]
        
        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 : 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 : BaseResponse{
    
    /// 分页元数据
    var data:MetaResponse!
}

封装MetaResponse

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

import Foundation

import HandyJSON

class MetaResponse : 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()

// 广告列表
provider.rx.request(.ads(position: VALUE0))
            .asObservable()
            .mapString()
            .mapObject(ListResponse.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.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)

IOS 14 封装网络请求框架_第2张图片

你可能感兴趣的:(IOS,ios)