AFN
一、什么是AFN
-
全稱是AFNetworking,是對NSURLConnection的一層封裝
-
雖然運行效率沒有ASI高,但是使用比ASI簡單
-
在iOS開發中,使用比較廣泛
-
AFN的github地址
二、AFN結構
-
NSURLConnection
- AFURLConnectionOperation
- AFHTTPRequestOperation
- AFHTTPRequestOperationManager(封裝了常用的 HTTP 方法)
- 屬性
- baseURL :AFN建議開發者針對 AFHTTPRequestOperationManager 自定義個一個單例子類,設置 baseURL, 所有的網絡訪問,都只使用相對路徑即可
- requestSerializer :請求數據格式/默認是二進制的 HTTP
- responseSerializer :響應的數據格式/默認是 JSON 格式
- operationQueue
- reachabilityManager :網絡連接管理器
- 方法
- manager :方便創建管理器的類方法
- HTTPRequestOperationWithRequest :在訪問服務器時,如果要告訴服務器一些附加信息,都需要在 Request 中設置
- GET
- POST
- 屬性
-
NSURLSession
- AFURLSessionManager
- AFHTTPSessionManager(封裝了常用的 HTTP 方法)
- GET
- POST
- UIKit + AFNetworking 分類
- NSProgress :利用KVO
-
半自動的序列化&反序列化的功能
- AFURLRequestSerialization :請求的數據格式/默認是二進制的
- AFURLResponseSerialization :響應的數據格式/默認是JSON格式
-
附加功能
- 安全策略
- HTTPS
- AFSecurityPolicy
- 網絡檢測
- 對蘋果的網絡連接檢測做了一個封裝
- AFNetworkReachabilityManager
- 安全策略
三、AFN基本使用
1.AFHTTPSessionManager
- 是AFN中最重要的對象之一
- 封裝了HTTP請求的常見處理
- GET\POST請求
- 解析服務器的響應數據
創建AFHTTPSessionManager
AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];
AFHTTPSessionManager的GET\POST請求
// GET請求
/*
http://120.25.226.186:32812/login?username=520it&pwd=520it
第一個參數: 請求的地址 http://120.25.226.186:32812/login
第二個參數: 請求的參數 username=520it&pwd=520it
第三個參數: 請求成功的回調
第四個參數: 請求失敗的回調
只要利用AFN發送請求, 如果服務器返回的是JSON數據, 那么AFN會自動將JSON轉會成OC對象返回給我們
*/
- (NSURLSessionDataTask *)GET:(NSString *)URLString
parameters:(id)parameters
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
// POST請求
- (NSURLSessionDataTask *)POST:(NSString *)URLString
parameters:(id)parameters
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
代碼示例
// GET
- (void)get2
{
// 1.創建AFN管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// 2.利用AFN管理者發送請求
NSDictionary *params = @{
@"username" : @"520it",
@"pwd" : @"520it"
};
[manager GET:@"http://120.25.226.186:32812/login" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(@"請求成功---%@", responseObject);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(@"請求失敗---%@", error);
}];
}
// POST
- (void)post2
{
// 1.創建AFN管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// 2.利用AFN管理者發送請求
NSDictionary *params = @{
@"username" : @"520it",
@"pwd" : @"520it"
};
[manager POST:@"http://120.25.226.186:32812/login" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(@"請求成功---%@", responseObject);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(@"請求失敗---%@", error);
}];
}
2.AFHTTPRequestOperationManager
創建AFHTTPRequestOperationManager
// 1.創建AFN管理者
// AFHTTPRequestOperationManager內部包裝了NSURLConnection
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
AFHTTPRequestOperationManager的GET\POST請求
// GET
- (NSURLSessionDataTask *)GET:(NSString *)URLString
parameters:(id)parameters
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
// POST請求
- (NSURLSessionDataTask *)POST:(NSString *)URLString
parameters:(id)parameters
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
代碼示例
- (void)get
{
// 1.創建AFN管理者
// AFHTTPRequestOperationManager內部包裝了NSURLConnection
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
// 2.利用AFN管理者發送請求
NSDictionary *params = @{
@"username" : @"520it",
@"pwd" : @"520it"
};
[manager GET:@"http://120.25.226.186:32812/login" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"請求成功---%@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"請求失敗---%@", error);
}];
}
- (void)post
{
// 1.創建AFN管理者
// AFHTTPRequestOperationManager內部包裝了NSURLConnection
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
// 2.利用AFN管理者發送請求
NSDictionary *params = @{
@"username" : @"520it",
@"pwd" : @"520it"
};
[manager POST:@"http://120.25.226.186:32812/login" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"請求成功---%@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"請求失敗---%@", error);
}];
}
四、AFN文件下載
// 執行下載文件的方法,可以監控下載進度
- (void)downLoadMonitor
{
// 1.創建網絡管理者
// AFHTTPSessionManager 基於NSURLSession
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// 2.利用網絡管理者下載數據
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_02.mp4"]];
/*
destination
- targetPath: 系統給我們自動寫入的文件路徑
- block的返回值, 要求返回一個URL, 返回的這個URL就是剪切的位置的路徑
completionHandler
- url :destination返回的URL == block的返回的路徑
*/
/*
@property int64_t totalUnitCount; 需要下載文件的總大小
@property int64_t completedUnitCount; 當前已經下載的大小
*/
NSProgress *progress = nil;
NSURLSessionDownloadTask *downTask = [manager downloadTaskWithRequest:request progress:&progress destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
NSString *path = [cachesPath stringByAppendingPathComponent:response.suggestedFilename];
return [NSURL fileURLWithPath:path];
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
NSLog(@"%@",filePath.absoluteString);
}];
/*
要跟蹤進度,需要使用 NSProgress,是在 iOS 7.0 推出的,專門用來跟蹤進度的類!
NSProgress只是一個對象!如何跟蹤進度!-> KVO 對屬性變化的監聽!
@property int64_t totalUnitCount; 總單位數
@property int64_t completedUnitCount; 完成單位數
*/
// 給Progress添加監聽 KVO
[progress addObserver:self forKeyPath:@"completedUnitCount" options:NSKeyValueObservingOptionNew context:nil];
// 3.啟動任務
[downTask resume];
}
// 收到通知調用的方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(NSProgress *)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"%f",1.0 * object.completedUnitCount / object.totalUnitCount);
// 回到主隊列刷新UI
dispatch_async(dispatch_get_main_queue(), ^{
self.progress.progress = 1.0 * object.completedUnitCount / object.totalUnitCount;
});
}
五、AFN序列化
- 默認是JSON數據,接收類型是JSON
- 如果接收的類型和返回的類型不匹配會報錯
// 1.創建AFN管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// 默認請求二進制
// 默認響應是JSON
// 告訴AFN,支持接受 text/xml 的數據
// [AFJSONResponseSerializer serializer].acceptableContentTypes = [NSSet setWithObject:@"text/xml"];
// 告訴AFN如何解析數據
// 告訴AFN客戶端, 將返回的數據當做JSON來處理,默認的是以JSON處理
// manager.responseSerializer = [AFJSONResponseSerializer serializer];
// 告訴AFN客戶端, 將返回的數據當做XML來處理
// manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
// 告訴AFN客戶端, 將返回的數據當做而進行來數據 (服務器返回什么就是什么)
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
六、AFN文件上傳
// formData: 專門用於拼接需要上傳的數據
- (NSURLSessionDataTask *)POST:(NSString *)URLString
parameters:(id)parameters
constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
AFN上傳文件代碼示例
// 1.創建網絡管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// 2.利用網絡管理者上傳數據
NSDictionary *dict = @{@"username":@"Syl"};
// formData: 專門用於拼接需要上傳的數據
[manager POST:@"http://120.25.226.186:32812/upload" parameters:dict constructingBodyWithBlock:
^void(id<AFMultipartFormData> formData) {
/*
Data: 需要上傳的數據
name: 服務器參數的名稱
fileName: 文件名稱
mimeType: 文件的類型
*/
UIImage *image =[UIImage imageNamed:@"minion_02"];
NSData *data = UIImagePNGRepresentation(image);
[formData appendPartWithFileData:data name:@"file" fileName:@"abc.png" mimeType:@"image/png"];
/*
NSURL *url = [NSURL fileURLWithPath:@"/Users/apple/Desktop/CertificateSigningRequest.certSigningRequest"];
// 任意的二進制數據MIMEType application/octet-stream
// [formData appendPartWithFileURL:url name:@"file" fileName:@"abc.cer" mimeType:@"application/octet-stream" error:nil];
[formData appendPartWithFileURL:url name:@"file" error:nil];
*/
} success:^void(NSURLSessionDataTask * task, id responseObject) {
// 請求成功
NSLog(@"請求成功 %@", responseObject);
} failure:^void(NSURLSessionDataTask * task, NSError * error) {
// 請求失敗
NSLog(@"請求失敗 %@", error);
}];
七、監控聯網狀態
1.AFN監控聯網狀態
聯網狀態status
// 2.設置監聽
/*
AFNetworkReachabilityStatusUnknown = -1, 未識別
AFNetworkReachabilityStatusNotReachable = 0, 未連接
AFNetworkReachabilityStatusReachableViaWWAN = 1, 3G
AFNetworkReachabilityStatusReachableViaWiFi = 2, wifi
*/
示例代碼
AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
// 提示:要監控網絡連接狀態,必須要先調用單例的startMonitoring方法
[manager startMonitoring];
[manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
NSLog(@"%d", status);
}];
2.Reachability監控聯網狀態蘋果提供,導入這兩個類使用
// 1.檢測wifi狀態
Reachability *wifi = [Reachability reachabilityForLocalWiFi];
// 2.檢測手機是否能上網絡(WIFI\3G\2.5G)
Reachability *conn = [Reachability reachabilityForInternetConnection];
// 3.判斷網絡狀態
if ([wifi currentReachabilityStatus] != NotReachable) { // 有wifi
NSLog(@"有wifi");
} else if ([conn currentReachabilityStatus] != NotReachable) { // 沒有使用wifi, 使用手機自帶網絡進行上網
NSLog(@"使用手機自帶網絡進行上網");
} else { // 沒有網絡
NSLog(@"沒有網絡");
}
①判斷聯網狀態
// 用WIFI
// [wifi currentReachabilityStatus] != NotReachable
// [conn currentReachabilityStatus] != NotReachable
// 沒有用WIFI, 只用了手機網絡
// [wifi currentReachabilityStatus] == NotReachable
// [conn currentReachabilityStatus] != NotReachable
// 沒有網絡
// [wifi currentReachabilityStatus] == NotReachable
// [conn currentReachabilityStatus] == NotReachable
②實時監聽網絡狀態
#import "ViewController.h"
#import "Reachability.h"
@interface HMViewController ()
@property (nonatomic, strong) Reachability *conn;
@end
@implementation HMViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkState) name:kReachabilityChangedNotification object:nil];
self.conn = [Reachability reachabilityForInternetConnection];
[self.conn startNotifier];
}
- (void)dealloc
{
[self.conn stopNotifier];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)checkNetworkState
{
// 1.檢測wifi狀態
Reachability *wifi = [Reachability reachabilityForLocalWiFi];
// 2.檢測手機是否能上網絡(WIFI\3G\2.5G)
Reachability *conn = [Reachability reachabilityForInternetConnection];
// 3.判斷網絡狀態
if ([wifi currentReachabilityStatus] != NotReachable) { // 有wifi
NSLog(@"有wifi");
} else if ([conn currentReachabilityStatus] != NotReachable) { // 沒有使用wifi, 使用手機自帶網絡進行上網
NSLog(@"使用手機自帶網絡進行上網");
} else { // 沒有網絡
NSLog(@"沒有網絡");
}
}
@end
