本篇是答应在端午写iOS网络-四篇源码解析以及封装的最后一篇,是针对上一篇YTKNetwork源码解析后的一次封装,也是自己实际项目中所使用过的。在对YTKNetwork封装的时候,还是需要对YTKNetwork源码进行了解,方便对此封装的理解,请读一下:https://www.cnblogs.com/guohai-stronger/p/9194519.html

本篇是实际工作过项目网络架构抽出来的,读完大约15-25分钟左右,Demo也会上传到github。(暂没有批量请求需求)

一、代码结构如下

1.针对YTKNetwork网络封装目录

2.项目代码结构与使用:举例购物车列表

二、准备

1.新建项目,导入AFNetworking,YTKNetwork(暂用cocoapods)。

1)通过命令行cd 新建项目地址(整个直接拖拽到终端),

2)进入项目输入vim Podfile

3)输入i,进入编辑模式

  1. platform :ios, '8.0'
  2.  
  3. target 'TestYTK' do
  4.  
  5. pod 'AFNetworking'
  6. pod 'YTKNetwork'
  7. pod 'YYModel'
  8. pod 'Toast'
  9.  
  10. end

4)然后按Esc键,并且输入“ :”号进入vim命令模式,在冒号后边输入wq

5)pod install

重新编译一下。 (最好建立一个pch文件,便于管理)

2.将代码直接拖入项目中

将标红的代码拖入项目中,编译一下!

三、代码分析

1 . IOANotificationManager(通知)

主要作用:主要是监听网络的变化。

  1. #import <Foundation/Foundation.h>
  2.  
  3. extern const NSString *kNotNetworkNotificationKey;
  4.  
  5. @interface IOANotificationManager : NSObject
  6.  
  7. // 无网络
  8. + (void)postNoNetworkNotification:(NSDictionary *)userInfo;
  9.  
  10. // 无网络
  11. + (void)addNoNetworkBoserver:(id)target selector:(SEL)selector;
  12.  
  13. + (void)removeObservers:(id)target;
  14. @end

.m实现如下:

  1. #import "IOANotificationManager.h"
  2.  
  3. const NSString *kNotNetworkNotificationKey = @"com.ioa.NoNetwork";
  4.  
  5. @implementation IOANotificationManager
  6.  
  7. + (void)postNoNetworkNotification:(NSDictionary *)userInfo {
  8. [[NSNotificationCenter defaultCenter] postNotificationName:(NSString *)kNotNetworkNotificationKey object:nil userInfo:userInfo];
  9. }
  10.  
  11. // 无网络
  12. + (void)addNoNetworkBoserver:(id)target selector:(SEL)selector {
  13. if (target) {
  14. [[NSNotificationCenter defaultCenter] addObserver:target selector:selector name:(NSString *)kNotNetworkNotificationKey object:nil];
  15. }
  16. }
  17.  
  18. + (void)removeObservers:(id)target {
  19. [[NSNotificationCenter defaultCenter] removeObserver:target];
  20. }
  21. @end

>>>拓展

其实在这里面也可以做用户登陆,退出登陆等监听操作。

2. IOARequest

主要作用:定义一些请求状态码、响应码,发起请求等

IOARequest.h

  1. #import <YTKNetwork.h>
  2. #import "IOAApiManager.h"
  3. //管理用户信息
  4. //#import "IOADataManager.h"
  5. #import "IOANotificationManager.h"
  6. #import "IOAResponse.h"
  7.  
  8. @interface IOARequest : YTKRequest
  9.  
  10. //返回接口状态码,其中:200 成功,
  11. // 600 未登录
  12. // 500 服务器错误
  13. // 501 已经存在
  14. // 502 数据接口为空
  15. // 400 请求参数有错,
  16. // 401 非法请求,
  17. // 1 没有网络
  18. // 0 服务后台问题,可使用response的statuscode查询具体问题
  19.  
  20. @property (nonatomic, readonly, assign) NSInteger serverResponseStatusCode;
  21.  
  22. //返回请求状态码,其中:1正常,0不正常
  23. @property (nonatomic, readonly, assign) NSInteger serverRequestStatusCode;
  24.  
  25. // 返回的提示信息
  26. @property (nonatomic, readonly, copy) NSString *serverResponseMessage;
  27.  
  28. // 如果没有网络 failure同步方式返回
  29. - (void)startWithCompletionBlockWithSuccess:(YTKRequestCompletionBlock)success
  30. failure:(YTKRequestCompletionBlock)failure;

通过上面发现IOARequest是继承YTKRequest,以后我们在每一个模块请求数据的时候,就继承我们自己的IOARequest。

返回接口状态码以及请求码是根据我们后台自己定义的,大家可以根据自己的实际情况进行更改。

2. IOARequest.m

部分代码:

  1. - (NSTimeInterval)requestTimeoutInterval {
  2. //请求限时
  3. return 30.0;
  4. }
  5.  
  6. - (YTKRequestMethod)requestMethod {
  7. //测试环境,使用YTKRequestMethodGET,便于与后台和测试调试问题
  8. #ifdef DEBUG
  9. return YTKRequestMethodGET;
  10. #else
  11. return YTKRequestMethodPOST;
  12. #endif
  13.  
  14. }
  15.  
  16. - (void)startWithCompletionBlockWithSuccess:(YTKRequestCompletionBlock)success
  17. failure:(YTKRequestCompletionBlock)failure {
  18. if (![IOAApiManager isNetworkReachable]) {
  19. self.serverResponseStatusCode = ; // 没网络
  20. [IOANotificationManager postNoNetworkNotification:nil];
  21. if (failure) {
  22. failure(self);
  23. }
  24. return;
  25. }
  26.  
  27. // WS(weakSelf);
  28. [self setCompletionBlockWithSuccess:success failure:^(__kindof YTKBaseRequest * _Nonnull request) {
  29. if (failure) {
  30. failure(request);
  31. // return;
  32. }
  33.  
  34. }];
  35.  
  36. //发起请求
  37. [self start];
  38. }
  39.  
  40. - (BOOL)statusCodeValidator {
  41. //判断响应状态码
  42. BOOL isOk = [super statusCodeValidator];
  43. if (!isOk) {
  44. #if DEBUG
  45. [self testAlertInfo:@"网络请求错误"];
  46. #endif
  47. return isOk;
  48. }
  49.  
  50. if (!self.responseObject) {
  51. self.serverResponseStatusCode = ;
  52. return NO;
  53. }
  54.  
  55. self.serverResponseStatusCode = [self.responseObject[@"ret"] integerValue];
  56. self.serverRequestStatusCode = [self.responseObject[@"code"] integerValue];
  57. self.serverResponseMessage = self.responseObject[@"msg"];
  58.  
  59. if (self.serverResponseStatusCode == ) {
  60. return YES;
  61. }
  62. else if (self.serverResponseStatusCode > && self.serverResponseStatusCode < ) {
  63. [IOAApiManager saveToken:nil];
  64.  
  65. //移除用户个人信息
  66. // [IOADataManager removeUserInfo];
  67.  
  68. return NO;
  69. }
  70.  
  71. return NO;
  72. }

3.IOAUploadRequest

主要负责:图片的上传和下载(我们项目上传图片,后台返回是一个对象,对象包括如下)。

  1. #import "IOARequest.h"
  2.  
  3. // 上传图片返回的模型
  4. @interface IOAUploadResponseModel : NSObject
  5.  
  6. @property (nonatomic, copy) NSString *url;
  7.  
  8. @property (nonatomic, copy) NSString *file;
  9.  
  10. @property (nonatomic, copy) NSString *file_name;
  11.  
  12. @end
  13.  
  14. //可以直接IOARequest,不需要继承YTKRequest
  15. @interface IOAUploadRequest : IOARequest
  16. @property (nonatomic, strong) UIImage *image;
  17.  
  18. //获取上传进度
  19. @property(nonatomic, copy) void(^uploadProgressBlock)(IOAUploadRequest *currentApi, NSProgress * progress);
  20. @end

在.m里面以文件上传方式上传

  1. #define WS(weakSelf) __weak __typeof(&*self)weakSelf = self
  2.  
  3. @implementation IOAUploadResponseModel
  4.  
  5. @end
  6.  
  7. @implementation IOAUploadRequest
  8. - (YTKRequestMethod)requestMethod {
  9. return YTKRequestMethodPOST;
  10. }
  11.  
  12. //设置上传图片 所需要的 HTTP HEADER
  13. - (AFConstructingBlock)constructingBodyBlock {
  14. UIImage *image = self.image;
  15. return ^(id<AFMultipartFormData> formData) {
  16. NSData *data = UIImagePNGRepresentation(image);
  17. NSString *name = @"file";
  18. NSString *fileName = @"upload";
  19. NSString *type = @"image/png";
  20. [formData appendPartWithFileData:data name:name fileName:fileName mimeType:type];
  21. };
  22. }
  23. #pragma mark 上传进度
  24. - (AFURLSessionTaskProgressBlock) resumableUploadProgressBlock {
  25. WS(weakSelf);
  26. AFURLSessionTaskProgressBlock block = ^void(NSProgress * progress){
  27. if (_uploadProgressBlock) {
  28. _uploadProgressBlock(weakSelf, progress);
  29. }
  30. };
  31. return block;
  32. }
  33. @end

4.IOANetworkManager

主要负责网络状态的管理,监听。

5.IOAResponse

主要负责后台返回状态码管理,包括:是否有网络,token是否失效,服务器错误以及参数错误等。

IOAResponse.h

  1. typedef NS_ENUM(NSInteger, ResponseStatusType) {
  2. kResponseStatusTypeRequestError = , // 服务后台问题
  3. kResponseStatusTypeNoNetwork = , // 没有网络
  4. kResponseStatusTypeSuccess = ,
  5. kResponseStatusTypeExpiryToken = ,
  6. kResponseStatusTypeServerServiceError = ,
  7. // kResponseStatustypeServiceExist = 501,
  8. kResponseStatusTypeDataNull = ,
  9. kResponseStatusTypeNotLogin = ,
  10. };
  1. @property (nonatomic, assign) BOOL success;
  2. //返回接口状态码,其中:200 成功,
  3. // 600 未登录
  4. // 500 服务器错误
  5. // 501 已经存在
  6. // 502 数据接口为空
  7. // 400 请求参数有错,
  8. // 401 非法请求,
  9. // 1 没有网络
  10. // 0 服务后台问题,可使用response的statuscode查询具体问题
  11. @property (nonatomic, assign) ResponseStatusType responseStatusType;
  12. @property (nonatomic, assign) NSInteger serverResponseStatusCode; // 服务端返回的status code
  13. @property (nonatomic, assign) NSInteger requestResponseStatusCode; // 请求返回的status code
  14.  
  15. @property (nonatomic, strong) id responseObject;
  16.  
  17. @property (nonatomic, copy) NSString *responseMessage;
  18.  
  19. + (IOAResponse *)responseWithRequest:(IOARequest *)request;
  20.  
  21. - (void)updateStatusCodesWithRequest:(IOARequest *)request;
  22.  
  23. // 是否需要提示
  24. - (BOOL)alertOrNot;
  25. // 是否没有有网络
  26. - (BOOL)isNoNetwork;
  27.  
  28. // 是否token失效
  29. - (BOOL)isExpiryToken;
  30.  
  31. // 服务器错误
  32. - (BOOL)isRequestServerError;
  33.  
  34. // 后台服务错误
  35. - (BOOL)isServerServiceError;

IOAResponse.m是其赋值,查看demo即可。

6.IOAApiManager

主要任务:负责是管理Api,开发环境,证书,接口参数,token等。

IOAApiManager.h

  1. + (void)configNetwork;
  2. //+ (NSString *)getService;
  3. //+ (NSString *)getToken;
  4. + (NSMutableDictionary *)getCommomParametersWith:(NSString *)service token:(NSString *)token;
  5. + (NSMutableDictionary *)getParametersWithService:(NSString *)service;
  6.  
  7. + (void)startNetworkMonitoring;
  8. + (void)stopNetworkMonitoring;
  9. + (BOOL)isNetworkReachable;
  10. + (AFNetworkReachabilityStatus)getNetworkStatus;
  11.  
  12. + (void)saveToken:(NSString *)token;
  13. + (NSString *)getToken;

在IOAApiManager.m

  1. typedef NS_ENUM(NSUInteger, ServerType) {
  2. kSeverTypeDev, // 开发服务器地址
  3. kSeverTypeTest, //测试服务器地址
  4. kSeverTypeRelease //发布版服务器地址
  5. };
  6.  
  7. @implementation IOAApiManager
  8.  
  9. + (void)configNetwork {
  10. YTKNetworkAgent *agent = [YTKNetworkAgent sharedAgent];
  11. [agent setValue:[NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html",@"text/plain",@"application/x-www-form-urlencodem", nil] forKeyPath:@"_manager.responseSerializer.acceptableContentTypes"];
  12.  
  13. static ServerType serverType = kSeverTypeRelease;
  14.  
  15. #if DEBUG
  16. serverType = kSeverTypeDev;
  17. #else
  18. serverType = kSeverTypeRelease;
  19. #endif
  20.  
  21. YTKNetworkConfig *config = [YTKNetworkConfig sharedConfig];
  22. switch (serverType) {
  23. case kSeverTypeDev: // 开发服务器地址
  24. //改成自己的
  25. config.baseUrl = @"http://www.baidu.com";
  26. break;
  27. case kSeverTypeTest: // 测试服务器地址
  28. config.baseUrl = @"https://www.baidu.com";
  29. break;
  30. case kSeverTypeRelease: // 发布版服务器地址
  31. config.baseUrl = @"https://www.baidu.com";
  32. break;
  33. default:
  34. break;
  35. }
  36.  
  37. [self configHttps];
  38. }
  39.  
  40. + (void)configHttps {
  41.  
  42. // 获取证书
  43. NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"ssl_content" ofType:@"pem"];//证书的路径
  44. NSData *certData = [NSData dataWithContentsOfFile:cerPath];
  45.  
  46. // 配置安全模式
  47. YTKNetworkConfig *config = [YTKNetworkConfig sharedConfig];
  48. // config.cdnUrl = @"";
  49.  
  50. // 验证公钥和证书的其他信息
  51. AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
  52.  
  53. // 允许自建证书
  54. securityPolicy.allowInvalidCertificates = YES;
  55.  
  56. // 校验域名信息
  57. securityPolicy.validatesDomainName = YES;
  58.  
  59. // 添加服务器证书,单向验证; 可采用双证书 双向验证;
  60. securityPolicy.pinnedCertificates = [NSSet setWithObject:certData];
  61.  
  62. [config setSecurityPolicy:securityPolicy];
  63. }

上面的域名要改成自己的域名,上面是以baidu为准啦!!!

四、实际使用

1. 这个项目是以MVVM模式进行搭建。

在Api文件夹写接口参数

在viewModel里面写接口的请求以及解析

在Datas里面放的是plist文件等。

这样便于根据不同功能进行管理

2.Api文件夹

Api.h

Api.m,利用YYModel进行将声明的model转为字典,作为参数

3.ViewModel

ViewModel.h声明方法,请求方法

在ViewModel.m实现其方法

4.最后在控制器里面调用请求方法

4.1、导入ViewModel所在的类名

4.2、声明属性并懒加载

4.3、控制器调用请求方法

上面就是YTKNetwork的封装使用了,demo里面只有封装的代码,使用必须要真实的接口,(假数据没有必要)。如果有需要对YTKNetwork进行二次封装,可以下载github,然后按照这个使用方法就可以进行网络请求和封装啦。

demo地址:https://github.com/zxy1829760/YTKNetwork-

到现在为止,四天关于网络请求的内容四篇博客就大致说完了,欢迎大家指正!!!

YTKNetwork网络封装的更多相关文章

  1. boost asio 学习(九) boost::asio 网络封装

    http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting- started-with-boostasio?pg=10 9. A ...

  2. [从源码学设计]蚂蚁金服SOFARegistry之网络封装和操作

    [从源码学设计]蚂蚁金服SOFARegistry之网络封装和操作 目录 [从源码学设计]蚂蚁金服SOFARegistry之网络封装和操作 0x00 摘要 0x01 业务领域 1.1 SOFARegis ...

  3. 基于AFNetworking3.0网络封装

    概述 对于开发人员来说,学习网络层知识是必备的,任何一款App的开发,都需要到网络请求接口.很多朋友都还在使用原生的NSURLConnection一行一行地写,代码到处是,这样维护起来更困难了. 对于 ...

  4. iOS_SN_基于AFNetworking3.0网络封装

    转发文章,原地址:http://www.henishuo.com/base-on-afnetworking3-0-wrapper/?utm_source=tuicool&utm_medium= ...

  5. 微信小程序网络封装-简单高效

    废话引言 小程序虽然出世很久了,但一直没怎么接触到小程序开发.吉他兴趣班老师想弄一个小程序发布课程信息和打卡功能,作为IT一员就自愿加入了这个小程序开发小组中.虽然小程序面向的是前端工程师,但作为移动 ...

  6. Swift网络封装库Moya中文手册之Endpoints

    Endpoints Endpoint是一种半私有的数据结构,Moya用来解释网络请求的根本构成.一个endpoint储存了以下数据: The URL. The HTTP method (GET,POS ...

  7. axios网络封装模块

    功能特点 在浏览器中发送XMLHttpRequests请求 在node.js总发送http请求 支持Promise API 拦截请求和相应 转换请求和响应数据 axios请求方式 支持多种请求方式 a ...

  8. RxHttp - 轻量级、可扩展、易使用、完美兼容MVVM、MVC架构的网络封装类库

    前言 RxHttp是基于RxJava2+Retrofit 2.9.0+OkHttp 4.9.0实现的轻量级,完美兼容MVVM架构的网络请求封装类库,小巧精致,简单易用,轻轻松松搞定网络请求. GitH ...

  9. Swift网络封装库Moya中文手册之Authentication

    Authentication 安全验证可能有点复杂,一些网络请求需要认证,这里我们讨论两种常见的. Basic HTTP Auth HTTP auth是HTTP协议自带的用户名/密码验证.如果你使用的 ...

随机推荐

  1. windows和ubuntu下git commit提交后如何保存和退出,回到命令行

    问题一: windows下git commit后会进入vim界面,不知道怎么操作 解决办法: 1.输入小写字母i,此时进入编辑模式,可以输入你想输入的内容 2.按下esc键,此时退出编辑模式,输入英文 ...

  2. POJ - 3984 迷宫问题 bfs解法

    #include<stdio.h> #include<string.h> #include<algorithm> #include<stack> usi ...

  3. Leetcode35 Search Insert Position 解题思路(python)

    本人编程小白,如果有写的不对.或者能更完善的地方请个位批评指正! 这个是leetcode的第35题,这道题的tag是数组,python里面叫list,需要用到二分搜索法 35. Search Inse ...

  4. Js实现继承的方法

    原型的作用:1.将公共部分放入原型中,这样构造出的多个实例对象的公共部分只会占用一个公共空间,实现数据共享和节省内存空间 2.通过原型实现继承:构造函数模拟 "类"这个面向对象的概 ...

  5. Android中RecyclerView出现java.lang.IndexOutOfBoundsException

    在RecyclerView更细数据时出现java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder ...

  6. 产生 unmerge path git

    1. Pull is not possible because you have unmerged files. 症状:pull的时候 $ git pull Pull is not possible ...

  7. FFmpeg命令行工具学习(二):播放媒体文件的工具ffplay

    一.简述 ffplay是以FFmpeg框架为基础,外加渲染音视频的库libSDL构建的媒体文件播放器. 在使用ffplay之前必须要安装到系统中,MAC的安装教程为:http://www.cnblog ...

  8. .net的服务转移

    问题: 服务器换新,但是本来服务器部署了一些window服务,需要迁移过来 解决过程: 百度了估计几百页了,之前因为老机器挂了,写这个代码布服务的人也早就不在了,所以自己闷头苦找,一个java初级程序 ...

  9. ImportError: No module named '_tkinter', please install the python3-tk package

    ImportError: No module named '_tkinter', please install the python3-tk package 先更新包,命令:sudo apt-get ...

  10. C++11实现一个轻量级的AOP框架

    AOP介绍 AOP(Aspect-Oriented Programming,面向方面编程),可以解决面向对象编程中的一些问题,是OOP的一种有益补充.面向对象编程中的继承是一种从上而下的关系,不适合定 ...