Swift基于Alamofire的再次封装


OC中我们习惯使用AFNetworking进行网络请求,而Alamofire是同一团队开发的Swift版本,也是进行Swift项目开发必备的三方库。我们在使用AFNetWorking网络请求时习惯对它进行再次封装,同样Alamofire也需要我们的封装,以便让我们的代码更加精简。

封装需要解决的问题点:

  • 网络环境可动态配置:开发环境测试环境生产环境等。
  • 有可能存在多个服务,服务地址可设置。不同的请求可能使用不同的IP地址。
  • 接口API 单独存放,便于统一维护管理。
  • 网络请求设置 Request Header。
  • 请求成功与失败数据统一处理。
  • 尽可能覆盖多种请求功能:登录GetPost图片上传下载等。

  1. 可配置的网络环境,使用enum来设置
/*
 * 配置你的网络环境
 */
enum  NetworkEnvironment{
    case Development
    case Test
    case Distribution
}
  1. 定义多个私有属性,来存储不同的服务地址
// 登录服务
private var LogInBase_Url = ""
// 普通服务
private var ProgressBase_Url = ""
  1. 根据设置的开发环境不同,服务地址发生改变
let CurrentNetWork : NetworkEnvironment = .Test

private func judgeNetwork(network : NetworkEnvironment = CurrentNetWork){
    
    if(network == .Development){
        
        LogInBase_Url = "http://dev-***.com/common-portal/"
        ProgressBase_Url = "http://dev-***.com:8080/isp-kongming/"
        

    }else if(network == .Test){
        
        LogInBase_Url = "http://test-***.com/common-portal/"
        ProgressBase_Url = "http://test-***.com/isp-kongming/"
        
    }else{
        
        LogInBase_Url = "https://***.com/common-portal/"
        ProgressBase_Url = "https://***.com/isp-kongming/"
        
    }
}
  1. 封装网络请求。备注:我们使用SwiftyJSON三方库来解析Response数据. 声明协议方法:
protocol NetworkToolDelegate {
    // 登录请求
    static func goToLogin(userName:String,password:String,completionHandler: @escaping(_ dict:[String : AnyObject]) -> (), errorHandler: @escaping(_ errorMsg : String) ->(), networkFailHandler: @escaping(_ error : Error) -> ())
    //GET 请求
    static func makeGetRequest(baseUrl : String,parameters : [String:AnyObject],successHandler: @escaping(_ json:JSON) ->(),errorMsgHandler : @escaping(_ errorMsg : String) ->(),networkFailHandler:@escaping(_ error : Error) -> ())
    
    
    //POST 请求
    static func makePostRequest(baseUrl : String,parameters : [String:Any],successHandler: @escaping(_ json:JSON) ->(),errorMsgHandler : @escaping(_ errorMsg : String) ->(),networkFailHandler:@escaping(_ error : Error) -> ())
    
    /*  图片上传 请求
     * imageData : 图片二进制数组
     */
    static func upDataIamgeRequest(baseUrl : String,parameters : [String : String],imageArr : [UIImage],successHandler: @escaping(_ dict:JSON) ->(),errorMsgHandler : @escaping(_ errorMsg : String) -> (),networkFailHandler: @escaping(_ error:Error) -> ())
    
}
  1. 接口Api的统一维护,新建Swift文件,分清功能模块。
import Foundation
//MARK: - 反馈接口
//反馈提交
let   cmd_custInsertUserFeedback  = "cust/insertUserFeedback"
// 反馈 列表
let   cmd_custSelectUserFeedback  =  "cust/selectUserFeedback"
//图片上传 反馈
let   cmd_custImgUpdate           =  "cust/imgUpdate"

//MARK: - 内容营销
//栏目列表
let   cmd_contentDictList          =         "content/dictList"
//产品列表
let   cmd_contentUserProduct        =        "content/app/product"
//产品详情
let  cmd_contentProductInfo         =        "content/product/info"
//往期回顾 列表
let  cmd_contentProductHistoryList    =       "content/app/historyProduct"

//MARK: - 发票模块
//筛选条件
let   cmd_GetInvoiceMenu    = "GetInvoiceMenu"
//发票列表
let   cmd_GetInvoiceList     = "GetInvoiceList"
// 发票明细
let  cmd_GetInvoiceInfo     = "GetInvoiceInfo"
//合同信息
let  cmd_GetInvoiceContractInfo    = "GetInvoiceContractInfo"
//更新签收状态
let  cmd_SaveInvoiceStatus     = "SaveInvoiceStatus"
//上传回执信息
let  cmd_SaveInvoiceUrl      = "SaveInvoiceUrl"
//获取审批信息
let  cmd_GetInvoiceLog     = "GetInvoiceLog"

  1. 实现扩展方法
    需要注意的点:
    • 这里有三个闭包: completionHandler :网络请求正常并且登录成功后调用。errorHandler :网络请求正常,但是登录失败时候调用,errorMsg是 服务返回的错误提示。networkFailHandler: 网络请求失败或者服务异常调用。
    • @escaping() : 逃逸闭包
    • 方法 参数encoding有三种取值:
      (1)URLEncoding 和URL相关的编码,有两种编码方式:直接拼接到URL中通过request的httpBody传值
      (2)JSONEncoding 把参数字典编码成JSONData后赋值给request的httpBody
      (3) PropertyListEncoding把参数字典编码成PlistData后赋值给request的httpBody
    • 获取cookie 的方式
 let headerFields = response.response?.allHeaderFields as! [String : String]
 let userCookie =  headerFields["Set-Cookie"]`

最后的方法实现

extension NetworkToolDelegate{
    
 static func goToLogin(userName:String,password:String,completionHandler: @escaping(_ dict:[String : AnyObject]) -> (), errorHandler: @escaping(_ errorMsg : String) ->(), networkFailHandler: @escaping(_ error : Error) -> ()){
        // 调用 网络请求判断方法
        judgeNetwork();
        let url = LogInBase_Url + "common/portal/login"

        let dict = ["username":userName,"password":password]
        Alamofire.request(url, method: .get, parameters: dict, encoding:URLEncoding.default, headers: nil).responseJSON { (response) in

            print(response)
            
            // 网络连接或者服务错误的提示信息
            guard response.result.isSuccess else
            { networkFailHandler(response.error!); return }
            // 保存 cookies
            let headerFields = response.response?.allHeaderFields as! [String : String]
            let userCookie =  headerFields["Set-Cookie"]
           // print("userCookie>>>>>>\(userCookie ?? "0000000")")
            UserDefaults.standard.set(userCookie, forKey: "userCookies")
            UserDefaults.standard.synchronize()
            
            if let value = response.result.value {
                let json = JSON(value)
                print(json)
                // 请求成功 但是服务返回的报错信息
                guard json["errorCode"].intValue == 0 else { errorHandler(json["errorMsg"].stringValue); return }
                
                if let resultDict = json["result"].dictionary{
                    
                    completionHandler(resultDict as [String : AnyObject])

                }
            }
        }
    }
}

这里登录接口单独拿出来是因为,我们需要登录接口获取cookie,在接下来的请求中,我们会把cookie放入 Request Header 发起请求。其他功能类似此方法,这里不再复写,具体的源码可参见我的Github

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • 打卡日期:2018年8月28日 打卡累计天数:25/30 #宣言(父母的高度决定孩子的起点)# 孩子第一个30天目...
    霞_4d30阅读 70评论 0 0