AFNetworking是一個令人愉快的iOS和Mac OS X的網絡庫。它建立在基礎URL加載系統之上,擴展了Cocoa中內置的強大的高級網絡抽象。它有一個模塊化架構,設計良好,功能豐富的API,使用起來很方便。
- AFN的簡介
- 簡介
- 請求數據格式
- 響應數據格式
- 數據格式小結
- AFN模擬登陸
- 發送GET請求獲取普通的Json數據
- AFN發送GET請求模擬登陸
- AFN發送POST請求模擬登陸
- AFN常見錯誤
- AFN實現文件上傳和下載
- 文件上傳
- 文件下載
- AFN常用功能
- AFN之BaseURL
- AFN之HTTPS
- AFN之監測網絡環境
- 封裝簡單的網絡請求工具類
AFN的簡介
簡介
- 目前國內開發網絡應用使用最多的第三方框架
- 是專為
Mac OS
和iOS
設計的一套網絡框架 - 對
NSURLConnection
和NSURLSession
做了封裝 - 提供有豐富的API
- 提供了完善的錯誤解決方案
- 使用起來相對來說比較簡單
- 官網地址:AFNetworking
請求數據格式
AFURLRequestSerialization
| 類型 | 說明 |
| --- | :---: | ---:|
| AFHTTPRequestSerializer
| 二進制的,默認的 |
| AFJSONRequestSerializer
| JSON(POST JSON) RESTful 設計風格需要 |
| AFPropertyListRequestSerializer
| PList(POST Plist-開發中幾乎不用) |
響應數據格式
AFURLResponseSerialization
| 類型 | 說明 |
| --- | :---: | ---:|
| AFHTTPResponseSerializer
| HTTP二進制的 |
| AFJSONResponseSerializer
| JSON默認的 |
| AFXMLParserResponseSerializer
| XML Parser解析器 SAX解析 |
| AFXMLDocumentResponseSerializer
| (Mac OS X) XML DOM |
| AFPropertyListResponseSerializer
| PList幾乎不用 |
| AFImageResponseSerializer
| 圖像,不支持GIF |
| AFCompoundResponseSerializer
| 組合的 |
數據格式小結
- 大多數情況下,都是
JSON
格式,不需要指定 - 如果是
XML
格式- 如果
SAX
解析,需要指定格式manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
- 然后利用代理方法解析
- 如果
DOM
解析,需要指定格式manager.responseSerializer = [AFHTTPResponseSerializer serializer];
- 然后利用第三方框架解析
- 如果
- 圖像
-
AFN
支持圖像緩存 - 但是不支持
GIF
-
- 提示
- 使用
AFN
時,一定記住要輸出:error
- 使用
AFN模擬登陸
導入頭文件:
#import "AFNetworking.h
發送GET請求獲取普通的JSON數據
- (IBAction)demo:(id)sender
{
// 1.網絡請求地址
NSString *URLString = @"http://xxxx/demo.json";
// 2.創建網絡請求管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// 3.發送網絡請求
[manager GET:URLString parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"%@ %@",[responseObject class],responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@",error);
}];
}
AFN發送GET請求模擬登陸
- (IBAction)GETLogin:(id)sender {
// NSString *URLString = @"http://xxxx/php/login/login.php?username=zhangsan&password=zhang";
// 登陸地址
NSString *URLString = @"http://xxxx/php/login/login.php";
// 網絡請求管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// 請求參數
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
parameters[@"username"] = @"zhangsan";
parameters[@"password"] = @"zhang";
// 發送GET請求
[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);
}];
}
AFN發送POST請求模擬登陸
- (IBAction)POSTLogin:(id)sender {
// 登陸地址
NSString *URLString = @"http://xxxx/php/login/login.php";
// 網絡請求管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// 請求參數
NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
parameters[@"username"] = @"zhangsan";
parameters[@"password"] = @"zhang";
// 發送POST請求
[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);
}];
}
AFN常見錯誤
AFN常見的序列化和反序列化的錯誤
1.常見錯誤一 :
AFN支持接收 @"application/json", @"text/json", @"text/javascript" 文本類型
AFN不支持接收 text/html 文本類型
2.常見錯誤二 :
AFN默認的成功的回調 responseObject 是把服務器返回的數據當做JSON數據格式解析,返回字典或者數組.
但是在加載網頁數據時,響應體是字符串.需要修改響應的序列化方式,讓AFN給我們返回原始的二進制數據即可.
3.常見錯誤三 :
AFN不支持接收 text/plian 文本類型
4.常見錯誤四 :
AFN默認只支持向服務器發送普通的二進制數據.比如普通的GET和POST請求數據.默認不支持發送JSON數據到服務器
如果要向服務器發送JSON格式的二進制數據,就需要特殊的處理請求的方式.使AFN支持向服務器發送JSON形式的二進制數據
其他常見錯誤
- 加載網頁數據時
- (void)loadData
{
// 網絡請求manager
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// 常見錯誤一 : 修改AFN支持接收的文本類型 : text/html
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", nil];
// 常見錯誤二 : 修改AFN默認的返回的數據類型,設置默認為只返回原始的二進制數據,程序猿自己解析
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
// 網絡請求地址
NSString *URLStr = @"http://www.baidu.com";
// 發送網絡請求
[manager GET:URLStr parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
// NSLog(@"%@ %@",[responseObject class],responseObject);
NSString *html = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(@"%@",html);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"出錯 %@",error);
}];
}
- 向服務器發送JSON數據時
- (void)postJSON
{
// 網絡請求manager
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// 常見錯誤三 : 修改AFN支持接收的文本類型 : text/plian
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", @"text/plain", nil];
// 常見錯誤二 : 修改AFN默認的返回的數據類型,設置默認為只返回原始的二進制數據,程序猿自己解析
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
// 常見錯誤四 : 修改AFN支持向服務器發送JSON形式的二進制數據
manager.requestSerializer = [AFJSONRequestSerializer serializer];
// 網絡請求地址
NSString *URLStr = @"http://localhost/php/upload/postjson.php";
// 請求參數
NSDictionary *parameters = @{
@"name":@"zhangsan"
};
// 發送網絡請求
[manager POST:URLStr parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
// NSLog(@"%@ %@",[responseObject class],responseObject);
NSString *html = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(@"%@",html);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"出錯 %@",error);
}];
}
AFN實現文件上傳和下載
文件上傳
-
文件數據拼接的方法
[formData appendPartWithFileData:data name:@"" fileName:@"" mimeType:@""];
-
文件數據拼接的四個參數
- 參數1:上傳文件的二進制信息
- 參數2:服務器接收二進制數據的字段名(跟服務器要)
- 參數3:文件保存到服務器的名字
- 參數4:上傳的文件的類型
文件上傳的主方法
- (void)uploadFile
{
// 網絡請求地址
NSString *URLStr = @"http://xxxx/php/upload/upload-m.php";
// 文件上傳的附帶信息
NSDictionary *textDict = @{
@"status":@"zhangsan"
};
// 網絡請求manager
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// 發送POST請求
[manager POST:URLStr parameters:textDict constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
// 獲取文件路徑1
NSString *filePath1 = [[NSBundle mainBundle] pathForResource:@"mm01.jpg" ofType:nil];
NSData *fileData1 = [NSData dataWithContentsOfFile:filePath1];
// 拼接數據1
[formData appendPartWithFileData:fileData1 name:@"userfile[]" fileName:[filePath1 lastPathComponent] mimeType:@"image/jpg"];
// 獲取文件路徑2
NSString *filePath2 = [[NSBundle mainBundle] pathForResource:@"mm02.jpg" ofType:nil];
NSData *fileData2 = [NSData dataWithContentsOfFile:filePath2];
// 拼接數據2
[formData appendPartWithFileData:fileData2 name:@"userfile[]" fileName:[filePath2 lastPathComponent] mimeType:@"image/jpg"];
} progress:^(NSProgress * _Nonnull uploadProgress) {
NSLog(@"進度 %f",uploadProgress.fractionCompleted);
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"%@ %@",[responseObject class],responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"出錯 %@",error);
}];
}
文件下載
- (void)downloadFile
{
// 下載地址
NSString *URLString = @"http://xxxx/xcode.zip";
// 請求
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:URLString]];
// 管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// 發起下載任務
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
NSLog(@"進度 %f",downloadProgress.fractionCompleted);
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
// AFN提供的文件保存路徑,在tmp文件中,下載完成之后就會被刪除
NSLog(@"%@",targetPath);
// 自己獲取文件保存的路徑
NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];
// 帶file:// 協議頭
NSURL *locationURL = [NSURL fileURLWithPath:filePath];
// 把文件緩存路徑剪切出去
return locationURL;
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
// 文件最終保存的路徑 : 從上面自動剪切過來的
NSLog(@"%@",filePath.path);
}];
// 開啟下載任務
[downloadTask resume];
}
AFN其他常用功能
AFN之BaseURL
- 使用場景:設計網絡請求工具類時使用
- (IBAction)baseURL:(id)sender
{
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:@"http://localhost/"]];
[manager GET:@"demo.json" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"%@",responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@",error);
}];
}
AFN之HTTPS
// 允許無效的證書 : 2.5.4 版本之前使用
manager.securityPolicy.allowInvalidCertificates = YES;
// 不驗證域名 : 2.6.0 版本之后使用
manager.securityPolicy.validatesDomainName = NO;
- (IBAction)HTTPS:(id)sender
{
// 創建網絡請求mansger
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// 允許無效的證書
// manager.securityPolicy.allowInvalidCertificates = YES;
// 不驗證域名
manager.securityPolicy.validatesDomainName = NO;
// 修改AFN默認支持接收的文本類型
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html" ,nil];
// 修改AFN默認處理數據的方式 : 設置成只返回原始的二進制數據,程序猿自己反序列化
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
// 網絡請求地址
NSString *URLStr = @"https://www.baidu.com";
[manager GET:URLStr parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
// NSLog(@"%@ %@",[responseObject class],responseObject);
// 反序列化
NSString *html = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(@"%@",html);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"出錯 %@",error);
}];
}
AFN之監測網絡環境
- 程序一啟動就開始監測網絡環境
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// 監測網絡環境
AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
/*
status
AFNetworkReachabilityStatusUnknown = -1, 不知道監測的是什么
AFNetworkReachabilityStatusNotReachable = 0, 沒有檢測到網絡
AFNetworkReachabilityStatusReachableViaWWAN = 1, 蜂窩網
AFNetworkReachabilityStatusReachableViaWiFi = 2, WIFI
*/
[manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
NSLog(@"%zd",status);
}];
[manager startMonitoring];
return YES;
}
封裝簡單的網絡請求工具類
新建類 NetworkTool
NetworkTool.h
// 第一步 : 繼承自 AFHTTPSessionManager
@interface NetworkTool : AFHTTPSessionManager
/**
* 網絡請求工具類全局訪問點
*
* @return AFHTTPSessionManager的實例
*/
+ (instancetype)sharedNetworkTool;
/**
* 網絡請求工具類GET請求的主方法
*
* @param URLString 請求地址
* @param success 成功的回調
* @param faile 失敗的回調
*/
- (void)GETWithURLString:(NSString *)URLString success:(void(^)(id responseObject))success faile:(void(^)(NSError *error))faile;
NetworkTool.m
+ (instancetype)sharedNetworkTool
{
static NetworkTool *instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 設置相對路徑
NSURL *BaseURL = [NSURL URLWithString:@"http://c.m.163.com/nc/"];
// 實例化Manager
instance = [[self alloc] initWithBaseURL:BaseURL];
// 增加AFN支持的文件類型
instance.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", @"text/plain", nil];
});
return instance;
}
// 網絡工具類實現GET請求的主方法
- (void)GETWithURLString:(NSString *)URLString success:(void (^)(id))success faile:(void (^)(NSError *))faile
{
[self GET:URLString parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (success) {
success(responseObject);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (faile) {
faile(error);
}
}];
}
感謝讀到最后的朋友,最后祝大家工作順利,請點贊支持一下,謝謝!