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. Swift3.0服务端开发(一) 完整示例概述及Perfect环境搭建与配置(服务端+iOS端)

    本篇博客算是一个开头,接下来会持续更新使用Swift3.0开发服务端相关的博客.当然,我们使用目前使用Swift开发服务端较为成熟的框架Perfect来实现.Perfect框架是加拿大一个创业团队开发 ...

  2. 如何进行python性能分析?

    在分析python代码性能瓶颈,但又不想修改源代码的时候,ipython shell以及第三方库提供了很多扩展工具,可以不用在代码里面加上统计性能的装饰器,也能很方便直观的分析代码性能.下面以我自己实 ...

  3. 转:聊聊mavenCenter和JCenter

    Gradle支持从maven中央仓库和JCenter上获取构件,那这两者有什么区别呢? maven中央仓库(http://repo1.maven.org/maven2/)是由Sonatype公司提供的 ...

  4. tomcat开发远程调试端口以及利用eclipse进行远程调试

    一.tomcat开发远程调试端口 方法1 WIN系统 在catalina.bat里:  SET CATALINA_OPTS=-server -Xdebug -Xnoagent -Djava.compi ...

  5. 苹果强制使用HTTPS传输了怎么办?——关于HTTPS,APP开发者必须知道的事

    WeTest 导读 2017年1月1日起,苹果公司将强制使用HTTPS协议传输.本文通过对HTTPS基础原理和通信过程内容的讲解,介绍APP开发者在这个背景下的应对办法. 几周前,我们在<htt ...

  6. 初学seaJs模块化开发,利用grunt打包,减少http请求

    原文地址:初学seaJs模块化开发,利用grunt打包,减少http请求 未压缩合并的演示地址:demo2 学习seaJs的模块化开发,适合对seajs基础有所了解的同学看,目录结构 js — —di ...

  7. 免费道路 bzoj 3624

    免费道路(1s 128MB)roads [输入样例] 5 7 21 3 04 5 13 2 05 3 14 3 01 2 14 2 1 [输出样例] 3 2 04 3 05 3 11 2 1 题解: ...

  8. 小程序用户反馈 - HotApp小程序统计仿微信聊天用户反馈组件,开源

    用户反馈是小程序开发必要的一个功能,但是和自己核心业务没关系,主要是产品运营方便收集用户的对产品的反馈.HotApp推出了用户反馈的组件,方便大家直接集成使用 源码下载地址: https://gith ...

  9. 用Swagger生成接口文档

    Swagger简介 在系统设计的时候,各个应用之间往往是通过接口进行交互的.因此接口的定义在整个团队中就变得尤为重要.我们可以把接口的规范用接口描述语言进行描述,然后Swagger可以根据我们定义的接 ...

  10. Atitit.软件开发的三层结构isv金字塔模型

    Atitit.软件开发的三层结构isv金字塔模型 第一层,Implements 层,着重与功能的实现.. 第二次,spec层,理论层,设计规范,接口,等.流程.方法论 顶层,val层,价值观层,原则, ...