OC和Swift的AFN网络封装

一、cocopos的使用
创建项目之后,关闭项目,打开终端,cd 空格 ,把项目所在的文件夹给拖进来, 回车
pod init
然后把项目中生成的那个podfile 项目拖到xcode ,打开 修改  pod 'AFNetworking'
cmt+S 保存关闭
在终端输入:
pod install --no-repo-update


二、 AFN 网络 封装

在应用程序开发中,一定要封装隔离网络框架

封装AFN的Get请求.

应用程序在做网络请求的时候不会直接调用到第三方的框架,直接访问在网络工具里面创建的网络请求方法

在网络工具类里面创建网络请求方法

报错:
status code: 200    ………….   unacceptable content-type: text/html
内容格式不支持,把数据进行反序列化格式
这是一个使用AFN时最常见的错误,



OC 封装网络工具

  • 新建网络工具类 NetworkTools
  • 实现单例

+( instancetype )shareTools{
   
static NetTools *tools;
   
   
static dispatch_once_t onceToken;
   
dispatch_once (&onceToken, ^{
       
       
// 注意:末尾要包含 “/”
       
NSURL *baseURL =[ NSURL URLWithString : @"http://www.weather.com.cn/" ];
       
        tools =[[
self alloc ] initWithBaseURL :baseURL]; //BaseURL ,指定一个参照的地址,以后只使用参照地址就可以
       
        // 设置反序列化格式。
// 因为报错:
//        status code: 200    ………….   unacceptable content-type: text/html
//        内容格式不支持
        // 直接粘过来: self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", nil];
        tools. responseSerializer . acceptableContentTypes = [ NSSet setWithObjects : @"application/json" , @"text/json" , @"text/javascript" , @"text/html" , nil ];
       
    });
   
   
return tools;

}

  • 建立网络请求方法

// 创建网络请求方法
// 网络请求时,把请求结果返回给调用方。使用 block,异步执行完成把结果返回给调用方
-( void )request:( NSString *)URLString parameters:( id )parameters finished:( void (^)( id result, NSError *error))finished{
    [
self GET :URLString parameters :parameters success :^( NSURLSessionDataTask * _Nonnull task, id   _Nullable responseObject) {
       
        finished(responseObject,
nil );
    }
failure :^( NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
       
NSLog ( @"%@" ,error);
        finished(
nil ,error);
    }];
}

  • 在调用方里面测试网络请求
[[ NetTools shareTools ] request : @"data/sk/101010100.html" parameters : nil finished :^( id result, NSError *error) {
       
if (error != nil ) {
           
NSLog ( @" 出错了 " );
           
return ;
        }
       
NSLog ( @"%@" ,result);
    }];


  • 定义一个HTTP请求类型的枚举类型
// 定义一个网络请求类型的枚举
typedef enum :NSUInteger {
    GET,
    POST,
}YSHRequestMethod;

// 让他既支持 get 请求,又支持 post 请求,所以定义一个结构体类型   扩展这个方法的参数,加一个参数(是判断请求方法的)
-(void)request:(YSHRequestMethod)method URLString:(NSString *)URLString parameters:(id)parameters finished:(void(^)(id result, NSError *error))finished;

 //AFN的网络请求方法,除了单词其他参数都一样的
-------------------------------------------------------------------------
[[ NetTools shareTools ] request : POST URLString : @"post" parameters : @{ @"name" : @"zhangsan" , @"age" : @18} finished :^( id result, NSError *error) {
       
if (error != nil ) {
           
NSLog ( @" 出错了 " );
           
return ;
        }
       
NSLog ( @"%@" ,result);
    }];


  • 由于get和post的网络请求方法,基本一致,所以封装代码


//AFN 的网络请求方法,除了单词其他参数都一样的
   
   
// 判断传过来的请求方式
   
NSString *methodName = (method == GET ) ? @"GET" : @"POST" ;
   
   
//点进去看发现GETPOST等都有一个相同的方法,所以使用,但是智能提示不出来,所以。。。
    //dataTaskWithHTTPMethod 本类没有实现方法,但是父类实现了
    // 在调用方法的时候,如果本类没有提供,直接调用父类的方法, AFN 内部已经实现这个方法!
//需要补全方法中的参数。
    [[ self dataTaskWithHTTPMethod :methodName URLString :URLString parameters :parameters success :^( NSURLSessionDataTask *task, id responseObject) {
        finished(responseObject,
nil );
    }
failure :^( NSURLSessionDataTask *task, NSError *error) {
       
NSLog ( @"%@" ,error);
        finished(
nil ,error);
    }] resume];


  • 从 AFHTTPSessionManager.m 中复制 dataTaskWithHTTPMethod 函数定义

因为那个方法是私有的方法,不能直接调用这个内部方法

在使用的地方,定义一个协议,把方法给粘过来

OC 没有任何的严谨性

我们通过协议把他的一个内部的私有的方法的定义给拿出来,然后操作这个原本私有的方法。可以直接使用这个私有的方法了。

调用私有的 API ,但不能调用苹果的私有API,否则不能上架。

/// 网络工具协议
@protocol NetworkToolsProxy < NSObject >

/// 网络请求方法
///
/// @param method     HTTP 请求方法
/// @param URLString  URLString
/// @param parameters 参数字典
/// @param success    成功回调
/// @param failure    失败回调
///
/// @return NSURLSessionDataTask

@optional // 可以不实现,因为我们是利用继承的特点,调用了父类的方法
- (
NSURLSessionDataTask *)dataTaskWithHTTPMethod:( NSString *)method
                                       URLString:(
NSString *)URLString
                                      parameters:(
id )parameters
                                         success:(
void (^)( NSURLSessionDataTask *, id ))success
                                         failure:(
void (^)( NSURLSessionDataTask *, NSError *))failure;

@end

///协议是让人遵守的,遵守协议
/// 遵守网络协议 - 为了能够欺骗 Xcode 给一个智能提示,以及编译通过!
@interface NetTools ()< NetworkToolsProxy >

@end


Swift 封装网络工具

  • 新建网络工具类 NetworkTools
  • 实现单例
// MARK: 网络工具
class NetworkTools: AFHTTPSessionManager {

   
//1. 设置网络工具单例 & 响应格式设置方法
    static let sharedTools: NetworkTools = {
       
let tools = NetworkTools (baseURL: nil )
       
       
// 设置反序列化数据格式 - 系统会自动将 OC 框架中的 NSSet 转换成 Set
        tools. responseSerializer . acceptableContentTypes ?. insert ( "text/html" )
       
return tools
    }()
}

  • 定义网络请求方法枚举
// 定义 HTTP 请求方法枚举
enum YSHRequestMethod: String {
   
case GET = "GET"
   
case POSE = "POSE"
}


  • 创建网络请求方法
// MARK: - 封装 AFN 网络方法
extension NetworkTools {
   
   
/// 网络请求
    ///
    /// - parameter method:     GET / POST
    /// - parameter URLString:  URLString
    /// - parameter parameters: 参数字典
    /// - parameter finished:   完成回调
    func requedt(method: YSHRequestMethod ,URLString: String ,parameters:[ String : AnyObject ]?,finsished: (result: AnyObject ?,error: NSError ?) ->() ){
       
       
       
if method == YSHRequestMethod . GET {
           
// 不需要用下划线替掉
            GET (URLString, parameters: parameters, success: { ( _ , result) -> Void in
                finsished(result: result, error:
nil )
                }, failure: { (
_ , error) -> Void in
                   
print (error)
                    finsished(result:
nil , error: error)
            })
        }
       
else {
           
POST (URLString, parameters: parameters, success: { ( _ , result) -> Void in
               
               
// 在开发网络应用的时候,错误不要提示给用户,但是错误一定要输出!
                finsished(result: result, error: nil )
               
                }, failure: { (
_ , error) -> Void in
                   
                    finsished(result:
nil , error: error)
            })
        }
    }
}

  • AFN 内部网络方法封装
//闭包是可以提前准备好的代码,在需要的时候调用执行,可以当做参数传递
       
       
// 定义成功回调的闭包
        // 想要把 success 传递到下面,则这个闭包的参数格式,必须和下面调用的地方的闭包的参数格式是一致的,可以直接粘贴 GET 调用的地方的闭包的代码。
       
       
let success = {
            (task:
NSURLSessionDataTask ,result: AnyObject ?) -> Void in
            finsished(result: result, error:
nil )
        }
       
       
// 定义失败回调的闭包
        let failure = { (task: NSURLSessionDataTask ?,error: NSError ) -> Void in
           
// 在开发网络应用的时候,错误不要提示给用户,但是错误一定要输出!
            print (error)
            finsished(result:
nil , error: error)
        }

       
       
// 优化封装
        if method == YSHRequestMethod . GET {
           
GET (URLString, parameters: parameters, success: success, failure: failure)
        }
       
else {
           
POST (URLString, parameters: parameters, success: success, failure: failure)
        }


  • 测试 POST 请求

NetworkTools .sharedTools. requedt ( YSHRequestMethod . POSE , URLString: "http://httpbin.org/post" , parameters: [ "name" : "wanglaowu" ]) { (result, error) -> () in
           
print (result)
        }


小结

  • 使用 typealias 可以统一和简化闭包的定义和传递
  • 使用 baseURL 能够简化网络访问方法中 URL 的传递
  • AFN 访问方法最常见的错误
    • status code == 200,但是提示 unacceptable content-type,表示网络访问正常,但是无法对返回数据做反序列化
    • 解决办法:增加 反序列化数据 格式
  • 另外一个常见错误
    • status code == 405,不支持的网络请求方法,检查 GET / POST 是否写错
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值