AFN和MBProgressHUD组合封装
从事ios开发也有一段时间了,早就有开通博客的想法,但因总感觉没啥有技术含量的ideas,一再拖延。秉着丑媳妇也得见公婆的观念,趁着2015年的最后一天开通微博,于新年第一天正式开启偶的博客之路,欢迎各位拍砖指正,共同进步。
app开发时网络请求很常见,但是网络不可控。在网络数据未返回之前有必要给用户点提示,告诉用户app仍在工作中而不要让其傻等,我所认知的网络状态提示方法如下:
1、所有控制器继承自一个基类,在基类中创建一个遮住整个视图的蒙版,蒙版上添加一个转圈控件,头文件暴露一个show和一个hidden方法供子类网络请求时调用。
2、直接使用三方框架MBProgressHUD或SVProgressHUD,每次网络请求时创建一个HUD添加到视图,网络请求完毕则销毁。
在公司项目开发中,这两种方法用着总是感觉有点淡淡地忧伤,网络很好时每当进入一个界面总会出现一闪而过的HUD,个人感觉很是老火,也影响用户体验,于是希望有一种方式能在网络状况优良时不弹出提示框,网络差时才让其出现。
早些日子详细看了下MBProgressHUD源码发现其中就自带这个小功能,于是将其与AFN框架一起封装在一块,经过公司项目验证,工作正常,现在对其进行简单分析:
在网络工具类NetworkTool.h中定义了一个枚举,能选择网络提示框出现的合适时机,举个例子,若网络数据在0.7s之后返回,则依次选择如下枚举的实现效果是:0.5秒后出现HUD共计0.2s、不出现HUD、0.1s后出现HUD共计0.6s、不出现HUD、出现HUD共计0.7s
网络提示框出现时机枚举
主要实现方法如下:
方法实现很大众,通俗易懂,这里需要稍微介绍下的是其中的两个子方法。
1、网络请求操作管理器manager的创建:
AFN中默认的请求序列化器是HTTP类型,默认设置了请求头Content-Type为application/x-www-form-urlencoded。JSON类型时默认设置请求头Content-Type为application/json。
就我自己公司而言,当服务器要求设置请求头Content-Type为application/x-www-form-urlencoded,可知请求序列化器为HTTP类型, Content-Type为application/json时请求序列化器为JSON类型。
响应序列化器默认为JSON类型,一般公司都是这种,但当访问网页等时有时需要设置响应序列化器为HTTP类型,如示例程序。
2、转圈控件HUD的创建:
先是根据枚举设置graceTime时间,再是创建一个hud添加到窗口上,很简单。这里必须要设置属性taskInProgress为YES,并且在网络请求成功或失败后设置为NO,graceTime属性的设置才会生效,具体后面分析。
需要注意,下面方法并不是马上将hud显示到窗口之上,具体后面分析。
下面把目光集中到hud的创建方法上,
我公司一个中小型项目,目前的网络请求有近两百个,每次请求都创建一个HUD再销毁显然没这个必要,运用动态绑定技术将hud和该类绑定,在程序运行过程中当且创建一个hud,避免频繁创建\销毁对象。
现在分析graceTime和taskInProgress组合实现延迟加载HUD原理。从方法[hud show:YES]入手。点进MBProgressHUD框架查看到该方法实现:
意思就是假若设置了graceTime,则开启定时器,在graceTime的时间之后再调用方法handleGraceTimer:方法,如下
此时若taskInProgress属性仍旧为YES才画出HUD显示到窗口上,否则不显示。很明显,若此时网络请求已经返回,则taskInProgress属性已经被设置为NO,再来到此方法时HUD不会显示,反之才会显示。
最后,工具中还提供了一个判断是否有网的方法,+ (BOOL)hasNetworkReachability,可以将其添加到每个网络请求发起之前,若存在网络才发起请求,否则提示没有网络。
最近看到一个话觉得很有意思,貌似是位大神的座右铭,拿来主义直接用下:
Talk is cheap, Show me the code.
github代码地址:https://github.com/zhangmaliang/SimpleNetwork