zoukankan      html  css  js  c++  java
  • AFNetworking自我总结

    AFNetworking

    简介

    • 目前国内开发网络应用使用最多的第三方框架
    • 是专为 Mac OS & iOS 设计的一套网络框架
    • 对 NSURLConnection 和 NSURLSession 做了封装
    • 提供有丰富的 API
    • 提供了完善的错误解决方案
    • 使用简单

    官网地址

    https://github.com/AFNetworking/AFNetworking

    学习第三方框架的步骤

    1. 获取框架
       $ git clone https://github.com/AFNetworking/AFNetworking.git
       # 更新框架
       $ git pull
      
    2. 查看官方文档
    3. 运行演示程序
    4. 建立学习分支
      • 分支是学习第三方框架和入手公司项目的重要手段!
    5. 编写测试程序
    6. 少百度,如果实在困难,可以谷歌

    数据格式

    请求的数据格式

    • AFURLRequestSerialization
    类型说明
    AFHTTPRequestSerializer 二进制的,默认的
    AFJSONRequestSerializer JSON(POST JSON) RESTful 设计风格需要
    AFPropertyListRequestSerializer PList(POST Plist-开发中几乎不用)

    响应数据格式

    • AFURLResponseSerialization
    类型说明
    AFHTTPResponseSerializer HTTP 二进制的
    AFJSONResponseSerializer JSON 默认的
    AFXMLParserResponseSerializer XML Parser 解析器 SAX 解析
    AFXMLDocumentResponseSerializer (Mac OS X) XML DOM
    AFPropertyListResponseSerializer PList 几乎不用
    AFImageResponseSerializer 图像,不支持 GIF
    AFCompoundResponseSerializer 组合的

    数据格式小结

    • 大多情况下,都是 JSON,不需要指定
    • XML 格式

      • 如果 SAX 解析,需要指定格式
        mgr.responseSerializer = [AFXMLParserResponseSerializer serializer];
        
      • 然后利用代理方法解析

      • 如果 DOM 解析,需要指定格式

        mgr.responseSerializer = [AFHTTPResponseSerializer serializer];
        
      • 然后利用第三方框架解析
    • 图像

      • AFN 支持图像缓存,也有对应的分类方法和 SDWebImage 非常像!
      • 但是:不支持 GIF

    提示

    • 使用 AFN 时,一定记住输出:error
    • 如果 state code == 200,就是数据格式错误,针对具体格式进行设置即可

    补充

    以下连接是移动开发中,常见的 XML 数据格式

    http://flash.weather.com.cn/wmaps/xml/china.xml

    官方演示程序

    AppDelegate

    设置缓存

    NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil];
    [NSURLCache setSharedURLCache:URLCache];
    

    设置网络访问标示

    [[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
    

    AFAppDotNetAPIClient

    • 提供全局网络访问入口

    • .h

    @interface AFAppDotNetAPIClient : AFHTTPSessionManager
    
    + (instancetype)sharedClient;
    
    @end
    
    • .m
    static NSString * const AFAppDotNetAPIBaseURLString = @"https://api.app.net/";
    
    @implementation AFAppDotNetAPIClient
    
    + (instancetype)sharedClient {
        static AFAppDotNetAPIClient *_sharedClient = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _sharedClient = [[AFAppDotNetAPIClient alloc] initWithBaseURL:[NSURL URLWithString:AFAppDotNetAPIBaseURLString]];
            _sharedClient.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
        });
    
        return _sharedClient;
    }
    
    @end
    

    小结

    1. 在 AppDelegate 中设置缓存
    2. 在 AppDelegate 中设置网络访问指示器
    3. 继承 AFHTTPSessionManager 创建单例统一管理网络访问
    4. 单例方法中使用了 BaseURL,设置后,再访问该服务器,可以直接使用相对路径

    代码演练

    常规代码演练

    - (void)postLogin {
        AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
    
        NSDictionary *params = @{@"username": @"张三&李四", @"password": @"123"};
    
        [mgr POST:@"http://localhost/login.php" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
            NSLog(@"POST Login %@", responseObject);
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"%@", error);
        }];
    }
    
    - (void)getLogin2 {
        AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
    
        NSDictionary *params = @{@"username": @"张三&李四", @"password": @"123"};
    
        [mgr GET:@"http://localhost/login.php" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
            NSLog(@"GET Login %@", responseObject);
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"%@", error);
        }];
    }
    
    - (void)getLogin1 {
    
        AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
    
        [mgr GET:@"http://localhost/login.php?username=zhangsan&password=123" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
            NSLog(@"%@", responseObject);
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"%@", error);
        }];
    }
    
    - (void)getDemo {
    
        AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
    
        [mgr GET:@"http://localhost/demo.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
            NSLog(@"%@ %@ %@", responseObject, [responseObject class], [NSThread currentThread]);
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"%@", error);
        }];
    }
    

    演练小结

    • 程序员不需要知道 URL,直接使用 URL 字符串
    • 自动实现 JSON 的反序列化
    • 网络访问完成的回调,是在主线程,程序员不需要考虑线程间通讯
    • URL 的参数可以使用 `字典的形式拼接,程序员不在需要考虑url` 的格式
    • 程序员不需要考虑百分号转义
      • OC中的百分号转义是有缺陷的,特殊字符例如&+= 用OC的百分号转义就不好使了,这时候需要用到AFN中提供的方法
    • 程序员不需要知道 HTTP 方法,只需要挑选单词即可!

    XML 解析

    SAX 解析

    tools.responseSerializer = [AFXMLParserResponseSerializer serializer];
    

    DOM 解析

    tools.responseSerializer =[AFHTTPResponseSerializer serializer];
    

    多值参数

    NetworkTools *tools = [NetworkTools sharedNetworkTools];
    
    NSDictionary *params = @{@"city": @[@"bj", @"sh", @"gz"]};
    
    [tools GET:@"weather.php" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) {
        NSLog(@"%@", responseObject);
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        NSLog(@"%@", error);
    }];
    

    PUT 上传 & 进度跟进

    - (void)putupload {
        NetworkTools *tools = [NetworkTools sharedNetworkTools];
    
        NSString *urlString = @"http://localhost/uploads/321.png";
        NSURL *url = [NSURL URLWithString:urlString];
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        request.HTTPMethod = @"PUT";
    
        NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"001.png" withExtension:nil];
        NSProgress *progress = nil;
        [[tools uploadTaskWithRequest:request fromFile:fileURL progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
            NSLog(@"%@ %@", response, responseObject);
        }] resume];
    
        // KVO
        [progress addObserver:self forKeyPath:@"completedUnitCount" options:NSKeyValueObservingOptionNew context:nil];
    }
    
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
        if ([object isKindOfClass:[NSProgress class]]) {
            NSProgress *progress = object;
            NSLog(@"%@ - %@ - %f", progress.localizedDescription, progress.localizedAdditionalDescription, progress.fractionCompleted);
        }
    }
    

    网络连接状态监听

    [tools.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        NSLog(@"%zd", status);
        switch (status) {
            case AFNetworkReachabilityStatusNotReachable:
                NSLog(@"没有连接");
                break;
            case AFNetworkReachabilityStatusReachableViaWiFi:
                NSLog(@"WI-FI");
                break;
            case AFNetworkReachabilityStatusReachableViaWWAN:
                NSLog(@"3G");
                break;
            default:
                NSLog(@"未知");
                break;
        }
    }];
    [tools.reachabilityManager startMonitoring];
  • 相关阅读:
    c++ 设计模式6 (Decorator 装饰模式)
    c++ 设计模式7 (Bridge 桥模式)
    c++ 设计模式8 (Factory Method 工厂方法)
    c++ 设计模式9 (Abstract Factory 抽象工厂模式)
    C++类设计2(Class with pointer members)
    C++类设计1(Class without pointer members)
    算法总结—链表
    C++对象内存模型1(堆栈模型)
    PHP 页面编码声明方法详解(header或meta)
    php变量与数组相互转换的方法(extract与compact
  • 原文地址:https://www.cnblogs.com/donghaoios/p/5090797.html
Copyright © 2011-2022 走看看