Swift 面向协议编程POP:网络封装

736 阅读1分钟

系列内容,swift学习路上.

“Swift 就是一个面向协议的编程语言” ,如果你看看 Swift 的标准库,那有超过 50个协议。这就是这门语言的成形之处.----那么我们在日常开发中如何使用?

思路:

  • 请求协议: 定义请求参数和数据处理类.
  • 数据处理协议: 定义数据解析.
  • 请求工具协议: 定义host和请求接口.请求接口->网络层实现.

协议代码

//请求协议
protocol PLRequestProtocol {
    //请求参数
    var path: String { get }
    var httpType: PLHTTPMethod { get }
    var params: [String: Any] { get }
    //数据处理
    associatedtype Respose: PLParseAble
}
//数据处理协议
protocol PLParseAble {
   static func parse(data: Data) -> Self?
}
//请求工具协议
protocol PLClientProtocal {
    var host: String { get }
    // 发送请求
    func sendRequest<T: PLRequestProtocol>(_ requst: T, handle: @escaping (T.Respose?) -> Void)
}

实现协议代码

  • 请求类
struct PLPersonRequest: PLRequestProtocol {
    
    let name: String
    
    var path: String {
        return "/pythonJson/getTeacherInfo/?username=\(name)"
    }
    
    let httpType: PLHTTPMethod = .GET
    
    let params: [String : Any] = [:]
    
    typealias Respose = PLPerson
}
  • 数据模型
struct PLPerson {
    let name: String
    init?(data: Data) {
        guard let obj = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any] else {
            return nil
        }
        guard let name = obj["name"] as? String else {
            return nil
        }
        self.name = name
    }
}

extension PLPerson: PLParseAble{
    static func parse(data: Data) -> PLPerson? {
        //处理数据,转化模型
        return PLPerson(data: data)
    }
}
  • 请求工具类
struct PLClient: PLClientProtocal {
    var host: String = "https://127.0.0.0"
    func sendRequest<T>(_ requst: T, handle: @escaping (T.Respose?) -> Void) where T : PLRequestProtocol {
        //网络层: 简易模拟,可以使用其它.
        let url = URL.init(string: host.appending(requst.path))!
        let urlRequst = URLRequest.init(url: url)
        let task = URLSession.shared.dataTask(with: urlRequst) {
            (data, respose, error) in
            if let data = data, let res = T.Respose.parse(data: data) {
                DispatchQueue.main.async { handle(res) }
            } else {
                DispatchQueue.main.async { handle(nil) }
            }
        }
        task.resume()
    }
}

使用操作

        //调用代码
        let requst = PLPersonRequest(name: "tom")
        PLClient().sendRequest(requst) { (person) in
            if let model = person{
                print(model)
            }
        }

持续思考

  • 结构清晰合理
  • 实现方式优雅
  • 使用方便