【iOS Swift Moya 最新请求网络框架封装通用】

【iOS Swift Moya 最新请求网络框架封装通用】

前言

设计一个基于Moya的网络请求框架,可以提供灵活的网络请求管理,例如设置请求超时时间、暂停某个正在进行的请求等功能。以下让我们一起来设计框架示例,包括关键部分的代码实现和详细说明。

框架结构

1. API定义(TargetType) : 定义所有的API接口。
2. 网络提供者(MoyaProvider) : 配置MoyaProvider,包括自定义Session以设置请求超时时间。
3. 网络管理器、网络响应处理 : 管理请求的发起、暂停和恢复;处理网络请求的响应和错误。
4. 使用实例。

1.API定义(TargetType)

  • 首先,定义一个符合TargetType协议的枚举来描述所有的API接口。例如,假设我们有一个用户相关的API:

    dart 复制代码
    import Moya
    
    enum UserAPI {
        case getUser(id: Int)
        case updateUser(id: Int, parameters: [String: Any])
        // 其他API接口
    }
    
    extension UserAPI: TargetType {
        var baseURL: URL {
            return URL(string: "https://api.example.com")!
        }
    
        var path: String {
            switch self {
            case .getUser(let id):
                return "/user/\(id)"
            case .updateUser(let id, _):
                return "/user/\(id)"
            }
        }
    
        var method: Moya.Method {
            switch self {
            case .getUser:
                return .get
            case .updateUser:
                return .put
            }
        }
    
        var task: Task {
            switch self {
            case .getUser:
                return .requestPlain
            case .updateUser(_, let parameters):
                return .requestParameters(parameters: parameters, encoding: JSONEncoding.default)
            }
        }
    
        var headers: [String : String]? {
            return ["Content-Type": "application/json"]
        }
    
        var sampleData: Data {
            // 提供模拟数据
            return Data()
        }
    }

2. 配置MoyaProvider

  • 为了设置请求超时时间,我们需要自定义Session并传递给MoyaProvider。同时,为了管理请求任务,我们需要保存Cancellable对象。

    dart 复制代码
    import Moya
    import Alamofire
    
    class NetworkProvider {
        static let shared = NetworkProvider()
        
        private let provider: MoyaProvider<UserAPI>
        private var cancellables: [String: Cancellable] = [:]
        private var pendingRequests: [String: (target: UserAPI, completion: (Result<Response, MoyaError>) -> Void)] = [:]
        private let lock = NSLock()
    
        private init() {
            let configuration = URLSessionConfiguration.default
            configuration.timeoutIntervalForRequest = 30 // 设置请求超时时间为30秒
            configuration.timeoutIntervalForResource = 60 // 设置资源请求超时时间为60秒
    
            let session = Alamofire.Session(configuration: configuration)
    
            provider = MoyaProvider<UserAPI>(session: session, plugins: [NetworkLoggerPlugin()])
        }
    
        /// 发起网络请求
        func request(_ target: UserAPI,
                     identifier: String? = nil,
                     completion: @escaping (Result<Response, MoyaError>) -> Void) {
            let id = identifier ?? UUID().uuidString
            pendingRequests[id] = (target, completion)
            let cancellable = provider.request(target) { [weak self] result in
                self?.lock.lock()
                self?.cancellables.removeValue(forKey: id)
                self?.pendingRequests.removeValue(forKey: id)
                self?.lock.unlock()
                completion(result)
            }
            lock.lock()
            cancellables[id] = cancellable
            lock.unlock()
        }
    
        /// 暂停指定的请求
        func pauseRequest(identifier: String) {
            lock.lock()
            if let cancellable = cancellables[identifier] {
                cancellable.cancel()
                cancellables.removeValue(forKey: identifier)
                // 请求已取消,保留在pendingRequests以便恢复
            }
            lock.unlock()
        }
    
        /// 暂停所有请求
        func pauseAllRequests() {
            lock.lock()
            for (id, cancellable) in cancellables {
                cancellable.cancel()
                // 请求已取消,保留在pendingRequests以便恢复
            }
            cancellables.removeAll()
            lock.unlock()
        }
    
        /// 重新发起指定的请求
        func resumeRequest(identifier: String) {
            lock.lock()
            guard let request = pendingRequests[identifier] else {
                lock.unlock()
                return
            }
            let cancellable = provider.request(request.target) { [weak self] result in
                self?.lock.lock()
                self?.cancellables.removeValue(forKey: identifier)
                self?.pendingRequests.removeValue(forKey: identifier)
                self?.lock.unlock()
                request.completion(result)
            }
            cancellables[identifier] = cancellable
            lock.unlock()
        }
    
        /// 重新发起所有请求
        func resumeAllRequests() {
            lock.lock()
            for (id, request) in pendingRequests {
                let cancellable = provider.request(request.target) { [weak self] result in
                    self?.lock.lock()
                    self?.cancellables.removeValue(forKey: id)
                    self?.pendingRequests.removeValue(forKey: id)
                    self?.lock.unlock()
                    request.completion(result)
                }
                cancellables[id] = cancellable
            }
            lock.unlock()
        }
    }

    说明:

    • 自定义Session: 通过URLSessionConfiguration设置请求超时时间。
    • 管理Cancellable: 使用字典cancellables来保存每个请求的Cancellable对象,通过唯一标识符管理请求的取消。
    • 请求方法: request方法用于发起请求,并保存Cancellable对象。
    • 暂停请求: pauseRequest方法通过标识符取消指定的请求,pauseAllRequests取消所有请求。

3. 网络管理器

  • 创建一个更高层次的网络管理器,用于处理不同类型的API请求,提供更方便的接口给业务层使用。

    dart 复制代码
    import Foundation
    import Moya
    
    class NetworkManager {
        static let shared = NetworkManager()
        
        private let networkProvider = NetworkProvider.shared
    
        private init() {}
    
        /// 获取用户信息
        func getUser(id: Int, identifier: String? = nil, completion: @escaping (Result<Response, MoyaError>) -> Void) {
            networkProvider.request(.getUser(id: id), identifier: identifier, completion: completion)
        }
    
        /// 更新用户信息
        func updateUser(id: Int, parameters: [String: Any], identifier: String? = nil, completion: @escaping (Result<Response, MoyaError>) -> Void) {
            networkProvider.request(.updateUser(id: id, parameters: parameters), identifier: identifier, completion: completion)
        }
    
        /// 暂停指定请求
        func pauseRequest(identifier: String) {
            networkProvider.pauseRequest(identifier: identifier)
        }
    
        /// 暂停所有请求
        func pauseAllRequests() {
            networkProvider.pauseAllRequests()
        }
    
        /// 重新发起指定请求
        func resumeRequest(identifier: String) {
            networkProvider.resumeRequest(identifier: identifier)
        }
    
        /// 重新发起所有请求
        func resumeAllRequests() {
            networkProvider.resumeAllRequests()
        }
    
        // 其他API接口的封装
    }

    说明:

    • NetworkManager封装了所有的API接口调用,提供统一的入口。

    • 通过identifier参数,可以为每个请求指定唯一标识符,以便后续管理(暂停、取消等)。

    • 需要注意的是,HTTP请求本身并不支持暂停和恢复,只能取消并重新发起请求。如果实现类似暂停和恢复的功能,通常需要在请求被取消后,重新发起相同的请求。

4. 使用示例

  • 下面是如何使用上述框架进行网络请求、设置超时和暂停请求的示例。

    dart 复制代码
    import UIKit
    import Moya
    
    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            
            // 发起获取用户信息的请求
            let requestIdentifier = "getUser_123"
            NetworkManager.shared.getUser(id: 123, identifier: requestIdentifier) { result in
                switch result {
                case .success(let response):
                    do {
                        // 解析数据
                        let json = try response.mapJSON()
                        print("User Info: \(json)")
                    } catch {
                        print("解析错误: \(error)")
                    }
                case .failure(let error):
                    print("请求失败: \(error)")
                }
            }
            
            // 示例:在某个时刻暂停请求
            // NetworkManager.shared.pauseRequest(identifier: requestIdentifier)
            
            // 示例:在另一个时刻恢复请求
            // NetworkManager.shared.resumeRequest(identifier: requestIdentifier)
        }
    }

    说明:

    • 发起请求时,提供一个唯一的identifier用于后续管理。
    • 可以根据业务需求,在适当的时机调用pauseRequest或pauseAllRequests来取消请求。

注意事项

  1. 暂停和恢复请求: HTTP请求本身不支持暂停和恢复,pause操作实际上是取消请求,resume操作需要重新发起相同的请求。
  2. 线程安全: 使用NSLock确保对cancellables和pendingRequests的访问是线程安全的。
  3. 请求标识符: 为每个请求提供唯一的标识符,以便后续管理。可以使用UUID或自定义的字符串。
  4. 错误处理: 根据实际需求,完善错误处理和重试机制。
  5. 扩展性: 可以根据项目需求,进一步扩展网络框架,例如添加更多的插件、支持多种认证方式等。

进一步优化

  1. 支持多种API接口: 将UserAPI扩展为包含所有需要的API接口,或者使用多个TargetType枚举。
  2. 响应解析: 提供统一的响应解析方法,例如使用Codable解析JSON数据。
  3. 缓存机制: 根据需求添加网络缓存策略,提高性能。
  4. 重试机制: 对于失败的请求,添加自动重试机制。

通过以上设计和实现,您将拥有一个基于Moya的灵活且功能完整的网络请求框架,能够满足设置请求超时时间、暂停和恢复请求等需求。

需要讨论可加V:Jun_Yeong-Huang

相关推荐
O。o.尊都假都4 小时前
UDP协议
linux·服务器·网络·网络协议·udp
科技小E4 小时前
国标GB28181视频平台EasyCVR安防系统部署知识:如何解决异地监控集中管理和组网问题
大数据·网络·人工智能·音视频
yangpipi-5 小时前
10.王道_HTTP
网络协议·http·ios
无锡耐特森5 小时前
ProfiNet与CANopen:新能源时代的“语言翻译官”
网络·网络协议
Pythonliu75 小时前
启智平台调试 qwen3 4b ms-swift
开发语言·swift
成都渲染101云渲染66665 小时前
blender云渲染指南2025版
前端·javascript·网络·blender·maya
虾球xz5 小时前
游戏引擎学习第260天:在性能分析器中实现钻取功能
网络·c++·学习·游戏引擎
AORO_BEIDOU5 小时前
遨游科普:2025年,三防平板有多智能?
网络·人工智能·安全·智能手机·电脑·信息与通信
搬码临时工6 小时前
如何通过外网访问内网?对比5个简单的局域网让互联网连接方案
服务器·网络·智能路由器·内网穿透·外网访问
鸡哥爱技术7 小时前
网工实验——OSPF配置
网络·智能路由器