Swift:NetworkController

本文详细介绍了一种在Swift中封装网络请求的方法,包括APIRequestConfigure的定义与使用,APIRequestLoader的实现,以及Session协议的抽象。通过具体的代码示例,展示了如何利用这些组件进行API调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本篇主要介绍如何建一个networkController进行API Call。首先是APIRequestConfigure

protocol APIRequestConfigure {
    var url: String { get }
    var cachePolicy: URLRequest.CachePolicy? { get }
    var timeoutInterval: TimeInterval? { get }
    var header: [String:String]? { get }
    var httpBody: Data? { get }
    var httpMethod: String? { get }
}

extension APIRequestConfigure {
    func makeRequest() throws -> URLRequest {
        guard let url = URL(string: url) else { throw NetworkError.invalidURL }
        var request = URLRequest(url: url, cachePolicy: cachePolicy ?? URLRequest.CachePolicy.useProtocolCachePolicy, timeoutInterval: timeoutInterval ?? 10)
        request.allHTTPHeaderFields = header
        request.httpBody = httpBody
        request.httpMethod = httpMethod
        return request
    }
}

这个APIRequestConfigure主要是对API Request进行一个封装。这里除了URL,其他的parameter都是optional。
接下来是APIRequestLoader

class APIRequestLoader {
    let apiRequest: APIRequestConfigure
    let urlSession: Session
    
    init(apiRequest: APIRequestConfigure, urlSession: Session = URLSession.shared) {
        self.apiRequest = apiRequest
        self.urlSession = urlSession
    }
    
    func loadRequest<T: Codable>(completionHandler: @escaping ((T?, Error?) -> Void)) {
        guard let request = try? apiRequest.makeRequest() else {
            completionHandler(nil, NetworkError.invalidRequest)
            return
        }
        urlSession.getData(with: request) { (data, error) in
            guard error == nil else {
                completionHandler(nil, error)
                return
            }
            guard let data = data else {
                completionHandler(nil, NetworkError.noData)
                return
            }
            do {
                let decodedData = try JSONDecoder().decode(T.self, from: data)
                completionHandler(decodedData, nil)
            } catch {
                completionHandler(nil, NetworkError.invalidJSONData)
            }
        }
    }
}

这个就是比较常规的用URLSession进行APICal了。在初始化中我把default的session设置为URLSession.share,方便如果需要用其他的framework的话,可以在这里进行插入。接下来是Session。

protocol Session {
    func getData(with url: URL, completionHandler: @escaping (Data?, Error?) -> Void)
    func getData(with request: URLRequest, completionHandler: @escaping(Data?, Error?) -> Void)
}

extension URLSession: Session {
    func getData(with request: URLRequest, completionHandler: @escaping (Data?, Error?) -> Void) {
        self.dataTask(with: request) { (data, _, error) in
            completionHandler(data, error)
        }.resume()
    }
    
    func getData(with url: URL, completionHandler: @escaping (Data?, Error?) -> Void) {
        self.dataTask(with: url) { (data, _, error) in
            completionHandler(data, error)
        }.resume()
    }
}

这里用Protocol作为一个abstract方便之后的使用,并把它作为subclass添加到了URLSession里,这样在使用URLSession的时候,也可以getData进行APICall。最后是NetworkRequestConfigure。

struct NetworkRequestConfigure: APIRequestConfigure {
    var url: String
    
    var cachePolicy: URLRequest.CachePolicy?
    
    var timeoutInterval: TimeInterval?
    
    var header: [String : String]?
    
    var httpBody: Data?
    
    var httpMethod: String?
}

用之前的APIRequestConfigure作为subclass,代入后就可以用这个NetworkRequestConfigure作为一个abstract方便之后的使用。
最后来看我是如何使用它的

   private var apiRequestLoader: APIRequestLoader
    
    init(apiRequestLoader: APIRequestLoader? = nil) {
        if let apiRequestLoader = apiRequestLoader {
            self.apiRequestLoader = apiRequestLoader
        } else {
            let ituneRssRequestConfig: APIRequestConfigure = ItunesRssRequestConfig()
            let apiRequestLoader = APIRequestLoader(apiRequest: ituneRssRequestConfig)
            self.apiRequestLoader = apiRequestLoader
        }
    }

在ViewModel里创建一个apiRequestLoader,然后在初始化里把它设置成optional。再用if let进行optional binding。如果在初始化里有apiRequestLoader,就等于它。如果没有,就等于我设置的这个viewModel该需要的ituneRssRequestConfig(这个ituneRss有APIRequestConfigure里多加了一个需要使用的URL)。下面是github

https://github.com/grm121616/NetworkController/tree/master/NetworkController

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值