IOS 使用Block二次封装AFNetworking 3.0详解

IOS 使用Block二次封装AFNetworking 3.0详解

1. 前言

AFNetworking 是 iOS 开发中常用的网络请求库,其基于 NSURLConnectionNSURLSession,提供了更加简单方便的接口,使得开发者可以方便地进行网络请求。

但是,AFNetworking 中的回调方式为传统的代理方法,不够便捷。为此,我们可以进行二次封装,使用 Block 作为网络请求结果的回调方式,在开发中更为方便。

本文将详细讲解如何使用 Block 二次封装 AFNetworking,并提供示例说明。

2. 封装过程

2.1 创建网络请求类

先创建一个网络请求类 NetRequest。这个类提供网络请求的基本功能,包括 GET 请求、POST 请求、上传文件等主要的请求功能。

这个网络请求类可以使用单例模式,保证全局只有一个实例。

@interface NetRequest : NSObject

+ (instancetype)getInstance;

- (void)requestWithMethod:(NSString *)method
                      url:(NSString *)url
               parameters:(NSDictionary *)parameters
                  success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
                  failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure;

@end

2.2 实现网络请求类

在实现网络请求类时,我们需要使用 AFNetworking 中提供的 AFHTTPSessionManager 类。我们可以将这个类的实例作为属性加入到我们的网络请求类中。

@interface NetRequest()

@property (nonatomic, strong) AFHTTPSessionManager *manager;

@end

@implementation NetRequest

+ (instancetype)getInstance {
    static NetRequest *request = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        request = [[NetRequest alloc] init];
    });
    return request;
}

- (instancetype)init {
    if (self = [super init]) {
        _manager = [AFHTTPSessionManager manager];
        _manager.requestSerializer = [AFJSONRequestSerializer serializer];
        _manager.responseSerializer = [AFJSONResponseSerializer serializer];
    }
    return self;
}

- (void)requestWithMethod:(NSString *)method
                      url:(NSString *)url
               parameters:(NSDictionary *)parameters
                  success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
                  failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure {
    if ([method isEqualToString:@"GET"]) {
        [self.manager GET:url
               parameters:parameters
                  headers:nil
                 progress:nil
                  success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            if (success) {
                success(task, responseObject);
            }
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            if (failure) {
                failure(task, error);
            }
        }];
    } else if ([method isEqualToString:@"POST"]) {
        [self.manager POST:url
                parameters:parameters
                   headers:nil
                  progress:nil
                   success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            if (success) {
                success(task, responseObject);
            }
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            if (failure) {
                failure(task, error);
            }
        }];
    }
}

@end

其中:

  • GET 请求使用 GET 方法,同时对应的成功和失败的回调均使用传入的 successfailure 参数来获取。
  • POST 请求使用 POST 方法,同时对应的成功和失败的回调均使用传入的 successfailure 参数来获取。

NetRequest 类的实现完成后,我们就可以使用这个类来进行网络请求了。

2.3 进一步封装

如果我们需要在网络请求中添加其他的功能,例如数据缓存,请求重试等,都可以在 NetRequest 类中进一步实现。

例如:实现一个添加缓存功能的网络请求方法

/**
 * GET 请求,支持缓存
 * @param url 请求 URL
 * @param parameters 请求参数
 * @param cache 过期时间,单位为秒,-1 表示永不过期,0 表示不使用缓存,默认为 -1。
 * @param success 请求成功回调
 * @param failure 请求失败回调
 */
- (void) getWithUrl:(NSString *)url
         parameters:(NSDictionary *)parameters
               cache:(NSTimeInterval)cache
            success:(void (^)(NSURLSessionDataTask *, id))success
            failure:(void (^)(NSURLSessionDataTask *, NSError *))failure {
    if (cache > 0) {
        // 从缓存中获取数据
        id responseObject = [CacheManager cacheForKey:url];
        if (responseObject) {
            if (success) {
                success(nil, responseObject);
            }
            return;
        }
    }

    // 没有从缓存中获取到数据,进行网络请求
    [self getWithUrl:url parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
        if (cache > 0) {
            // 将数据保存在缓存中
            [CacheManager setCache:responseObject forKey:url expireTime:cache];
        }
        if (success) {
            success(task, responseObject);
        }
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        if (failure) {
            failure(task, error);
        }
    }];
}

其中,如果 cache 参数大于 0,我们会先从缓存中获取数据,如果缓存中有数据,就直接返回,并调用成功回调。如果没有缓存数据,就进行网络请求。

3. 示例说明

下面是两个示例,演示如何使用封装好的 NetRequest 类进行网络请求。

示例1:GET 请求

NSDictionary *params = @{@"key1": @"value1", @"key2": @"value2"};
[[NetRequest getInstance] requestWithMethod:@"GET"
                                        url:@"http://httpbin.org/get"
                                 parameters:params
                                    success:^(NSURLSessionDataTask *task, id responseObject) {
        NSLog(@"%@", responseObject);
    }
                                    failure:^(NSURLSessionDataTask *task, NSError *error) {
        NSLog(@"%@", error);
    }];

这个请求会向 httpbin.org 发送一个 GET 请求,并将 params 中的参数附加在 URL 后面,请求成功回调中会打印出服务端返回的数据。

示例2:下载文件

NSString *url = @"http://httpbin.org/image/jpeg";
NSURLSessionDownloadTask *task = [[NetRequest getInstance].manager downloadTaskWithURL:[NSURL URLWithString:url] completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    if (error) {
        NSLog(@"Download Error: %@", error);
    } else {
        NSString *documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        NSString *fileUrl = [documentsDirectoryPath stringByAppendingPathComponent:@"image.jpeg"];
        [[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:fileUrl] error:nil];
    }
}];
[task resume];

这个请求会向 httpbin.org 发送一个下载图片的请求,请求成功后会将图片下载到应用的 document 目录中。

4. 总结

以上就是使用 Block 二次封装 AFNetworking 3.0 的完整攻略。我们可以将这个封装好的网络请求类作为一个通用的工具类,方便项目中的其他模块使用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:IOS 使用Block二次封装AFNetworking 3.0详解 - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • 详解Linux下find查找文件命令和grep查找文件命令

    下面我将详细讲解Linux下find查找文件命令和grep查找文件命令的攻略。 find查找文件命令 命令格式 find [path] [expression] 其中,path为要查找的目录或文件,不填则默认为当前目录;expression为查找的表达式,用于对文件名进行匹配或对文件属性进行查找。 常用参数 -name:按照文件名进行查找; -type:按照…

    other 2023年6月26日
    00
  • Swift中定义单例的方法实例

    当我们需要在Swift中创建一个单例(Singleton)时,可以使用以下方法: 方法一:使用静态常量 class Singleton { static let shared = Singleton() private init() { // 初始化代码 } // 其他方法和属性 } 在这个示例中,我们创建了一个名为Singleton的类,并定义了一个静态常…

    other 2023年7月29日
    00
  • javascript 用局部变量来代替全局变量第1/2页

    JavaScript 用局部变量来代替全局变量攻略 在 JavaScript 中,全局变量的使用可能会导致一些问题,例如命名冲突和代码维护性差。为了解决这些问题,我们可以使用局部变量来代替全局变量。本攻略将详细介绍如何使用局部变量来代替全局变量,并提供两个示例说明。 步骤1:理解全局变量和局部变量的概念 在开始之前,我们需要理解全局变量和局部变量的概念。 全…

    other 2023年7月29日
    00
  • Powershell Profiles配置文件的存放位置介绍

    当进入Powershell命令行时,Powershell会自动执行一个叫做Profile的脚本。Profile可以用于配置Powershell环境初始化,比如设置环境变量、导入常见的模块等等。本篇攻略将会介绍在Windows系统中,Powershell Profile的存放位置,并且提供两个示例来演示Profile的使用。 存放位置 Powershell P…

    other 2023年6月25日
    00
  • 下载:Android 7.0开发者预览官方工厂镜像 附刷机方法

    下载 Android 7.0 开发者预览官方工厂镜像及刷机方法 Android 7.0 开发者预览版是 Android 系统的下一个大版本更新,此版本提供了更多的新特性和优化,让开发者和用户体验更加完美。本篇文章将介绍如何下载 Android 7.0 开发者预览版的官方工厂镜像,并提供了刷机方法。 一、下载 Android 7.0 开发者预览版官方工厂镜像 …

    other 2023年6月26日
    00
  • 压力测试工具——jmeter

    压力测试工具——jmeter 1. 什么是jmeter Apache JMeter是一个纯Java应用程序,用于性能测试和基准测试Web应用程序,进行负载测试,功能测试和压力测试。 2. jmeter能做什么 JMeter能够以不同的方式测试不同类型的应用程序,例如:- web应用程序:HTTP, HTTPS (Java, NodeJS, PHP, ASP.…

    其他 2023年3月28日
    00
  • 封装好的省市地区联动控件附下载

    本文将为大家介绍如何使用封装好的省市区联动控件及其下载方式。 1. 下载 该控件源码可以在GitHub上找到,可以通过以下链接进行下载: https://github.com/cipchk/v-orgpicker 2. 安装 下载完成后,解压缩得到v-orgpicker文件夹。将该文件夹拷贝到你的项目的所在目录中,然后在你的项目中通过import导入v-or…

    other 2023年6月25日
    00
  • C语言内存操作函数详解

    C语言内存操作函数详解 C语言是一门近乎底层的编程语言,与其他高级编程语言相比,C语言提供了更加精细的内存操作功能。C语言内存操作函数可以分为以下四类: 内存拷贝函数 内存比较函数 内存设置函数 内存分配和释放函数 下面将详细讲解这些函数。 一、内存拷贝函数 memcpy()、memmove()和strcpy()函数都可以进行内存拷贝的操作。其中,memcp…

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部