美文网首页Swift
SolarNetwork-优雅的Swift网络封装

SolarNetwork-优雅的Swift网络封装

作者: Yohohoho | 来源:发表于2018-02-08 18:01 被阅读120次

    GitHub: SolarNetwork

    前言

    刚开始写Swift项目时,用到网络请求时,毫无疑问,选择了Moya。但随着项目的增大,接口越来越多,TargetType文件也越来越大,寻找某一个接口的参数和其他配置时,就要在各种Switch中跳来跳去,感到十分烦恼,就算分了多个TargetType,也还是存在这个问题,于是就干脆借鉴Moya的优点,基于Alamofire重新封装了一个简单易用的网络库,保留了TargetType的服务配置功能,并将接口配置分离成各个独立的Request,形成一个新的网络库SolarNetwork


    目录


    设计

    SolarNetwork包括以前几个类:

    • SLNetwork 对应一个SessionManager,负责Request的发送,Progress和Response的回调。
    • SLTarget 对应一个Host或者一系列具有相同配置请求的配置。
    • SLRequest, SLDownloadRequest, SLUploadRequest 分别对应Data, Download和Upload,是这3种请求的配置。
    • SLProgress 下载和上传进度的回调。
    • SLResponse 是一个已处理过的Response,你可以进一步选择转换为JsonObject或者Model。
    • SLPlugin 提供了两个切入点,分别用来在请求发送前修改请求的willSend 和 接收到网络回调后修改回调内容的 didReceive
    • SLReflection 负责将SLRequest的子类属性反射为Alamofire.Parameters。

    所以一个网络请求的具体流程为:

    SLNetwork(SLTarget).request(SLRequest).willSend(SLRequest)
                       .progressClosure(SLProgress)
                       .reponseData(OriginalResponse)
                       .didReceive(SLResponse).decodeTo(Dictionary)
                       .completionClosure(SLResponse)
                       .decodeTo(Model: Decodable).dealWithError
    

    大多数情况下,你只需要关心的是:

    SLNetwork(SLTarget).request(SLRequest)
                       .progressClosure(SLProgress)
                       .completionClosure(SLResponse)
    

    特性

    • 灵活的多服务配置(baseURL, Header, ParameterEncoding, URLSessionConfiguration, TSL…...)
    • 完整的数据请求方法
    • 完整的下载和断点下载方法(意外退出也能恢复)
    • 完整的上传方法:File, Data, InputStream, FormData
    • 上传和下载的进度回调
    • 网络状态Reachability回调
    • 保留Alamofire的对外API
    • 修改Request和Response的Plugin
    • Swift4下利用Decodable将JSON转为Model
    • 完整的日志打印

    更多内容请直接到GitHub查看。


    要求

    • iOS 8.0+
    • Xcode 9+
    • Swift 4+

    使用

    配置服务

    import SolarNetwork
    
    struct HTTPBinTarget: SLTarget {
        var baseURLString: String { return "https://httpbin.org" }
    }
    
    let HTTPBinNetwork = SLNetwork(HTTPBinTarget())
    

    发送一个请求

    import SolarNetwork
    
    //Mark: - GET
    class HTTPBinGETRequest: SLRequest {
        
        override func loadRequest() {
            super.loadRequest()
            
            self.path = "/get"
        }
        
    }
    
    HTTPBinNetwork.request(HTTPBinGETRequest()) { (response) in
        if let dictionary = response.dataDictionary {
                            
        }
        else if let error = response.error {
            //show error
        }
    }
    
    //Mark: - POST
    class HTTPBinPOSTRequest: SLRequest {
        
        override func loadRequest() {
            super.loadRequest()
            
            self.method = .post
            self.path = "/post"
        }
        
        /**
         利用反射,将属性自动转换为Parameters,不需要自己组装了
         ["userName": "myUserName",
          "password": "myPassword"]
         */
        let userName = "myUserName"
        let password = "myPassword"
    
    }
    
    HTTPBinNetwork.request(HTTPBinPOSTRequest()) { (response) in
        if let dictionary = response.dataDictionary {
                            
        }
        else if let error = response.error {
            //show error
        }
    }
    

    下载和断点续传

    import SolarNetwork
    
    class GitHubDownloadRequest: SLDownloadRequest {
        
        override func loadRequest() {
            super.loadRequest()
            
            self.URLString = "http://cdnvue.com/video/rzGHzRA19L/64tBZo"
        }
    }
    
    let downloadRequest = GitHubDownloadRequest()
    GitHubNetwork.download(downloadRequest, progressClosure: { (progress) in
                        
    }) { (response) in
                        
    }
    
    //如果需要断点下载此文件,请设置该属性为true
    downloadRequest.isResume = true
    
    //自定义文件下载完成后的存放路径,默认为"/Library/Caches/SLNetwork/Destination/(requestID)"
    downloadRequest.destinationURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
    

    上传

    import SolarNetwork
    
    class HTTPBinUploadRequest: SLUploadRequest {
        
        override func loadRequest() {
            super.loadRequest()
            
            self.path = "/post"
        }
        
    }
    
    let uploadRequest = HTTPBinUploadRequest()
    uploadRequest.data = data //data to upload
    HTTPBinNetwork.upload(uploadRequest, progressClosure: { (progress) in
                                
    }) { (response) in
                                
    }
    

    Decode

    Swift 4下,利用Decodable将Json转为Model

    import SolarNetwork
    
    struct User: Decodable { //Swift 4 Codable
        var id: Int
        var name: String
        var token: String
    }
    
    HTTPBinNetwork.request(UserRequest()) { (response) in
        if let user = response.decode(to: User.self) {
                            
        }
        else if let error = response.error {
            //show error
        }
    }
    
    更多内容,Demo和交流请到GitHub

    相关文章

      网友评论

        本文标题:SolarNetwork-优雅的Swift网络封装

        本文链接:https://www.haomeiwen.com/subject/qbottftx.html