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日

相关文章

  • vue判断字符串长度

    以下是“Vue判断字符串长度”的完整攻略: Vue判断字符串长度 在Vue中,我们可以使用JavaScript的length属性来获取字符串的长度。以下是判断字符串长度的步骤: 1. 获取字符串 首先,我们需要获取要判断长度的字符串。可以使用以下代码: new Vue({ el: ‘#app’, data: { str: ‘Hello, world!’ } …

    other 2023年5月7日
    00
  • iphone手机搜狗输入法快速打字小技巧

    iPhone手机搜狗输入法快速打字小技巧攻略 1. 使用滑动输入法 搜狗输入法在iPhone上提供了滑动输入的功能,可以大大提高打字速度。以下是使用滑动输入法的步骤: 在搜狗输入法中打开滑动输入功能。 在键盘上滑动手指,从一个字母滑到另一个字母,形成一个连续的轨迹。 搜狗输入法会根据轨迹自动识别出你想要输入的单词。 示例说明: 假设你想输入单词\”Hello…

    other 2023年8月19日
    00
  • GIT相关-IDEA/ECLIPSE工具配置的教程详解

    GIT相关-IDEA/Eclipse工具配置的教程详解 一、IDEA工具配置 1. 安装Git插件 首先需要在IDEA中安装Git插件。打开IDEA,点击 Settings -> Plugins,在搜索框中输入Git,选择Git插件并点击 Install 安装即可。 2. 配置Git 安装完Git插件之后,需要在IDEA中对Git进行配置。打开IDEA…

    other 2023年6月27日
    00
  • WPF弹出右键菜单时判断鼠标是否选中该项

    为了完整地讲解“WPF弹出右键菜单时判断鼠标是否选中该项”,我将分为以下步骤进行说明: 什么是 WPF 弹出右键菜单? 弹出右键菜单的基本流程 如何判断鼠标是否选中该项 两条示例说明 1. 什么是 WPF 弹出右键菜单? WPF 弹出右键菜单是一种常用的交互方式,它可以让用户通过鼠标右键点击物体或者某个空白区域时,弹出一个菜单供用户选择操作。 2. 弹出右键…

    other 2023年6月27日
    00
  • DOS未公开的命令与参数

    下面介绍一下如何使用DOS未公开的命令和参数。 什么是DOS未公开的命令和参数 DOS未公开的命令和参数指的是在DOS系统中,虽然未被公开文档所记载,但实际上可以执行的一些命令和参数。它们通常可用于实现一些特殊的功能或调试操作。 这些命令和参数并不受到官方支持,使用时需要注意风险并自担责任。以下是几个常用的DOS未公开的命令和参数,供参考: 命令1:DEBU…

    other 2023年6月26日
    00
  • 正则表达式 运算符优先级介绍

    正则表达式运算符优先级介绍 在正则表达式中,不同的运算符有不同的优先级。了解运算符优先级对于正确构建和解析正则表达式非常重要。本文将详细介绍正则表达式的运算符优先级。 1. 优先级最高的运算符 最高优先级的运算符是括号()。括号的作用是用于分组,可以改变子表达式的优先级。在括号中的子表达式会先于其他运算符进行计算。 2. 优先级次高的运算符 次高优先级的运算…

    other 2023年6月28日
    00
  • 魔兽世界6.0熊T技能循环详解 各技能详细分析

    魔兽世界6.0熊T技能循环详解 本篇攻略介绍了魔兽世界6.0版本中,熊德国王专精的技能循环。本攻略将详细讲解各个技能的使用方法和优先级,帮助熊德国王在战斗中表现更加出色。 技能优先级 魔兽世界熊德国王专精的技能使用优先级如下: 月火术 野性冲锋 槌击 树皮术 重击 塞纳里奥结界 治疗之触(治疗模式下使用) 技能优先级的设定主要是出于几个方面的考虑,首先月火术…

    other 2023年6月27日
    00
  • 未来简史之数据主义(dataism)

    未来简史之数据主义(dataism) 近年来,随着人类社会的不断发展,数据的产生和应用成为了一种不可忽视的趋势。数据主义(Dataism)因此应运而生,成为了越来越多人关注的热点话题。本文将通过对数据主义背景、概念、特点、应用等方面的分析,以期能够更加深入地了解数据主义的意义和重要性。 数据主义的背景 数据主义是由耶鲁大学的文学家戴维·高夫(David Ge…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部