MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Objective-C中的网络请求库AFNetworking应用

2024-02-125.2k 阅读

1. AFNetworking 简介

AFNetworking 是一款功能强大、使用广泛的 iOS 和 macOS 网络请求库,它为开发者提供了简洁易用的 API 来处理各种网络请求,如 GET、POST、PUT、DELETE 等,并且支持多种数据格式,如 JSON、XML、HTTP 等。AFNetworking 具有高度的可定制性,能够满足不同项目的需求。它还提供了诸如请求缓存、认证、网络状态监测等功能,极大地简化了网络请求的开发流程。

1.1 AFNetworking 的特点

  • 简单易用:AFNetworking 的 API 设计简洁明了,开发者可以轻松上手,快速实现各种网络请求功能。
  • 性能卓越:经过优化的网络请求机制,能够高效地处理网络请求,减少网络延迟,提高应用的响应速度。
  • 支持多种请求类型:全面支持常见的 HTTP 请求方法,包括 GET、POST、PUT、DELETE 等,满足不同业务场景的需求。
  • 数据格式支持丰富:可以方便地处理 JSON、XML、HTTP 等多种数据格式,适应不同后端接口的数据返回形式。
  • 可定制性强:提供了丰富的配置选项,开发者可以根据项目需求对网络请求进行定制,如设置超时时间、添加请求头、处理认证等。
  • 网络状态监测:能够实时监测网络状态的变化,让应用可以根据网络情况做出相应的处理,如提示用户网络异常、暂停或重试请求等。

2. AFNetworking 的安装与配置

2.1 使用 CocoaPods 安装 AFNetworking

CocoaPods 是 iOS 和 macOS 项目中常用的第三方库管理工具,使用它来安装 AFNetworking 非常方便。

  1. 创建或打开项目:首先在 Xcode 中创建一个新的项目,或者打开现有的项目。
  2. 创建 Podfile:在项目的根目录下,通过终端执行 pod init 命令,这会在项目根目录生成一个 Podfile 文件。
  3. 编辑 Podfile:打开 Podfile 文件,添加以下内容:
platform :ios, '9.0'
target 'YourTargetName' do
  pod 'AFNetworking', '~> 4.0'
end

请将 YourTargetName 替换为你项目的实际目标名称,~> 4.0 表示安装 AFNetworking 的 4.0 版本及以上的最新版本。 4. 安装 AFNetworking:在终端中进入项目根目录,执行 pod install 命令。CocoaPods 会自动下载 AFNetworking 及其依赖库,并生成一个 xcworkspace 文件。 5. 使用项目:从现在开始,需要使用生成的 xcworkspace 文件打开项目,而不是原来的 xcodeproj 文件。

2.2 手动安装 AFNetworking

如果不想使用 CocoaPods,也可以手动安装 AFNetworking。

  1. 下载 AFNetworking:从 AFNetworking 的官方 GitHub 仓库(https://github.com/AFNetworking/AFNetworking)下载最新的代码。
  2. 添加文件到项目:解压下载的文件,将 AFNetworking 文件夹拖入到 Xcode 项目中。在弹出的对话框中,确保勾选了 “Copy items if needed” 和 “Create groups”,并选择合适的目标。
  3. 配置项目设置
    • 添加系统框架:AFNetworking 依赖一些系统框架,需要在项目的 “Build Phases” -> “Link Binary With Libraries” 中添加以下框架:
      • CFNetwork.framework
      • Security.framework
      • MobileCoreServices.framework(如果是 iOS 项目)
      • CoreServices.framework(如果是 macOS 项目)
    • 设置头文件搜索路径:在项目的 “Build Settings” -> “Search Paths” -> “Header Search Paths” 中添加 $(SRCROOT)/AFNetworking,并将其设置为 “recursive”。

3. AFNetworking 的基本使用

3.1 创建 AFHTTPSessionManager

在使用 AFNetworking 进行网络请求之前,首先需要创建一个 AFHTTPSessionManager 对象。AFHTTPSessionManager 是 AFNetworking 中用于处理 HTTP 请求的核心类,它继承自 AFURLSessionManager

#import <AFNetworking/AFNetworking.h>

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

上述代码通过 +manager 类方法创建了一个默认配置的 AFHTTPSessionManager 对象。默认情况下,AFHTTPSessionManager 使用 application/json 作为请求和响应的序列化格式。

3.2 GET 请求

GET 请求是最常见的网络请求方式之一,用于从服务器获取数据。

NSString *urlString = @"https://example.com/api/data";
NSDictionary *parameters = @{@"param1": @"value1", @"param2": @"value2"};

[manager GET:urlString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"请求成功,响应数据:%@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"请求失败,错误信息:%@", error);
}];

在上述代码中:

  • urlString 是请求的 URL 地址。
  • parameters 是请求参数,以字典的形式传递。如果没有参数,可以设置为 nil
  • progress 是一个块,用于监听请求的进度。这里设置为 nil,表示不监听进度。
  • success 块在请求成功时调用,responseObject 是服务器返回的响应数据,根据响应的序列化格式(默认 JSON),它可能是一个字典、数组等对象。
  • failure 块在请求失败时调用,error 包含了请求失败的详细信息。

3.3 POST 请求

POST 请求通常用于向服务器提交数据,如用户注册、登录等场景。

NSString *urlString = @"https://example.com/api/submit";
NSDictionary *parameters = @{@"username": @"user1", @"password": @"pass123"};

[manager POST:urlString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"请求成功,响应数据:%@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"请求失败,错误信息:%@", error);
}];

POST 请求的代码结构与 GET 请求类似,只是将 GET 方法替换为 POST 方法。同样,parameters 包含要提交的数据。

3.4 其他请求方法

除了 GET 和 POST 请求,AFNetworking 还支持 PUT、DELETE、PATCH 等常见的 HTTP 请求方法,使用方式与 GET 和 POST 类似。

  • PUT 请求
NSString *urlString = @"https://example.com/api/update";
NSDictionary *parameters = @{@"id": @"123", @"name": @"newName"};

[manager PUT:urlString parameters:parameters success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"请求成功,响应数据:%@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"请求失败,错误信息:%@", error);
}];
  • DELETE 请求
NSString *urlString = @"https://example.com/api/delete";
NSDictionary *parameters = @{@"id": @"123"};

[manager DELETE:urlString parameters:parameters success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"请求成功,响应数据:%@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"请求失败,错误信息:%@", error);
}];
  • PATCH 请求
NSString *urlString = @"https://example.com/api/patch";
NSDictionary *parameters = @{@"id": @"123", @"status": @"updated"};

[manager PATCH:urlString parameters:parameters success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"请求成功,响应数据:%@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"请求失败,错误信息:%@", error);
}];

4. AFNetworking 的数据序列化与反序列化

4.1 数据序列化

数据序列化是指将应用程序中的数据对象转换为适合在网络上传输的格式,如 JSON、XML 等。AFNetworking 支持多种数据序列化格式,默认使用 JSON 序列化。

  • JSON 序列化:AFNetworking 的 AFJSONRequestSerializer 类用于 JSON 序列化。默认情况下,AFHTTPSessionManager 使用 AFJSONRequestSerializer 来序列化请求数据。
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
NSDictionary *parameters = @{@"key1": @"value1", @"key2": @"value2"};
NSData *jsonData = [manager.requestSerializer dataWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://example.com"]] parameters:parameters error:nil];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(@"JSON 序列化后的数据:%@", jsonString);

上述代码展示了如何获取 AFJSONRequestSerializer 并将字典数据序列化为 JSON 格式的 NSData,然后转换为字符串进行查看。

  • XML 序列化:如果需要使用 XML 序列化,可以使用 AFXMLRequestSerializer 类。
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.requestSerializer = [AFXMLRequestSerializer serializer];
NSDictionary *parameters = @{@"key1": @"value1", @"key2": @"value2"};
NSData *xmlData = [manager.requestSerializer dataWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://example.com"]] parameters:parameters error:nil];
NSString *xmlString = [[NSString alloc] initWithData:xmlData encoding:NSUTF8StringEncoding];
NSLog(@"XML 序列化后的数据:%@", xmlString);

4.2 数据反序列化

数据反序列化是将从网络接收到的数据转换为应用程序能够处理的对象,如字典、数组等。

  • JSON 反序列化:AFNetworking 的 AFJSONResponseSerializer 类用于 JSON 反序列化。默认情况下,AFHTTPSessionManager 使用 AFJSONResponseSerializer 来反序列化响应数据。
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
NSString *urlString = @"https://example.com/api/jsonData";
[manager GET:urlString parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    if ([responseObject isKindOfClass:[NSDictionary class]]) {
        NSDictionary *jsonDict = (NSDictionary *)responseObject;
        NSLog(@"JSON 反序列化后的字典数据:%@", jsonDict);
    } else if ([responseObject isKindOfClass:[NSArray class]]) {
        NSArray *jsonArray = (NSArray *)responseObject;
        NSLog(@"JSON 反序列化后的数组数据:%@", jsonArray);
    }
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"请求失败,错误信息:%@", error);
}];

上述代码展示了如何使用默认的 AFJSONResponseSerializer 反序列化 JSON 格式的响应数据,并根据数据类型进行处理。

  • XML 反序列化:对于 XML 响应数据的反序列化,可以使用 AFXMLParserResponseSerializer 类。
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
NSString *urlString = @"https://example.com/api/xmlData";
[manager GET:urlString parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    if ([responseObject isKindOfClass:[NSXMLParser class]]) {
        NSXMLParser *xmlParser = (NSXMLParser *)responseObject;
        // 在这里可以对 XML 解析器进行进一步处理
        NSLog(@"XML 反序列化后的解析器对象:%@", xmlParser);
    }
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"请求失败,错误信息:%@", error);
}];

在上述代码中,AFXMLParserResponseSerializer 将 XML 响应数据反序列化为 NSXMLParser 对象,开发者可以进一步使用该解析器来处理 XML 数据。

5. AFNetworking 的请求缓存

5.1 缓存策略

AFNetworking 支持多种缓存策略,通过设置 AFURLSessionManagerrequestSerializercachePolicy 属性来实现。常见的缓存策略有:

  • NSURLRequestUseProtocolCachePolicy:使用协议定义的缓存策略,这是默认策略。对于 HTTP 请求,它会遵循 HTTP 协议中的缓存规则,如 ExpiresCache - Control 头信息。
  • NSURLRequestReloadIgnoringLocalCacheData:忽略本地缓存数据,每次都从服务器重新加载数据。
  • NSURLRequestReturnCacheDataElseLoad:先尝试从本地缓存中加载数据,如果缓存中没有,则从服务器加载数据。
  • NSURLRequestReturnCacheDataDontLoad:只从本地缓存中加载数据,即使缓存数据过期或不存在,也不从服务器加载数据。

5.2 示例代码

以下是设置缓存策略的示例代码:

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.requestSerializer.cachePolicy = NSURLRequestReturnCacheDataElseLoad;
NSString *urlString = @"https://example.com/api/cachedData";
[manager GET:urlString parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"请求成功,响应数据:%@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"请求失败,错误信息:%@", error);
}];

在上述代码中,将缓存策略设置为 NSURLRequestReturnCacheDataElseLoad,这样在请求数据时,首先会尝试从本地缓存中获取数据,如果缓存中没有,则会从服务器加载数据。

5.3 缓存管理

AFNetworking 使用 NSURLCache 来管理缓存。可以通过 NSURLCache 的单例对象来设置缓存的大小、清除缓存等操作。

  • 设置缓存大小
NSURLCache *sharedCache = [NSURLCache sharedURLCache];
NSUInteger cacheSizeMemory = 4 * 1024 * 1024; // 4MB 内存缓存
NSUInteger cacheSizeDisk = 20 * 1024 * 1024; // 20MB 磁盘缓存
NSURLCache *newCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:nil];
[NSURLCache setSharedURLCache:newCache];

上述代码将内存缓存大小设置为 4MB,磁盘缓存大小设置为 20MB。

  • 清除缓存
NSURLCache *sharedCache = [NSURLCache sharedURLCache];
[sharedCache removeAllCachedResponses];

执行上述代码后,会清除所有的缓存数据。

6. AFNetworking 的认证

6.1 Basic 认证

Basic 认证是一种简单的认证方式,它将用户名和密码进行 Base64 编码后,放在 HTTP 请求头的 Authorization 字段中发送给服务器。

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
NSString *username = @"user1";
NSString *password = @"pass123";
NSString *authString = [NSString stringWithFormat:@"%@:%@", username, password];
NSData *authData = [authString dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64EncodedAuthString = [authData base64EncodedStringWithOptions:0];
NSString *authHeaderValue = [NSString stringWithFormat:@"Basic %@", base64EncodedAuthString];
[manager.requestSerializer setValue:authHeaderValue forHTTPHeaderField:@"Authorization"];

NSString *urlString = @"https://example.com/api/protectedData";
[manager GET:urlString parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"请求成功,响应数据:%@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"请求失败,错误信息:%@", error);
}];

在上述代码中,首先将用户名和密码进行拼接并转换为 Base64 编码的字符串,然后设置到请求头的 Authorization 字段中,以实现 Basic 认证。

6.2 OAuth 认证

OAuth 是一种开放标准的授权协议,常用于第三方登录等场景。AFNetworking 本身没有直接提供 OAuth 认证的实现,但可以通过结合其他库(如 AFNetworkingOAuthManager)或者手动处理 OAuth 流程来实现。 以下是一个简单的手动处理 OAuth 2.0 认证流程的示例(假设已经获取到了 access token):

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
NSString *accessToken = @"your_access_token";
[manager.requestSerializer setValue:[NSString stringWithFormat:@"Bearer %@", accessToken] forHTTPHeaderField:@"Authorization"];

NSString *urlString = @"https://example.com/api/oauthProtectedData";
[manager GET:urlString parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"请求成功,响应数据:%@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"请求失败,错误信息:%@", error);
}];

在上述代码中,将获取到的 access token 放在请求头的 Authorization 字段中,以 Bearer 类型的认证方式发送请求。

7. AFNetworking 的网络状态监测

7.1 监测网络状态

AFNetworking 提供了 AFNetworkReachabilityManager 类来监测网络状态。可以通过以下方式使用:

#import <AFNetworking/AFNetworking.h>

AFNetworkReachabilityManager *reachabilityManager = [AFNetworkReachabilityManager sharedManager];
[reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
    switch (status) {
        case AFNetworkReachabilityStatusNotReachable:
            NSLog(@"网络不可用");
            break;
        case AFNetworkReachabilityStatusReachableViaWWAN:
            NSLog(@"使用蜂窝网络");
            break;
        case AFNetworkReachabilityStatusReachableViaWiFi:
            NSLog(@"使用 Wi - Fi 网络");
            break;
        default:
            break;
    }
}];
[reachabilityManager startMonitoring];

上述代码创建了一个 AFNetworkReachabilityManager 单例对象,并设置了网络状态变化的回调块。在回调块中,根据不同的网络状态进行相应的处理。最后通过 startMonitoring 方法开始监测网络状态。

7.2 根据网络状态处理请求

可以根据网络状态来决定是否发送网络请求,或者对已有的请求进行暂停、重试等操作。

AFNetworkReachabilityManager *reachabilityManager = [AFNetworkReachabilityManager sharedManager];
[reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
    switch (status) {
        case AFNetworkReachabilityStatusNotReachable:
            // 暂停所有网络请求
            [[AFHTTPSessionManager manager].operationQueue setSuspended:YES];
            break;
        case AFNetworkReachabilityStatusReachableViaWWAN:
        case AFNetworkReachabilityStatusReachableViaWiFi:
            // 恢复所有网络请求
            [[AFHTTPSessionManager manager].operationQueue setSuspended:NO];
            break;
        default:
            break;
    }
}];
[reachabilityManager startMonitoring];

在上述代码中,当网络不可用时,暂停 AFHTTPSessionManager 的操作队列,从而暂停所有网络请求;当网络恢复可用时,恢复操作队列,继续执行网络请求。

8. AFNetworking 的高级应用

8.1 自定义请求头和响应头

在某些情况下,需要为网络请求添加自定义的请求头,或者处理服务器返回的自定义响应头。

  • 添加自定义请求头
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager.requestSerializer setValue:@"CustomValue" forHTTPHeaderField:@"CustomHeader"];

NSString *urlString = @"https://example.com/api/customHeader";
[manager GET:urlString parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"请求成功,响应数据:%@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"请求失败,错误信息:%@", error);
}];

上述代码通过 setValue:forHTTPHeaderField: 方法为请求添加了一个自定义的请求头 CustomHeader,值为 CustomValue

  • 处理自定义响应头
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
NSString *urlString = @"https://example.com/api/customResponseHeader";
[manager GET:urlString parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSDictionary *headers = task.response.allHeaderFields;
    NSString *customHeaderValue = headers[@"CustomResponseHeader"];
    NSLog(@"自定义响应头的值:%@", customHeaderValue);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"请求失败,错误信息:%@", error);
}];

在上述代码中,通过 task.response.allHeaderFields 获取服务器返回的所有响应头,然后从中提取自定义的响应头 CustomResponseHeader 的值。

8.2 并发请求与请求优先级

AFNetworking 使用 NSOperationQueue 来管理网络请求,因此可以方便地实现并发请求和设置请求优先级。

  • 并发请求
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
NSMutableArray<NSURLSessionDataTask *> *tasks = [NSMutableArray array];

NSString *url1 = @"https://example.com/api/data1";
NSURLSessionDataTask *task1 = [manager GET:url1 parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"请求 1 成功,响应数据:%@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"请求 1 失败,错误信息:%@", error);
}];
[tasks addObject:task1];

NSString *url2 = @"https://example.com/api/data2";
NSURLSessionDataTask *task2 = [manager GET:url2 parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"请求 2 成功,响应数据:%@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"请求 2 失败,错误信息:%@", error);
}];
[tasks addObject:task2];

for (NSURLSessionDataTask *task in tasks) {
    [task resume];
}

上述代码创建了两个并发的 GET 请求,通过将 NSURLSessionDataTask 对象添加到数组中,并遍历数组调用 resume 方法来启动请求。

  • 设置请求优先级
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
NSString *url1 = @"https://example.com/api/highPriorityData";
NSURLSessionDataTask *highPriorityTask = [manager GET:url1 parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"高优先级请求成功,响应数据:%@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"高优先级请求失败,错误信息:%@", error);
}];
highPriorityTask.priority = NSURLSessionTaskPriorityHigh;

NSString *url2 = @"https://example.com/api/lowPriorityData";
NSURLSessionDataTask *lowPriorityTask = [manager GET:url2 parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"低优先级请求成功,响应数据:%@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"低优先级请求失败,错误信息:%@", error);
}];
lowPriorityTask.priority = NSURLSessionTaskPriorityLow;

[highPriorityTask resume];
[lowPriorityTask resume];

在上述代码中,通过设置 NSURLSessionDataTaskpriority 属性来设置请求的优先级,NSURLSessionTaskPriorityHigh 表示高优先级,NSURLSessionTaskPriorityLow 表示低优先级。

8.3 上传和下载文件

  • 文件上传
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
NSString *urlString = @"https://example.com/api/upload";
NSURL *fileURL = [NSURL fileURLWithPath:@"/path/to/your/file.jpg"];
[manager POST:urlString parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
    [formData appendPartWithFileURL:fileURL name:@"file" error:nil];
} progress:^(NSProgress * _Nonnull uploadProgress) {
    // 监听上传进度
    NSLog(@"上传进度:%.2f%%", (double)uploadProgress.completedUnitCount / (double)uploadProgress.totalUnitCount * 100);
} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSLog(@"文件上传成功,响应数据:%@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"文件上传失败,错误信息:%@", error);
}];

上述代码展示了如何使用 AFNetworking 上传文件。通过 constructingBodyWithBlock 块将文件添加到请求体中,并可以通过 progress 块监听上传进度。

  • 文件下载
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
NSString *urlString = @"https://example.com/api/download/file.zip";
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
    // 监听下载进度
    NSLog(@"下载进度:%.2f%%", (double)downloadProgress.completedUnitCount / (double)downloadProgress.totalUnitCount * 100);
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
    NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
    return [documentsDirectoryURL URLByAppendingPathComponent:response.suggestedFilename];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
    if (!error) {
        NSLog(@"文件下载成功,保存路径:%@", filePath);
    } else {
        NSLog(@"文件下载失败,错误信息:%@", error);
    }
}];
[downloadTask resume];

在上述代码中,通过 downloadTaskWithRequest:progress:destination:completionHandler: 方法创建一个文件下载任务。destination 块用于指定文件下载后的保存路径,completionHandler 块在下载完成后调用,根据是否有错误来处理下载结果。同时,可以通过 progress 块监听下载进度。