睿诚科技协会

AFNetworking网络请求如何使用?

AFNetworking 是一个在 iOS/macOS 开发中非常流行的第三方网络请求库,它基于苹果的 NSURLConnectionNSURLSession 进行了封装,极大地简化了网络请求的代码,提供了非常友好的 API。

AFNetworking网络请求如何使用?-图1
(图片来源网络,侵删)

准备工作:安装与配置

在使用 AFNetworking 之前,你需要先将其添加到你的项目中。

CocoaPods (推荐)

在你的 Podfile 文件中添加以下代码:

platform :ios, '9.0' # 或你项目支持的最低版本
use_frameworks!
target 'YourProjectName' do
  pod 'AFNetworking', '~> 3.2.1' # 指定一个稳定版本
end

然后在终端中,进入项目根目录,执行命令:

pod install

之后,请务必使用 .xcworkspace 文件来打开你的项目,而不是 .xcodeproj 文件。

AFNetworking网络请求如何使用?-图2
(图片来源网络,侵删)

手动导入

  1. AFGitHub 仓库 下载最新源码。
  2. AFNetworking 文件夹拖入你的 Xcode 项目中。
  3. 在弹出的选项中,确保勾选了 "Copy items if needed" 并将目标选为你的 App Target。

核心组件简介

AFNetworking 的核心类都在 AFNetworking.h 中引入,主要有以下几个:

  • AFHTTPSessionManager: 这是最常用、最核心的类,它内部管理着一个 NSURLSession 对象,封装了常用的 HTTP 请求方法(GET, POST, PUT, DELETE 等),你几乎所有的网络请求都可以通过这个类来完成。
  • AFURLSessionManager: AFHTTPSessionManager 的父类,提供了更底层的 NSURLSession 管理功能,如果你需要更灵活的控制,可以使用这个类。
  • AFSecurityPolicy: 用于管理 SSL/TLS 的验证策略,比如是否允许自签名证书、是否验证主机名等,对安全性要求高的 App 非常重要。
  • AFNetworkReachabilityManager: 用于监控网络连接状态(如 WWAN, WiFi, Not Reachable),可以实现网络状态的实时监听。

基本使用示例

步骤 1: 创建 AFHTTPSessionManager 实例

我们会在应用中创建一个单例的 AFHTTPSessionManager 来统一管理所有的网络请求。

// Swift
import AFNetworking
let manager = AFHTTPSessionManager()
// Objective-C
#import <AFNetworking/AFNetworking.h>
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

步骤 2: 设置请求序列化器

AFHTTPSessionManager 默认使用 JSONResponseSerializer 来解析 JSON 响应,你也可以设置为其他类型,XMLProperty List

// 设置响应序列化为 JSON (默认)
manager.responseSerializer = AFJSONResponseSerializer()
// 如果服务器返回的是 XML,可以这样设置
// manager.responseSerializer = AFXMLParserResponseSerializer()
// 设置请求序列化,用于将请求参数编码
manager.requestSerializer = AFJSONRequestSerializer()
// 设置响应序列化为 JSON (默认)
manager.responseSerializer = [AFJSONResponseSerializer serializer];
// 如果服务器返回的是 XML,可以这样设置
// manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
// 设置请求序列化
manager.requestSerializer = [AFJSONRequestSerializer serializer];

步骤 3: 发起 GET 请求

GET 请求通常用于从服务器获取数据。

AFNetworking网络请求如何使用?-图3
(图片来源网络,侵删)
// Swift
let parameters: [String: Any] = ["key1": "value1", "key2": "value2"]
// GET 请求参数可以直接拼在 URL 后面,也可以通过 parameters 传递
manager.get("https://example.com/api/data", parameters: parameters, progress: { (progress) in
    // 请求进度
    print("Download Progress: \(progress.fractionCompleted)")
}, success: { (task, responseObject) in
    // 请求成功
    // responseObject 是解析后的 JSON 对象 (Swift 中是 Any, OC 中是 id)
    print("Response: \(responseObject ?? "")")
}, failure: { (task, error) in
    // 请求失败
    // error 是包含错误信息的 NSError 对象
    print("Error: \(error.localizedDescription)")
})
// Objective-C
NSDictionary *parameters = @{@"key1": @"value1", @"key2": @"value2"};
[manager GET:@"https://example.com/api/data" parameters:parameters progress:^(NSProgress * _Nonnull downloadProgress) {
    // 请求进度
    NSLog(@"Download Progress: %f", downloadProgress.fractionCompleted);
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
    // 请求成功
    // responseObject 是解析后的 JSON 对象
    NSLog(@"Response: %@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    // 请求失败
    // error 是包含错误信息的 NSError 对象
    NSLog(@"Error: %@", error.localizedDescription);
}];

步骤 4: 发起 POST 请求

POST 请求通常用于向服务器提交数据,比如表单提交、文件上传等。

// Swift
let parameters: [String: Any] = ["username": "test", "password": "123456"]
manager.post("https://example.com/api/login", parameters: parameters, progress: nil, success: { (task, responseObject) in
    print("Login Success: \(responseObject ?? "")")
}, failure: { (task, error) in
    print("Login Failed: \(error.localizedDescription)")
})
// Objective-C
NSDictionary *parameters = @{@"username": @"test", @"password": @"123456"};
[manager POST:@"https://example.com/api/login" parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
    NSLog(@"Login Success: %@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"Login Failed: %@", error.localizedDescription);
}];

高级功能

上传文件

AFNetworking 对文件上传做了很好的封装。

// Swift
let fileURL = Bundle.main.url(forResource: "image", withExtension: "jpg")!
manager.upload(fileURL, to: "https://example.com/api/upload", method: .post, headers: nil, constructingBody: { (formData) in
    // 可以在这里添加其他表单字段
    formData.appendPart(withFormData: "description".data(using: .utf8)!, name: "description")
    // 上传文件
    formData.appendPart(withFileURL: fileURL, name: "file")
}, progress: { (progress) in
    print("Upload Progress: \(progress.fractionCompleted)")
}, success: { (task, responseObject) in
    print("Upload Success: \(responseObject ?? "")")
}, failure: { (task, error) in
    print("Upload Failed: \(error.localizedDescription)")
})
// Objective-C
NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"image" withExtension:@"jpg"];
[manager uploadFile:fileURL
                to:@"https://example.com/api/upload"
             method:@"POST"
            headers:nil
   constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
    // 添加其他表单字段
    [formData appendPartWithFormData:[@"description" dataUsingEncoding:NSUTF8StringEncoding] name:@"description"];
    // 上传文件
    [formData appendPartWithFileURL:fileURL name:@"file" error:nil];
} progress:^(NSProgress * _Nonnull uploadProgress) {
    NSLog(@"Upload Progress: %f", uploadProgress.fractionCompleted);
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
    NSLog(@"Upload Success: %@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    NSLog(@"Upload Failed: %@", error.localizedDescription);
}];

下载文件

// Swift
let downloadURL = URL(string: "https://example.com/file.zip")!
let downloadTask = manager.downloadTask(with: downloadURL, progress: { (progress) in
    print("Download Progress: \(progress.fractionCompleted)")
}, destination: { (targetPath, response) in
    // 指定下载文件的保存路径
    let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let fileURL = documentsURL.appendingPathComponent(response.suggestedFilename!)
    return fileURL
}, completionHandler: { (task, localURL, error) in
    if let error = error {
        print("Download Error: \(error.localizedDescription)")
    } else {
        print("Download Finished at: \(localURL!.path)")
    }
})
downloadTask.resume() // 必须手动启动任务

// Objective-C
NSURL *downloadURL = [NSURL URLWithString:@"https://example.com/file.zip"];
NSURLSession
分享:
扫描分享到社交APP
上一篇
下一篇