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. EntityFramework Core Raw SQL

    前言 本节我们来讲讲EF Core中的原始查询,目前在项目中对于简单的查询直接通过EF就可以解决,但是涉及到多表查询时为了一步到位就采用了原始查询的方式进行.下面我们一起来看看. EntityFram ...

  2. 火焰图分析openresty性能瓶颈

    注:本文操作基于CentOS 系统 准备工作 用wget从https://sourceware.org/systemtap/ftp/releases/下载最新版的systemtap.tar.gz压缩包 ...

  3. bootstrap + requireJS+ director+ knockout + web API = 一个时髦的单页程序

    也许单页程序(Single Page Application)并不是什么时髦的玩意,像Gmail在很早之前就已经在使用这种模式.通常的说法是它通过避免页面刷新大大提高了网站的响应性,像操作桌面应用程序 ...

  4. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

  5. 菜鸟学Struts2——零配置(Convention )

    又是周末,继续Struts2的学习,之前学习了,Struts的原理,Actions以及Results,今天对对Struts的Convention Plugin进行学习,如下图: Struts Conv ...

  6. 【初学python】使用python调用monkey测试

    目前公司主要开发安卓平台的APP,平时测试经常需要使用monkey测试,所以尝试了下用python调用monkey,代码如下: import os apk = {'j': 'com.***.test1 ...

  7. ASP.NET Core的路由[3]:Router的创建者——RouteBuilder

    在<注册URL模式与HttpHandler的映射关系>演示的实例中,我们总是利用一个RouteBuilder对象来为RouterMiddleware中间件创建所需的Router对象,接下来 ...

  8. JDK动态代理

    一.基本概念 1.什么是代理? 在阐述JDK动态代理之前,我们很有必要先来弄明白代理的概念.代理这个词本身并不是计算机专用术语,它是生活中一个常用的概念.这里引用维基百科上的一句话对代理进行定义: A ...

  9. nginx服务器安装及配置文件详解

    nginx在工作中已经有好几个环境在使用了,每次都是重新去网上扒博客,各种编译配置,今天自己也整理一份安装文档和nginx.conf配置选项的说明,留作以后参考.像负载均衡配置(包括健康检查).缓存( ...

  10. win10系统下连接无线网络掉线问题解决办法

    打开驱动精灵----系统诊断 找一个可修复的驱动点击 选择连不上网中的查看更多 有连不上网络,网络连接受限,解决无线间歇性掉网问题 进入计算机管理----设备管理 修改无线网络属性(名称含有wirel ...