1. 程式人生 > >AFNetworking框架IOS網路資料請求由淺入深的使用方法

AFNetworking框架IOS網路資料請求由淺入深的使用方法

一. 概述

我們今天是來深入研究一下這個與我們日常開發密切相關的框架是如何實現的。

這是我對 AFNetworking 整個架構的理解,隨後一系列的文章也會逐步分析這些模組。

在這篇文章中,我們有兩個問題需要了解:

  1. 如何使用 NSURLSession 發出 HTTP 請求

  2. 如何使用 AFNetworking 發出 HTTP 請求

NSURLSession

NSURLSession 以及與它相關的類為我們提供了下載內容的 API,這個 API 提供了一系列的代理方法來支援身份認證,並且支援後臺下載。

使用 NSURLSession 來進行 HTTP 請求並且獲得資料總共有五個步驟:

  1. 例項化一個 NSURLRequest/NSMutableURLRequest,設定 URL

  2. 通過 - sharedSession 方法獲取 NSURLSession

  3. 在 session 上呼叫 - dataTaskWithRequest:completionHandler: 方法返回一個 NSURLSessionDataTask

  4. 向 data task 傳送訊息 - resume,開始執行這個任務

  5. 在 completionHandler 中將資料編碼,返回字串

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[[NSURL
alloc] initWithString:@"https://github.com"]]; NSURLSession *session = [NSURLSession sharedSession]; NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { NSString
*dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@", dataStr); }]; [task resume];

這一段程式碼可以說是使用 NSURLSession 傳送請求最簡單的一段程式碼了,當你執行這段程式碼會在控制檯看到一坨 github 首頁的 html。

<!DOCTYPE html>
<html lang="en" class="">
  <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# object: http://ogp.me/ns/object# article: http://ogp.me/ns/article# profile: http://ogp.me/ns/profile#">
    <meta charset='utf-8'>
        ...
    </head>
    ...
</html>

AFNetworking

AFNetworking 的使用也是比較簡單的,使用它來發出 HTTP 請求有兩個步驟

  1. 以伺服器的主機地址或者域名生成一個 AFHTTPSessionManager 的例項

  2. 呼叫 - GET:parameters:progress:success:failure: 方法

AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[[NSURL alloc] initWithString:@"hostname"]];
[manager GET:@"relative_url" parameters:nil progress:nil
    success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSLog(@"%@" ,responseObject);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"%@", error);
    }];

注意:在 iOS9 中,蘋果預設全域性 HTTPs,如果你要傳送不安全的 HTTP 請求,需要在 info.plist 中加入如下鍵值對才能發出不安全的 HTTP 請求

還有一件事情是要注意的是,AFNetworking 預設接收 json 格式的響應(因為這是在 iOS 平臺上的框架,一般不需要 text/html),如果想要返回 html,需要設定 acceptableContentTypes

AFNetworking 的呼叫棧

在這一節中我們要分析一下在上面兩個方法的呼叫棧,首先來看的是 AFHTTPSessionManager 的初始化方法 - initWithBaseURL:

- [AFHTTPSessionManager initWithBaseURL:]
    - [AFHTTPSessionManager initWithBaseURL:sessionConfiguration:]
        - [AFURLSessionManager initWithSessionConfiguration:]
            - [NSURLSession sessionWithConfiguration:delegate:delegateQueue:]
            - [AFJSONResponseSerializer serializer] // 負責序列化響應
            - [AFSecurityPolicy defaultPolicy] // 負責身份認證
            - [AFNetworkReachabilityManager sharedManager] // 檢視網路連線情況
        - [AFHTTPRequestSerializer serializer] // 負責序列化請求
        - [AFJSONResponseSerializer serializer] // 負責序列化響應

從這個初始化方法的呼叫棧,我們可以非常清晰地瞭解這個框架的結構:

  • 其中 AFURLSessionManager 是 AFHTTPSessionManager 的父類

  • AFURLSessionManager 負責生成 NSURLSession 的例項,管理 AFSecurityPolicy 和 AFNetworkReachabilityManager,來保證請求的安全和檢視網路連線情況,它有一個 AFJSONResponseSerializer 的例項來序列化 HTTP 響應

  • AFHTTPSessionManager 有著自己的 AFHTTPRequestSerializer 和 AFJSONResponseSerializer 來管理請求和響應的序列化,同時依賴父類提供的介面保證安全、監控網路狀態,實現發出 HTTP 請求這一核心功能

初始化方法很好地揭示了 AFNetworking 整個框架的架構,接下來我們要通過分析另一個方法 - GET:parameters:process:success:failure: 的呼叫棧,看一下 HTTP 請求是如何發出的:

- [AFHTTPSessionManager GET:parameters:process:success:failure:]
    - [AFHTTPSessionManager dataTaskWithHTTPMethod:parameters:uploadProgress:downloadProgress:success:failure:] // 返回 NSURLSessionDataTask #1
        - [AFHTTPRequestSerializer requestWithMethod:URLString:parameters:error:] // 返回 NSMutableURLRequest
        - [AFURLSessionManager dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:] // 返回 NSURLSessionDataTask #2
            - [NSURLSession dataTaskWithRequest:] // 返回 NSURLSessionDataTask #3
            - [AFURLSessionManager addDelegateForDataTask:uploadProgress:downloadProgress:completionHandler:]
                - [AFURLSessionManagerTaskDelegate init]
                - [AFURLSessionManager setDelegate:forTask:]
    - [NSURLSessionDataTask resume]

在這裡 #1 #2 #3 處返回的是同一個 data task,我們可以看到,在 #3 處呼叫的方法 - [NSURLSession dataTaskWithRequest:] 和只使用 NSURLSession 發出 HTTP 請求時呼叫的方法 - [NSURLSession dataTaskWithRequest:completionHandler:] 差不多。在這個地方返回 data task 之後,我們再呼叫 - resume 方法執行請求,並在某些事件執行時通知代理 AFURLSessionManagerTaskDelegate

小結

AFNetworking 實際上只是對 NSURLSession 高度地封裝, 提供一些簡單易用的 API 方便我們在 iOS 開發中發出網路請求並在其上更快地構建網路層元件並提供合理的介面.

到這裡,這一篇文章從上到下對 AFNetworking 是如何呼叫的進行了一個簡單的概述,我會在隨後的文章中會具體介紹 AFNetworking 中的每一個模組,瞭解它們是如何工作,並且如何合理地組織到一起的。

二. AFNetworking框架使用方法

1.將AFNetworking資料夾匯入工程;

2.新增類庫:Security.framework, MobileCoreServices.framework, SystemConfiguration.framework ;

3. 在使用的類中或者直接在pch預編譯檔案內引入:#import "AFNetworking,h"

解決編譯時警告:

Prefix.pch檔案中加入
#import <SystemConfiguration/SystemConfiguration.h>
#import <MobileCoreServices/MobileCoreServices.h>



注:AFNetWorking使用了ARC ,在不使用ARC專案中使用時,對AFNetWorking的所有.m檔案新增“-fobjc-arc”
    在使用ARC專案中,使用“不使用ARC”的類庫時,對類庫的.m檔案新增“-fno-objc-arc”