AFNetworking——優(yōu)雅的網(wǎng)絡(luò)框架


AFNetworking 是一個(gè)適用于 iOS、macOS、watchOS 和 tvOS 系統(tǒng)的網(wǎng)絡(luò)框架。它建立在 Foundation URL Loading System 之上,擴(kuò)展了 Cocoa 強(qiáng)大的高級網(wǎng)絡(luò)抽象功能。設(shè)計(jì)精良的模塊化架構(gòu)、功能豐富的 API,讓你能夠安心的使用,輕松實(shí)現(xiàn)各種網(wǎng)絡(luò)請求,比如 GET 請求,POST 請求。

如何開始

討論

  • If you need help, use Stack Overflow. (Tag 'afnetworking')
  • If you'd like to ask a general question, use Stack Overflow.
  • If you found a bug, and can provide steps to reliably reproduce it, open an issue.
  • If you have a feature request, open an issue.
  • If you want to contribute, submit a pull request.

安裝

AFNetworking 支持多種安裝方法。

CocoaPods 安裝

CocoaPods is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries like AFNetworking in your projects. See the "Getting Started" guide for more information. You can install it with the following command:

$ gem install cocoapods

CocoaPods 0.39.0+ is required to build AFNetworking 3.0.0+.

配置

To integrate AFNetworking into your Xcode project using CocoaPods, specify it in your Podfile:

pod 'AFNetworking', '~> 4.0'

Then, run the following command:

$ pod install

Carthage 安裝

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.

You can install Carthage with Homebrew using the following command:

$ brew update
$ brew install carthage

To integrate AFNetworking into your Xcode project using Carthage, specify it in your Cartfile:

github "AFNetworking/AFNetworking" ~> 3.0

Run carthage to build the framework and drag the built AFNetworking.framework into your Xcode project.

版本要求

AFNetworking Version Minimum iOS Target Minimum OS X Target Minimum watchOS Target Minimum tvOS Target Notes
4.x iOS 9 macOS 10.10 watchOS 2.0 tvOS 9.0 Xcode 11+ is required.
3.x iOS 7 OS X 10.9 watchOS 2.0 tvOS 9.0 Xcode 7+ is required. NSURLConnectionOperation support has been removed.
2.6 -> 2.6.3 iOS 7 OS X 10.9 watchOS 2.0 n/a Xcode 7+ is required.
2.0 -> 2.5.4 iOS 6 OS X 10.8 n/a n/a Xcode 5+ is required. NSURLSession subspec requires iOS 7 or OS X 10.9.
1.x iOS 5 Mac OS X 10.7 n/a n/a
0.10.x iOS 4 Mac OS X 10.6 n/a n/a

(OS X projects must support 64-bit with modern Cocoa runtime).

Programming in Swift? Try Alamofire for a more conventional set of APIs.

架構(gòu)

NSURLSession

  • AFURLSessionManager
  • AFHTTPSessionManager

序列化

  • <AFURLRequestSerialization> 請求序列化
    • AFHTTPRequestSerializer
    • AFJSONRequestSerializer
    • AFPropertyListRequestSerializer
  • <AFURLResponseSerialization> 響應(yīng)序列化
    • AFHTTPResponseSerializer
    • AFJSONResponseSerializer
    • AFXMLParserResponseSerializer
    • AFXMLDocumentResponseSerializer (Mac OS X)
    • AFPropertyListResponseSerializer
    • AFImageResponseSerializer
    • AFCompoundResponseSerializer

其他功能

  • AFSecurityPolicy 安全策略模塊
  • AFNetworkReachabilityManager 網(wǎng)絡(luò)狀態(tài)檢測模塊

項(xiàng)目模塊

006tKfTcly1fj0ndu06qaj307f0bqmye.jpg

用法

一、AFURLSessionManager

  • AFURLSessionManager 創(chuàng)建并管理 NSURLSession 對象。
  • NSURLSession 對象的創(chuàng)建需要基于指定的 NSURLSessionConfiguration 對象創(chuàng)建。
  • NSURLSessionConfiguration 對象遵守如下協(xié)議:
    • <NSURLSessionDelegate>
    • <NSURLSessionTaskDelegate>
    • <NSURLSessionDataDelegate>
    • <NSURLSessionDownloadDelegate>

NSURLSessionTask

NSURLSessionDelegate 委托協(xié)議

1. 創(chuàng)建下載任務(wù)

該類中提供了創(chuàng)建兩種下載任務(wù)的方法,一種是一次性下載任務(wù),另一種是可恢復(fù)下載任務(wù),即拿著上一次下載了一部分的緩存數(shù)據(jù)繼續(xù)下載。

// 1.創(chuàng)建 NSURLSessionConfiguration 對象
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

// 2.創(chuàng)建 AFURLSessionManager 對象
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];

// 3.創(chuàng)建 NSURL、NSURLRequest 對象
NSURL *URL = [NSURL URLWithString:@"http://example.com/download.zip"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];

// 4.創(chuàng)建 NSURLSessionDownloadTask 對象
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
    NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
    // 下載數(shù)據(jù)的目標(biāo)路徑
    return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
    // 下載完成后調(diào)用
    NSLog(@"File downloaded to: %@", filePath);
}];
// 5.開啟下載任務(wù)
[downloadTask resume];

2. 創(chuàng)建上傳任務(wù)

該類中提供了創(chuàng)建三種上傳任務(wù)的方法,主要以數(shù)據(jù)的上傳形式進(jìn)行區(qū)分:Data 數(shù)據(jù)、File 數(shù)據(jù)、Stream 流式數(shù)據(jù)。

// 1.創(chuàng)建 NSURLSessionConfiguration 對象
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

// 2.創(chuàng)建 AFURLSessionManager 對象
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];

// 3.創(chuàng)建 NSURL、NSURLRequest 對象
NSURL *URL = [NSURL URLWithString:@"http://example.com/upload"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];

// 4.創(chuàng)建 NSURLSessionUploadTask 對象
NSURL *filePath = [NSURL fileURLWithPath:@"file://path/to/image.png"];
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromFile:filePath progress:nil completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
    if (error) {
        NSLog(@"Error: %@", error);
    } else {
        NSLog(@"Success: %@ %@", response, responseObject);
    }
}];
// 5.開啟上傳任務(wù)
[uploadTask resume];

3. 創(chuàng)建上傳任務(wù),包含多個(gè) Request 信息,帶上傳進(jìn)度指示條

// 1.創(chuàng)建 NSMutableURLRequest 對象,并設(shè)置一系列參數(shù)
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"http://example.com/upload" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
    [formData appendPartWithFileURL:[NSURL fileURLWithPath:@"file://path/to/image.jpg"] name:@"file" fileName:@"filename.jpg" mimeType:@"image/jpeg" error:nil];
} error:nil];

// 2.創(chuàng)建 AFURLSessionManager 對象
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];

// 3.創(chuàng)建 NSURLSessionUploadTask 對象
NSURLSessionUploadTask *uploadTask;
uploadTask = [manager
              uploadTaskWithStreamedRequest:request
              progress:^(NSProgress * _Nonnull uploadProgress) {
                  // 此處不會(huì)在主線程上回調(diào)
                  // 你要負(fù)責(zé)在主線程上更新 UI
                  dispatch_async(dispatch_get_main_queue(), ^{
                      // Update the progress view
                      [progressView setProgress:uploadProgress.fractionCompleted];
                  });
              }
              completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
                  if (error) {
                      NSLog(@"Error: %@", error);
                  } else {
                      NSLog(@"%@ %@", response, responseObject);
                  }
              }];
// 4.開啟下載任務(wù)
[uploadTask resume];

4.創(chuàng)建數(shù)據(jù)任務(wù)

// 1.創(chuàng)建 NSURLSessionConfiguration 對象
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

// 2.創(chuàng)建 AFURLSessionManager 對象
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];

// 3.創(chuàng)建 NSURL、NSURLRequest 對象
NSURL *URL = [NSURL URLWithString:@"http://httpbin.org/get"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];


// 4.創(chuàng)建 NSURLSessionDataTask 對象
NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request
                                               uploadProgress:^(NSProgress * _Nonnull uploadProgress) {

} downloadProgress:^(NSProgress * _Nonnull downloadProgress) {

} completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
    if (error) {
        NSLog(@"Error: %@", error);
    } else {
        NSLog(@"%@ %@", response, responseObject);
    }
}];

// 5.開啟下載任務(wù)
[dataTask resume];

從使用上看,AFURLSessionManager 只是封裝了原生的 NSURLSession 對象,創(chuàng)建網(wǎng)絡(luò)請求步驟流程與原生方法(使用 NSURLSession 類)類似:

AFURLSessionManager

二、AFHTTPSessionManager

AFHTTPSessionManagerAFURLSessionManager 的子類對象,它提供了進(jìn)行 HTTP 請求的便捷方法。當(dāng)設(shè)置好 baseURL (服務(wù)器地址)時(shí),要發(fā)起 GET、POST 等請求時(shí),你就可以使用本類中的便捷方法了,而這些便捷方法只需要傳入相對路徑參數(shù)即可。

總之,AFHTTPSessionManager 提供了發(fā)起 GETHEAD、POSTPUT、PATCH、DELETE 請求的便捷語法。它調(diào)用的是父類 AFURLSessionManager 創(chuàng)建的 NSURLSessionDataTask 類型的任務(wù)。

這個(gè)類并沒有實(shí)現(xiàn)像 NSURLSessionUploadTask、NSURLSessionDownloadTask、NSURLSessionStreamTask 類型的任務(wù)。也就是說,你不能通過這個(gè)類創(chuàng)建上傳任務(wù)、下載任務(wù)或者 Stream 流式任務(wù)!

鼓勵(lì)以 iOS 7 或 Mac OS X 10.9 或更高版本為目標(biāo),并廣泛處理 Web 服務(wù)的開發(fā)人員使用 AFHTTPSessionManager 子類,并提供一種類方法,該方法返回共享的單例對象,在該對象上可以在應(yīng)用程序之間共享身份驗(yàn)證和其他配置。

通過 HTTP 客戶端創(chuàng)建的請求,將按照 requestSerializer 屬性的設(shè)置包含默認(rèn)的請求頭和編碼參數(shù)。 requestSerializer 屬性的實(shí)例是一個(gè)遵守 AFURLRequestSerialization 協(xié)議的對象。

從服務(wù)器接收到的響應(yīng)數(shù)據(jù)將按照 responseSerializers 屬性的設(shè)置自動(dòng)驗(yàn)證并且序列化。 responseSerializers 屬性的實(shí)例是一個(gè)遵守 AFURLResponseSerialization 協(xié)議的對象

初始化方法:

+ (instancetype)manager;
- (instancetype)initWithBaseURL:(nullable NSURL *)url;
- (instancetype)initWithBaseURL:(nullable NSURL *)url
           sessionConfiguration:(nullable NSURLSessionConfiguration *)configuration;

發(fā)起 HTTP 請求方法:

// GET
- (nullable NSURLSessionDataTask *)GET:(NSString *)URLString
                            parameters:(nullable id)parameters
                               headers:(nullable NSDictionary <NSString *, NSString *> *)headers
                              progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgress
                               success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                               failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

// HEAD
- (nullable NSURLSessionDataTask *)HEAD:(NSString *)URLString
                             parameters:(nullable id)parameters
                                headers:(nullable NSDictionary <NSString *, NSString *> *)headers
                                success:(nullable void (^)(NSURLSessionDataTask *task))success
                                failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

// POST
- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
                             parameters:(nullable id)parameters
                                headers:(nullable NSDictionary <NSString *, NSString *> *)headers
                               progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
                                success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                                failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
                             parameters:(nullable id)parameters
                                headers:(nullable NSDictionary <NSString *, NSString *> *)headers
              constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block
                               progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
                                success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                                failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

// PUT
- (nullable NSURLSessionDataTask *)PUT:(NSString *)URLString
                            parameters:(nullable id)parameters
                               headers:(nullable NSDictionary <NSString *, NSString *> *)headers
                               success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                               failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

// PATCH
- (nullable NSURLSessionDataTask *)PATCH:(NSString *)URLString
                              parameters:(nullable id)parameters
                                 headers:(nullable NSDictionary <NSString *, NSString *> *)headers
                                 success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                                 failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

// DELETE
- (nullable NSURLSessionDataTask *)DELETE:(NSString *)URLString
                               parameters:(nullable id)parameters
                                  headers:(nullable NSDictionary <NSString *, NSString *> *)headers
                                  success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                                  failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

// 創(chuàng)建自定義請求方法
- (nullable NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
                                                URLString:(NSString *)URLString
                                               parameters:(nullable id)parameters
                                                  headers:(nullable NSDictionary <NSString *, NSString *> *)headers
                                           uploadProgress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
                                         downloadProgress:(nullable void (^)(NSProgress *downloadProgress))downloadProgress
                                                  success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                                                  failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

一、GET 請求

NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"];
// 默認(rèn)會(huì)話配置
NSURLSessionConfiguration *defaultConfig = [NSURLSessionConfiguration defaultSessionConfiguration];

// 1.創(chuàng)建 AFHTTPSessionManager 對象
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:baseURL sessionConfiguration:defaultConfig];

// 2.構(gòu)建參數(shù),parameters 參數(shù)可以傳 nil
NSString *urlString = @"/login";

// 3.Task 任務(wù)
[manager GET:urlString parameters:nil headers:nil
    progress:^(NSProgress * _Nonnull downloadProgress) {
    // 請求進(jìn)度
} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    // 請求成功
    // task: 通過 task 拿到響應(yīng)頭
    // responseObject: 請求成功返回的響應(yīng)結(jié)果(AFN內(nèi)部已經(jīng)把響應(yīng)體轉(zhuǎn)換為OC對象,通常是字典或數(shù)組)
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    // 請求失敗
    NSLog(@"GET ERROR:%@",error.localizedDescription);
}];

二、POST 請求

// 1.創(chuàng)建 AFHTTPSessionManager 對象
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]
    initWithBaseURL:[NSURL URLWithString:@"https://www.google.com"]];

// 2.請求接口
NSString *relativePaths = @"/login";
// 2.請求參數(shù)
NSDictionary *parameters = @{
                             @"username":@"admin",
                             @"password":@"123456",
                             };
// 3.Task 任務(wù)
[manager POST:relativePaths parameters:parameters headers:nil progress:^(NSProgress * _Nonnull uploadProgress) {
    // 進(jìn)度
} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    // 請求成功
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    // 請求失敗
}];

三、其他設(shè)置

timeoutInterval 設(shè)置請求超時(shí)時(shí)間,默認(rèn)為 60s:

// 設(shè)置請求超時(shí)時(shí)間為 10s
[manager.requestSerializer willChangeValueForKey:@"timeoutInterval"];
manager.requestSerializer.timeoutInterval = 10.f;
[manager.requestSerializer didChangeValueForKey:@"timeoutInterval"];

ContentTypes 類型

// AFN 默認(rèn)接收的 ContentTypes 有以下三種:
self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", nil];

// 如果服務(wù)器返回的 ContentTypes 類型為 text/html,需要設(shè)置如下:
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];

responseSerializer 默認(rèn)把服務(wù)器返回的數(shù)據(jù)當(dāng)做是 JSON 類型并自動(dòng)轉(zhuǎn)化為 Objective-C

// 設(shè)置為 XML 類型,此時(shí)返回的是 NSXMLParser 類型,需要我們自己解析。
manager.responseSerializer = [AFXMLParserResponseSerializer serializer];

// 設(shè)置為其他類型
manager.responseSerializer = [AFHTTPResponseSerializer serializer];

設(shè)置安全策略,驗(yàn)證 SSL 證書

// 驗(yàn)證 CN 域名
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"server" ofType:@"cer"];
NSData *cerData = [NSData dataWithContentsOfFile:cerPath];
manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:[[NSSet alloc]initWithObjects:cerData, nil]];

// 是否信任具有無效或過期 SSL 證書的服務(wù)器(自建證書)
manager.securityPolicy.allowInvalidCertificates = YES;

// 是否在證書的 CN 字段中驗(yàn)證域名
manager.securityPolicy.validatesDomainName = NO;

設(shè)置狀態(tài)欄活動(dòng)指示器

啟用后,系統(tǒng)會(huì)自動(dòng)在應(yīng)用程序發(fā)起網(wǎng)絡(luò)請求時(shí),在狀態(tài)欄顯示旋轉(zhuǎn)的 loading 動(dòng)畫。

  1. 在項(xiàng)目的 AppDelegate.m 文件中導(dǎo)入AFNetworkActivityIndicatorManager.h 文件;
  2. AppDelegate application:didFinishLaunchingWithOptions:方法中設(shè)置如下代碼:
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];

四、請求序列化

請求序列化通過將請求參數(shù)編碼為查詢字符串或者 HTTP 請求體,來為 URL 字符串創(chuàng)建請求。

NSString *URLString = @"http://example.com";
NSDictionary *parameters = @{@"foo": @"bar", @"baz": @[@1, @2, @3]};

一、編碼為查詢字符串

// GET
[[AFHTTPRequestSerializer serializer] requestWithMethod:@"GET" URLString:URLString parameters:parameters error:nil];
GET http://example.com?foo=bar&baz[]=1&baz[]=2&baz[]=3

二、編碼為URL表單

// POST
[[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:URLString parameters:parameters error:nil];
POST http://example.com/
Content-Type: application/x-www-form-urlencoded

foo=bar&baz[]=1&baz[]=2&baz[]=3

三、編碼為 JSON 字符串

// AFJSONRequestSerializer
[[AFJSONRequestSerializer serializer] requestWithMethod:@"POST" URLString:URLString parameters:parameters error:nil];
POST http://example.com/
Content-Type: application/json

{"foo": "bar", "baz": [1,2,3]}

五、網(wǎng)絡(luò)狀態(tài)管理

AFNetworkReachabilityManager 類用于監(jiān)測 WWAN 和 WiFi 接口的網(wǎng)絡(luò)聯(lián)通性。

  • 不要依據(jù)它來決定是否發(fā)起網(wǎng)絡(luò)請求。
    • 你應(yīng)該嘗試發(fā)送網(wǎng)絡(luò)請求。
  • 你可以依據(jù)它來選擇是否自動(dòng)重新發(fā)送請求。
    • 雖然它可能仍然失敗,但當(dāng)連接可用時(shí),可訪問性通知是重試某些東西的好時(shí)機(jī)。
  • 它是一個(gè)判斷網(wǎng)絡(luò)請求失敗原因的很好用的工具。
    • 當(dāng)網(wǎng)絡(luò)請求失敗時(shí),告訴用戶他們已經(jīng)離線,要比告訴他們一些比如”請求超時(shí)”一類的準(zhǔn)確的錯(cuò)誤更好。

See also WWDC 2012 session 706, "Networking Best Practices.".

網(wǎng)絡(luò)狀態(tài)管理使用示例:

AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
[manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
    switch (status) {
        case AFNetworkReachabilityStatusUnknown: {
            DDLogInfo(@"網(wǎng)絡(luò)異常:未知網(wǎng)絡(luò)");
            break;
        }
        case AFNetworkReachabilityStatusNotReachable: {
            DDLogInfo(@"網(wǎng)絡(luò)異常:沒有網(wǎng)絡(luò)");
            break;
        }
        case AFNetworkReachabilityStatusReachableViaWWAN: {
            DDLogInfo(@"網(wǎng)絡(luò)狀態(tài)檢測:蜂窩網(wǎng)絡(luò)");
            break;
        }
        case AFNetworkReachabilityStatusReachableViaWiFi: {
            DDLogInfo(@"網(wǎng)絡(luò)狀態(tài)檢測:WiFi");
            break;                
        }
    }
}];
[networkReachabilityManager startMonitoring]; // 開啟網(wǎng)絡(luò)檢測

六、安全策略

AFSecurityPolicy 基于 X.509 數(shù)字證書和公鑰來確定服務(wù)器是否可信。

向應(yīng)用程序中添加固定的 SSL 證書有助于防止中間人攻擊和其他漏洞。強(qiáng)烈建議處理敏感客戶數(shù)據(jù)或財(cái)務(wù)信息的應(yīng)用程序通過 HTTPS 的連接方式和服務(wù)器通信。

允許無效的 SSL 證書

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.securityPolicy.allowInvalidCertificates = YES; // 生產(chǎn)環(huán)境不建議使用

單元測試

AFNetworking 在 Tests 子目錄中包含一套單元測試。 這些測試可以簡單地執(zhí)行您想要測試的平臺框架上的測試操作。

賬戶

AFNetworking is owned and maintained by the Alamofire Software Foundation.

AFNetworking was originally created by Scott Raymond and Mattt Thompson in the development of Gowalla for iPhone.

AFNetworking's logo was designed by Alan Defibaugh.

And most of all, thanks to AFNetworking's growing list of contributors.

Security Disclosure

If you believe you have identified a security vulnerability with AFNetworking, you should report it as soon as possible via email to security@alamofire.org. Please do not post it to a public issue tracker.

License

AFNetworking is released under the MIT license. See LICENSE for details.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • PLEASE READ THE FOLLOWING APPLE DEVELOPER PROGRAM LICENSE...
    念念不忘的閱讀 13,650評論 5 6
  • **2014真題Directions:Read the following text. Choose the be...
    又是夜半驚坐起閱讀 11,039評論 0 23
  • 清晨 我站著井邊 一片陽光從山頭灑了下來 我伸出右手 金黃金黃的 帶點(diǎn)熱度 沒有一點(diǎn)兒聲音 實(shí)在安靜 忍不住問它 ...
    laiqintoto閱讀 165評論 0 0
  • 用#來表示標(biāo)題,1個(gè)#表示是1級標(biāo)題,依次類推 ##表示二級標(biāo)題 大家好 這表示是個(gè)引用 用+,-,*表示無序列表...
    joykechen閱讀 389評論 0 0
  • 昨天發(fā)送了人生年輪第二季度的分享,和之前一起畫過輪子的朋友聊起來,他說:“我收到了,不知該腫么總結(jié)……今年我的心態(tài)...
    Larissa閱讀 322評論 0 0

友情鏈接更多精彩內(nèi)容