網(wǎng)絡(luò)解析:AFNnetworking詳解
一、什么事AFN□在iOS開發(fā)中,使用比較廣泛□全稱是AFNetworking,是對(duì)NSURLConnection、NSURLsession的一層封裝□雖然運(yùn)行效率沒有ASI高,但是使用比ASI簡(jiǎn)單
二、AFN結(jié)構(gòu)? ? ? ? NSURLConnection? ? ? ? AFURLConnectionOperation? ? ? ? AFHTTPRequestOperation? ? ? ? AFHTTPRequestOperationManager(封裝了常用的 HTTP 方法)? ? ? ? ??
屬性? ? ? ? ??
? ? baseURL :AFN建議開發(fā)者針對(duì) AFHTTPRequestOperationManager 自定義個(gè)一個(gè)單例子類,設(shè)置 baseURL, 所有的網(wǎng)絡(luò)訪問,都只使用相對(duì)路徑即可? ? ? ? ? ? ? ? requestSerializer :請(qǐng)求數(shù)據(jù)格式/默認(rèn)是二進(jìn)制的 HTTP? ? ? ? ? ? ? ? responseSerializer :響應(yīng)的數(shù)據(jù)格式/默認(rèn)是 JSON 格式? ? ? ? ? ? ? ? operationQueue?
reachabilityManager :網(wǎng)絡(luò)連接管理器? ? ?
? ? ? 方法? ? ? ? ?
? ? ? manager :方便創(chuàng)建管理器的類方法? ? ? ? ? ? ? ? HTTPRequestOperationWithRequest :在訪問服務(wù)器時(shí),如果要告訴服務(wù)器一些附加信息,都需要在 Request 中設(shè)置? ? ? ? ? ??
? GET
POST? ? ?
? NSURLSession? ? ? ? AFURLSessionManager? ? ? ? AFHTTPSessionManager(封裝了常用的 HTTP 方法)? ? ? ? ??
GET??
POST? ?
?UIKit + AFNetworking 分類? ? ? ? ? ?
NSProgress :利用KVO? ? 半自動(dòng)的序列化&反序列化的功能? ??
AFURLRequestSerialization :請(qǐng)求的數(shù)據(jù)格式/默認(rèn)是二進(jìn)制的? ?
?AFURLResponseSerialization :響應(yīng)的數(shù)據(jù)格式/默認(rèn)是JSON格式
? 附加功能
? ? ? 安全策略? ??
? ? ? HTTPS? ? ? ?
? ? AFSecurityPolicy??
? ? 網(wǎng)絡(luò)檢測(cè)? ?
? ? ? ? 對(duì)蘋果的網(wǎng)絡(luò)連接檢測(cè)做了一個(gè)封裝? ? ? ? ? ? AFNetworkReachabilityManager三、AFN基本使用1.AFHTTPSessionManager? ? 是AFN中最重要的對(duì)象之一? ? 封裝了HTTP請(qǐng)求的常見處理? ? GET\POST請(qǐng)求? ? 解析服務(wù)器的響應(yīng)數(shù)據(jù)創(chuàng)建AFHTTPSessionManagerAFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];AFHTTPSessionManager的GET\POST請(qǐng)求// GET請(qǐng)求/*? ? http://120.25.226.186:32812/login?username=520it&pwd=520it??
第一個(gè)參數(shù): 請(qǐng)求的地址? http://120.25.226.186:32812/login? ?
第二個(gè)參數(shù): 請(qǐng)求的參數(shù)? username=520it&pwd=520it??
第三個(gè)參數(shù): 請(qǐng)求成功的回調(diào)??
第四個(gè)參數(shù): 請(qǐng)求失敗的回調(diào)? ? 只要利用AFN發(fā)送請(qǐng)求, 如果服務(wù)器返回的是JSON數(shù)據(jù), 那么AFN會(huì)自動(dòng)將JSON轉(zhuǎn)會(huì)成OC對(duì)象返回給我們??
*/- (NSURLSessionDataTask *)GET:(NSString *)URLString? ? ? ? ? ? ? ? ? parameters:(id)parameters? ? ? ? ? ?
? ? ? success:(void (^)(NSURLSessionDataTask *task, id responseObject))success? ? ? ? ? ??
? ? failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure// POST請(qǐng)求- (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.創(chuàng)建AFN管理者? ? AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];? ? // 2.利用AFN管理者發(fā)送請(qǐng)求? ? NSDictionary *params = @{? ? ? ? ? ? ? ? ? ? ? ? ? ? @"username" : @"520it",? ? ? ? ? ? ? ? ? ? ? ? ? ? @"pwd" : @"520it"? ? ? ? ? ? ? ? ? ? ? ? ? ? };??
[manager GET:@"http://120.25.226.186:32812/login" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) {? ? ? ? NSLog(@"請(qǐng)求成功---%@", responseObject);? ? } failure:^(NSURLSessionDataTask *task, NSError *error) {? ? ? ? NSLog(@"請(qǐng)求失敗---%@", error);? ? }];}
// POST- (void)post2{? ? // 1.創(chuàng)建AFN管理者? ? AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];?
? // 2.利用AFN管理者發(fā)送請(qǐng)求? ? NSDictionary *params = @{? ? ? ? ? ? ? ? ? ? ? ? ? ? @"username" : @"520it",? ? ? ? ? ? ? ?
? ? ? ? ? ? @"pwd" : @"520it"? ? ? ? ? ? ?
? ? ? ? ? ? ? };??
[manager POST:@"http://120.25.226.186:32812/login" parameters:params success:^(NSURLSessionDataTask *task, id responseObject) {? ? ? ? NSLog(@"請(qǐng)求成功---%@", responseObject);? ? } failure:^(NSURLSessionDataTask *task, NSError *error) {? ?
? ? NSLog(@"請(qǐng)求失敗---%@", error);? ? }];}
2.AFHTTPRequestOperationManager創(chuàng)建AFHTTPRequestOperationManager// 1.創(chuàng)建AFN管理者? ? // AFHTTPRequestOperationManager內(nèi)部包裝了NSURLConnection? ? AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];AFHTTPRequestOperationManager的GET\POST請(qǐng)求// GET- (NSURLSessionDataTask *)GET:(NSString *)URLString? ? ? ? ? ? ? ? ? parameters:(id)parameters? ? ? ? ? ?
? ? ? ? ? success:(void (^)(NSURLSessionDataTask *task, id responseObject))success? ? ? ? ?
? ? ? ? ? ? failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure// POST請(qǐng)求- (NSURLSessionDataTask *)POST:(NSString *)URLString? ? ? ? ? ? ?
? ? ? parameters:(id)parameters? ? ? ? ? ??
? ? ? ? success:(void (^)(NSURLSessionDataTask *task, id responseObject))success? ? ? ? ? ? ? ?
? ? ? failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure代碼示例- (void)get{?
? // 1.創(chuàng)建AFN管理者? ? // AFHTTPRequestOperationManager內(nèi)部包裝了NSURLConnection? ? AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];??
// 2.利用AFN管理者發(fā)送請(qǐng)求? ? NSDictionary *params = @{
? ? ? ? ? ? ? ? ? ? ? ? ? @"username" : @"520it",? ? ? ? ? ? ?
? ? ? ? ? ? ? @"pwd" : @"520it"? ? ? ? ? ? ?
? ? ? ? ? ? ? };
? [manager GET:@"http://120.25.226.186:32812/login" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {??
? ? NSLog(@"請(qǐng)求成功---%@", responseObject);?
? } failure:^(AFHTTPRequestOperation *operation, NSError *error) {? ? ? ? NSLog(@"請(qǐng)求失敗---%@", error);? ? }];}
- (void)post{?
// 1.創(chuàng)建AFN管理者?
? // AFHTTPRequestOperationManager內(nèi)部包裝了NSURLConnection? ? AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];? ? // 2.利用AFN管理者發(fā)送請(qǐng)求? ? NSDictionary *params = @{? ? ? ? ? ? ? ? ? ? ? ? ? ? @"username" : @"520it",? ? ? ? ? ? ? ? ? ? ? ? ? ? @"pwd" : @"520it"? ? ? ? ? ? ? ? ? ? ? ? ? ? };? ? [manager POST:@"http://120.25.226.186:32812/login" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {? ? ? ? NSLog(@"請(qǐng)求成功---%@", responseObject);? ? } failure:^(AFHTTPRequestOperation *operation, NSError *error) {? ? ? ? NSLog(@"請(qǐng)求失敗---%@", error);? ? }];}
四、AFN文件下載
// 執(zhí)行下載文件的方法,可以監(jiān)控下載進(jìn)度- (void)downLoadMonitor{? ? // 1.創(chuàng)建網(wǎng)絡(luò)管理者? ?
// AFHTTPSessionManager 基于NSURLSession? ? AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
? // 2.利用網(wǎng)絡(luò)管理者下載數(shù)據(jù)? ? NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_02.mp4"]];?
? /*? ? destination? ? - targetPath: 系統(tǒng)給我們自動(dòng)寫入的文件路徑? ? - block的返回值, 要求返回一個(gè)URL, 返回的這個(gè)URL就是剪切的位置的路徑? ? completionHandler? ? - url :destination返回的URL == block的返回的路徑? ? */? ? /*? ? @property int64_t totalUnitCount;? 需要下載文件的總大小? ? @property int64_t completedUnitCount; 當(dāng)前已經(jīng)下載的大小? ? */? ? 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);? ? }];? ? /*? ? 要跟蹤進(jìn)度,需要使用 NSProgress,是在 iOS 7.0 推出的,專門用來(lái)跟蹤進(jìn)度的類!? ? NSProgress只是一個(gè)對(duì)象!如何跟蹤進(jìn)度!-> KVO 對(duì)屬性變化的監(jiān)聽!? ? @property int64_t totalUnitCount;? ? ? ? 總單位數(shù)? ? @property int64_t completedUnitCount;? ? 完成單位數(shù)? ? */? ? // 給Progress添加監(jiān)聽 KVO? ? [progress addObserver:self forKeyPath:@"completedUnitCount" options:NSKeyValueObservingOptionNew context:nil];? ? // 3.啟動(dòng)任務(wù)? ? [downTask resume];}// 收到通知調(diào)用的方法- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(NSProgress *)object change:(NSDictionary *)change context:(void *)context{? ? NSLog(@"%f",1.0 * object.completedUnitCount / object.totalUnitCount);? ? // 回到主隊(duì)列刷新UI? ? dispatch_async(dispatch_get_main_queue(), ^{? ? ? ? self.progress.progress = 1.0 * object.completedUnitCount / object.totalUnitCount;? ? });}
五、AFN序列化?
? 默認(rèn)是JSON數(shù)據(jù),接收類型是JSON? ? ? ? 如果接收的類型和返回的類型不匹配會(huì)報(bào)錯(cuò)? // 1.創(chuàng)建AFN管理者? ? AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];? ? // 默認(rèn)請(qǐng)求二進(jìn)制? ? // 默認(rèn)響應(yīng)是JSON? ? // 告訴AFN,支持接受 text/xml 的數(shù)據(jù)? ? // [AFJSONResponseSerializer serializer].acceptableContentTypes = [NSSet setWithObject:@"text/xml"];? ? // 告訴AFN如何解析數(shù)據(jù)? ? // 告訴AFN客戶端, 將返回的數(shù)據(jù)當(dāng)做JSON來(lái)處理,默認(rèn)的是以JSON處理//? ? manager.responseSerializer = [AFJSONResponseSerializer serializer];? ? // 告訴AFN客戶端, 將返回的數(shù)據(jù)當(dāng)做XML來(lái)處理//? ? manager.responseSerializer = [AFXMLParserResponseSerializer serializer];? ? // 告訴AFN客戶端, 將返回的數(shù)據(jù)當(dāng)做而進(jìn)行來(lái)數(shù)據(jù) (服務(wù)器返回什么就是什么)? ? manager.responseSerializer = [AFHTTPResponseSerializer serializer];
六、AFN文件上傳
// formData: 專門用于拼接需要上傳的數(shù)據(jù)- (NSURLSessionDataTask *)POST:(NSString *)URLString? ? ? ? ? ? ? ? ? ? parameters:(id)parameters? ? constructingBodyWithBlock:(void (^)(idformData))block? ? ? ? ? ? ? ? ? ? success:(void (^)(NSURLSessionDataTask *task, id responseObject))success? ? ? ? ? ? ? ? ? ? failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failureAFN上傳文件代碼示例? ? // 1.創(chuàng)建網(wǎng)絡(luò)管理者? ? AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];? ? // 2.利用網(wǎng)絡(luò)管理者上傳數(shù)據(jù)? ? NSDictionary *dict = @{@"username":@"Syl"};? ? // formData: 專門用于拼接需要上傳的數(shù)據(jù)? ? [manager POST:@"http://120.25.226.186:32812/upload" parameters:dict constructingBodyWithBlock:? ? ^void(idformData) {
/*
Data: 需要上傳的數(shù)據(jù)
name: 服務(wù)器參數(shù)的名稱
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"];
// 任意的二進(jìn)制數(shù)據(jù)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) {
// 請(qǐng)求成功
NSLog(@"請(qǐng)求成功 %@", responseObject);
} failure:^void(NSURLSessionDataTask * task, NSError * error) {
// 請(qǐng)求失敗
NSLog(@"請(qǐng)求失敗 %@", error);
}];
七、監(jiān)控聯(lián)網(wǎng)狀態(tài)
1.AFN監(jiān)控聯(lián)網(wǎng)狀態(tài)
聯(lián)網(wǎng)狀態(tài)status
// 2.設(shè)置監(jiān)聽
/*
AFNetworkReachabilityStatusUnknown? ? ? ? ? = -1,? 未識(shí)別
AFNetworkReachabilityStatusNotReachable? ? = 0,? 未連接
AFNetworkReachabilityStatusReachableViaWWAN = 1,? 3G
AFNetworkReachabilityStatusReachableViaWiFi = 2,? wifi
*/
示例代碼
AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
// 提示:要監(jiān)控網(wǎng)絡(luò)連接狀態(tài),必須要先調(diào)用單例的startMonitoring方法
[manager startMonitoring];
[manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
NSLog(@"%d", status);
}];
2.Reachability監(jiān)控聯(lián)網(wǎng)狀態(tài)蘋果提供,導(dǎo)入這兩個(gè)類使用
// 1.檢測(cè)wifi狀態(tài)
Reachability *wifi = [Reachability reachabilityForLocalWiFi];
// 2.檢測(cè)手機(jī)是否能上網(wǎng)絡(luò)(WIFI\3G\2.5G)
Reachability *conn = [Reachability reachabilityForInternetConnection];
// 3.判斷網(wǎng)絡(luò)狀態(tài)
if ([wifi currentReachabilityStatus] != NotReachable) { // 有wifi
NSLog(@"有wifi");
} else if ([conn currentReachabilityStatus] != NotReachable) { // 沒有使用wifi, 使用手機(jī)自帶網(wǎng)絡(luò)進(jìn)行上網(wǎng)
NSLog(@"使用手機(jī)自帶網(wǎng)絡(luò)進(jìn)行上網(wǎng)");
} else { // 沒有網(wǎng)絡(luò)
NSLog(@"沒有網(wǎng)絡(luò)");
}
①判斷聯(lián)網(wǎng)狀態(tài)
// 用WIFI
// [wifi currentReachabilityStatus] != NotReachable
// [conn currentReachabilityStatus] != NotReachable
// 沒有用WIFI, 只用了手機(jī)網(wǎng)絡(luò)
// [wifi currentReachabilityStatus] == NotReachable
// [conn currentReachabilityStatus] != NotReachable
// 沒有網(wǎng)絡(luò)
// [wifi currentReachabilityStatus] == NotReachable
// [conn currentReachabilityStatus] == NotReachable
②實(shí)時(shí)監(jiān)聽網(wǎng)絡(luò)狀態(tài)
#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.檢測(cè)wifi狀態(tài)
Reachability *wifi = [Reachability reachabilityForLocalWiFi];
// 2.檢測(cè)手機(jī)是否能上網(wǎng)絡(luò)(WIFI\3G\2.5G)
Reachability *conn = [Reachability reachabilityForInternetConnection];
// 3.判斷網(wǎng)絡(luò)狀態(tài)
if ([wifi currentReachabilityStatus] != NotReachable) { // 有wifi
NSLog(@"有wifi");
} else if ([conn currentReachabilityStatus] != NotReachable) { // 沒有使用wifi, 使用手機(jī)自帶網(wǎng)絡(luò)進(jìn)行上網(wǎng)
NSLog(@"使用手機(jī)自帶網(wǎng)絡(luò)進(jìn)行上網(wǎng)");
} else { // 沒有網(wǎng)絡(luò)
NSLog(@"沒有網(wǎng)絡(luò)");
}
}
@end