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
) }
} }

如有错误之处,请指正!谢谢~

Swift -- 对AFN框架的封装的更多相关文章

  1. AFN框架基本使用

    0.AFN框架基本使用 0.1 AFN内部结构 AFN结构体 - NSURLConnection + AFURLConnectionOperation(已经被废弃) + AFHTTPRequestOp ...

  2. AFN框架

    0.AFN框架基本使用 0.1 AFN内部结构 AFN结构体 - NSURLConnection + AFURLConnectionOperation(已经被废弃) + AFHTTPRequestOp ...

  3. 【SSH进阶之路】一步步重构容器实现Spring框架——彻底封装,实现简单灵活的Spring框架(十一)

    文件夹      [SSH进阶之路]一步步重构容器实现Spring框架--从一个简单的容器開始(八)      [SSH进阶之路]一步步重构容器实现Spring框架--解决容器对组件的"侵入 ...

  4. Thinkphp3.2.3框架下封装公共的函数,例如封装CURL函数来获取接口数据

    当我们需要在控制层调用相同的封装函数时,写多次相同的函数,显得代码十分的拉杂,不精简: TP框架有一个很好的机制,可以再Common定义一个function.php函数,当我们在控制层调用的时候直接调 ...

  5. 第二百六十七节,Tornado框架-分页封装模块

    Tornado框架-分页封装模块 框架引擎 #!/usr/bin/env python #coding:utf-8 import tornado.ioloop import tornado.web # ...

  6. 【JavaScript框架封装】实现一个类似于JQuery的缓存框架的封装

    // 缓存框架 (function (xframe) { /** * 实现了缓存框架的临时存储功能(内存存储) * @type {{data: Array, get: (function(*): *) ...

  7. 【JavaScript框架封装】实现一个类似于JQuery的动画框架的封装

    // 动画框架 (function (xframe) { // 需要参与链式访问的(必须使用prototype的方式来给对象扩充方法) xframe.extend({}); // 不需要参与链式访问的 ...

  8. ios开发瀑布流框架的封装

    一:瀑布流框架封装的实现思路:此瀑布流框架的封装仿照tableView的底层实现,1:每个cell的frame的设置都是找出每列的最大y值,比较每列的最大y值,将下一个cell放在最大y值最小的那一列 ...

  9. JS-特效 ~ 05. 缓动框架兼容封装/回掉函数/兼容透明度/层级、旋转轮播图、正则表达式、验证表单注册账号、

    缓动函数中opcity  写百分值的值 JS一般不用小数运算,会照成精度丢失 元素的默*认透明度是 层级一次性赋值,不缓动 利用for…in为同一个父元素的子元素绑定属性 缓动框架兼容封装/回掉函数/ ...

随机推荐

  1. servlet文件下载

    创建web工程servlet,新建DownloadServlet.java package com.xmyself.servlet; import java.io.File; import java. ...

  2. javascript匹配各种括号书写是否正确

    今天在codewars上做了一道题,如下 看上去就是验证三种括号各种嵌套是否正确书写,本来一头雾水,一种括号很容易判断, 但是三种怎么判断! 本人只是个前端菜鸟,,不会什么高深的正则之类的. 于是,在 ...

  3. python中IndentationError: expected an indented block错误的解决方法

    IndentationError: expected an indented block 翻译为IndentationError:预期的缩进块 解决方法:有冒号的下一行要缩进,该缩进就缩进

  4. java面向对象中的关键字

    1,super关键字 super:父类的意思 1. super.属性名 (调用父类的属性) 2. super.方法名 (调用父类的方法) 3. super([参数列表])(调用父类的构造方法) 注意: ...

  5. 【干货分享】流程DEMO-采购预算编制

    流程名: 采购预算编制  业务描述: 在月初由计财部进行预算编辑,提交审批后预算生效  流程相关文件: 流程包.xml WebService业务服务.xml WebService.asmx WebSe ...

  6. Android中的沉浸式状态栏效果

    无意间了解到沉浸式状态栏,感觉贼拉的高大上,于是就是试着去了解一下,就有了这篇文章.下面就来了解一下啥叫沉浸式状态栏.传统的手机状态栏是呈现出黑色条状的,有的和手机主界面有很明显的区别.这一样就在一定 ...

  7. 简历生成平台项目开发-STEP1问卷设计

    周五课程结束完后,小组建立QQ群和微信群,着手讨论项目问题.一开始的大概想法:就业信息平台,收集企业招聘信息和就业生资料,提供给学生和企业的校企对接平台.后来发现群里谭卓同学也有个相关的思路,经过商量 ...

  8. JavaScript 写计算器改进版

    <html><head><style> .short{height:50px;width:55px;float:left;}</style></h ...

  9. Jenkins的一个bug-同时build一个项目两次导致失败

    我们有一个job A, A只是配置了一些参数,它会去触发模板job B. 我一开始点击构建A, 马上发现参数配置不对,于是撤消了构建,但是我没有发现B已经被触发,我重新配置参数,然后再次构建A,这个时 ...

  10. CentOS7 + mono +Jexus 环境的搭建

    CentOS7的安装和配置 1,从http://www.centos.org/下载CentOS7的镜像,并在VMWare中创建该镜像的虚拟机,为方便操作,把虚拟机的网络连接设置为桥接模式:在安装过程中 ...