Swift -- 对AFN框架的封装
一.封装AFN的目的
-
简单的说: 解耦
-
日常工作中,我们一般都不会去直接使用AFNetWorking来直接发送网络请求,因为耦合性太强,假设有多个控制器都使用AFN发送请求,那么假设有一天AFN框架的作者不更新了,到时我们需要改动的地方太多太多~
-
所以这里我们要自己来封装AFN
二.封装之前准备工作:
- 利用cocoapods集成AFN框架
三.封装AFN的方式
- 封装AFN有两种方法:
- 工具类,继承NSObject
- 继承AFHTTPSessionManager
四.封装实现
第一种, 继承NSObject封装AFN
实现代码如下:
import UIKit
import AFNetworking
// 请求类型
enum RequestType
{
case Get
case Post
}
class MTYNetWorking: NSObject {
// 单例
static let shareInstance = MTYNetWorking()
// 懒加载 - 方式1: 单纯的懒加载
lazy var mgr = AFHTTPSessionManager()
/* 懒加载 - 方式2: 可以对请求管理者做些初始化的操作
lazy var mgr = {
// 可以做些初始化的操作
return $0
}(AFHTTPSessionManager())
*/
/// 对外提供的网络请求接口
///
/// - Parameters:
/// - requestType: 发送请求的类型,是个枚举
/// - url: 请求路径
/// - parameters: 请求参数,字典类型
/// - resultBlock: 请求结果
func request(requestType:RequestType,
url:String,
parameters:[String: Any],
resultBlock:@escaping (_ response: [String: Any]?,_ error: String?) -> ())
{
// 请求成功的闭包
let successBlock = { (task: URLSessionDataTask, response: Any?) in
// 拿到结果
resultBlock((response as? [String: Any])!, nil)
}
// 请求失败的闭包
let failuerBlock = { (task: URLSessionDataTask?, error: Error) in
// 拿到结果
resultBlock(nil, error.localizedDescription)
}
// 发送异步 Get请求
if requestType == .Get {
mgr.get (
url,
parameters: parameters,
progress: nil,
success: successBlock,
failure: failuerBlock
)
// 发送异步 Post请求
}else if requestType == .Post
{
mgr.post (
url,
parameters: parameters,
progress: nil,
success: successBlock,
failure: failuerBlock
)
}
}
}
封装时的注意点:
1.单例:
因为上面的封装使用的是对象方法
,外界模块在使用我们这个工具类时每次都会创建一个对象,来调用接口,然后他们并不会被释放,所以为了保证整个内存里面只存在一个对象,要使用单例.
// static 保证内存中只有1份
// let 常量,不可以被改变
// 因为shareInstance这个属性是依附于类(MTYNetWorking)的,所以只有一份
static let shareInstance = MTYNetWorking()
2.懒加载请求管理者的两种方式
3.为什么使用闭包
来传值
- 设计这个接口的最终目的,就是拿到请求后的返回结果.但是我们不能把这个结果放到方法的返回值处,这样外界在调用的时候要么立即拿到这个结果,否则就会等待这个结果,也就是发送了一个同步的请求,这样会阻塞主线程,影响用户的体验,所以一般使用逃逸闭包来传值
- AFN框架的success和failure后面的闭包的目的就是要告诉我们请求结果的,无论是请求成功还是失败
- 而我们设计这个接口的目的就是通过闭包来告诉外面的结果
第二种, 继承AFHTTPSessionManager封装AFN
代码实现
import UIKit
import AFNetworking
// 请求类型
enum RequestType2
{
case Get
case Post
}
class MTYNetWorkingTool: AFHTTPSessionManager {
// 单例
static let shareInstance = MTYNetWorkingTool()
func request(type: RequestType2,
url: String,
parameters: [String: Any],
resultBlock:@escaping ((_ response:[String: Any]?, _ error: Error?) ->())) {
// 成功的闭包
let successBlock = { (task: URLSessionDataTask, response: Any?) in
resultBlock(response as? [String: Any], nil)
}
// 失败的闭包
let failureBlock = { (task: URLSessionDataTask?, error: Error) in
resultBlock(nil, error)
}
// Get 请求
if type == .Get {
get(
url,
parameters: parameters,
progress: nil,
success: successBlock,
failure: failureBlock
)
// Post请求
}else if type == .Post {
post(
url,
parameters: parameters,
progress: nil,
success: successBlock,
failure: failureBlock
)
}
}
}
如有错误之处,请指正!谢谢~