Alamofire+HandyJSON+泛型封装的简单离散式网络框架
Posted Androider_Zxg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Alamofire+HandyJSON+泛型封装的简单离散式网络框架相关的知识,希望对你有一定的参考价值。
离散式与集约式网络框架
集约式:
每个请求都会走统一的入口,对外暴露了请求的 URL 和 Param 以及请求方式,入口一般都是通过单例
来实现。例如
HttpClient.getInstance().sendRequest(url,params,callback)
优点:
1、使用便捷,可以快速开发
缺点:
1、对每个请求的定制要求不够,例如,现在有个新需求,请求新闻条目需要保存网络缓存,但其他网络请求不需要。那么我们必须新开一个sendRequest()方法,其中加一个参数isCache。这种情况对后期业务扩展非常不友好。
离散式:
即每个网络请求类都是一个对象,它的 URL 以及请求方式和响应方式 均不暴露给外部调用。只能内部通过 重载或实现协议
的方式来指定,例如ios中的YTKNetWork即是这种方式。思想是为每一个请求编写一个配置类,在该类中重写接口(协议)中定义的方法返回该网络请求需要的参数。
优点:
1、扩展性强
2、URL 以及请求和响应方式不暴露给外部,避免外部调用的时候写错,设想一下,使用集约式设计,我们所有的URL地址均写在一个类似URLContants的文件中,那么新增、修改、删除url都需要修改该文件,大大提高了出错风险。
3、可定制性强,可以为每个请求指定请求的超时时间以及缓存的周期
缺点:
每个网络请求都要配置一个类,业务丰富后类数量较多
好,有了简单的概念了解后,我们进入正题,设计一套离散式的网络框架
swift离散式网络框架
1、框架性代码HttpRestfulClient
核心类,封装第三方网络请求库,暴露请求方式,是单例。我就将代码完全粘进来了,保证同学能看得懂
//
// HttpRestfulClient.swift
// HelloIOS
//
// Created by zxg on 2018/10/29.
// Copyright © 2018年 zxg. All rights reserved.
//
import UIKit
import Alamofire
import SwiftyJSON
import HandyJSON
class HttpRestfulClient
static let sharedInstance = HttpRestfulClient()
private init()
// let device_id: Int = 6096495334
// let iid: Int = 5034850950
//Demo
//这里使用了逃逸闭包,因为responseJson为异步,所以当网络请求结果回来后,事实上testRequest()方法已经执行完了。那么
//传入函数testRequest()的闭包是在testRequest()函数执行完后,才要执行的,也就是说这个闭包已经逃逸到函数外部了。所以要加该注解
//swift3.0默认是非逃逸的
//弊端
//该方法拿到数据后,字节解析字段,破坏了封装性。合理的做法应该是封装成model,再调用闭包,把model给出去
public func testRequset<T:HandyJSON>(_ completionHandler: @escaping(_ dataFromNet:AnyObject)->(),_ protocol:BaseProtocol<T>)
// let params = ["device_id": device_id, "iid": iid]
// Alamofire.request("https://is.snssdk.com/search/suggest/homepage_suggest/?", method: .get, parameters params).responseString
// (response) in
// if let value = response.result.value
// print("value:",value5034850950)
// let json = JSON(value)
// print(json)
// guard json["message"] == "success" else return
//
// if let data = json["data"].dictionary
// completionHandler(data["homepage_search_suggest"]!.string!)
//
// let responseModel = BaseResponse<T>.deserialize(from: value)!
// print("model:",responseModel.data)
// completionHandler((responseModel.data as? AnyObject)!)
//
//
//网络请求函数,参数固定,所有网络请求参数放在netProtocol中,即使以后扩展
//也不需要改变接口
public func sendRequset<T:HandyJSON>(_ netProtocol:BaseProtocol<T>,_ competionHandler:@escaping(_ model:AnyObject?,_ error:NetError)->())
var error:NetError = NetError.SUCCESS
Alamofire.request(netProtocol.getOpertion()!,
method: transformMethod(netProtocol.getMethod()),
parameters: netProtocol.getParams()).responseString
(response) in
if let value = response.result.value
print("value:",value)
let responseModel = BaseResponse<T>.deserialize(from: value)!
if(responseModel.message! != "success")
error = NetError.DATA_ERROR
competionHandler(responseModel.data as? AnyObject,error)
//自定义NetMethod转Alamofire.HTTPMethod,目的是对上层完全隐藏Alamofire,这样即使换掉Alamofire框架
//上层也不需要改动
private func transformMethod(_ method:NetMethod)->HTTPMethod
switch method
case .GET:
return HTTPMethod.get
case .POST:
return HTTPMethod.post
default:
return HTTPMethod.get
enum NetError:Int
case SUCCESS = 0;
case DATA_ERROR = 1;
enum NetMethod:Int
case GET = 10;
case POST = 20;
框架性代码BaseProtocol
该类作为sendRequest()的核心参数,封装网络请求参数,业务层开发时,不同的网络请求均要实现这样一个类
//
// BaseProtocol.swift
// HelloIOS
//
// Created by zxg on 2018/10/29.
// Copyright © 2018年 zxg. All rights reserved.
//
import UIKit
import HandyJSON
class BaseProtocol<T:HandyJSON>
//返回网络请求参数
func getParams()->Dictionary<String, AnyObject>?
return nil;
//返回网络地址url
func getOpertion()->String?
return nil
//返回请求方法
func getMethod()->HttpRestfulClient.NetMethod
return HttpRestfulClient.NetMethod.GET
//以后可以增加接口
public required init()
框架性代码BaseResponse
用于使用HandyJSON进行Json解析,HandyJSON和Gson很像,都是采用反射、泛型等技术进行json与model的映射,不需要手动解析每一个字段,这里使用泛型,也是为了外部在调用时,通过泛型将需要映射成的目标model类传进来,sendRequest内部进行解析。其实也可以直接将jsonStr抛给netProtocol,让解析response这个动作也离散式的分解到每一个protocol中。而封装BaseResponse的目的是做一些通用逻辑,例如在进行Model转换前,判断message是否为success。是success再进行model转换否则抛出error
//
// BaseResponse.swift
// HelloIOS
//
// Created by zxg on 2018/10/31.
// Copyright © 2018年 zxg. All rights reserved.
//
import Foundation
import HandyJSON
class BaseResponse<T>:HandyJSON
var message:String?
var data:T?
public required init()
业务性代码
这里我们站在业务端角度,使用一下该简单框架,网络请求的名字就叫TestNet吧
为本次网络请求配置Protocol类:TestNetProtocol
//
// TestNetProtocol.swift
// HelloIOS
//
// Created by zxg on 2018/11/1.
// Copyright © 2018年 zxg. All rights reserved.
//
import Foundation
import HandyJSON
class TestNetProtocol:BaseProtocol<TestNetResponse>
var device_id:Int=0
var iid:Int=0
override func getParams()->Dictionary<String, AnyObject>?
return ["device_id": device_id as AnyObject, "iid": iid as AnyObject];
override func getOpertion()->String?
return "https://is.snssdk.com/search/suggest/homepage_suggest/?"
override func getMethod() -> HttpRestfulClient.NetMethod
return HttpRestfulClient.NetMethod.GET
required init()
super.init()
Response类
//
// TestNetResponse.swift
// HelloIOS
//
// Created by zxg on 2018/10/31.
// Copyright © 2018年 zxg. All rights reserved.
//
import Foundation
import HandyJSON
class TestNetResponse:HandyJSON
var call_per_refresh:Int?
var homepage_search_suggest:String?
var suggest_words:[SuggestWord]?
required init()
class SuggestWord:HandyJSON
var id:Int?
var or:String?
var word:String?
required init()
在Controller中调用
//测试访问网络
@IBAction func testNet(_ sender: Any)
prot.device_id = 6096495334
prot.iid = 5034850950
print("testNetWork click")
HttpRestfulClient.sharedInstance.sendRequset(prot,(model,error) in
if error != HttpRestfulClient.NetError.SUCCESS
print("error")
return
if let data = model as? TestNetResponse
self.updateUI(model: data)
)
private func updateUI(model:TestNetResponse)
self.tvNetData.text = model.homepage_search_suggest!
网络返回的json:
testNetWork click
value: "data":"call_per_refresh":1,"homepage_search_suggest":"劳森 | 今晚中国女排直播5 | 古德洛克","suggest_words":["id":"6538744360526157064","or":"qcrs:65","word":"劳森","id":"6605143180503422221","or":"qc:349 qcrs:15","word":"今晚中国女排直播5","id":"6573947909807592707","or":"qcrs:66","word":"古德洛克"],"message":"success"
后记
逻辑比较简单,没有处理缓存、header头等逻辑,仅仅是为了展示离散式网络访问思想的优点,以及练习下swift的泛型、闭包等技术。如果有时间,后期会丰富。
以上是关于Alamofire+HandyJSON+泛型封装的简单离散式网络框架的主要内容,如果未能解决你的问题,请参考以下文章