Swift - 網絡URLSession

問:Swift的網絡請求怎麼實現? 答:用AFNetworkingAlamofire這些框架啊,快速、好用、數據解析難度低。 是的,第三方網絡框架真的好用,好用到咱們都快忘了原生API是怎麼玩了,但萬丈高樓平地起,原生API咱們仍是有必要掌握的,能讓咱們更容易、更深刻理解AFNetworkingAlamofire等框架,寫這篇文章的目的是對Swift的原生API URLSession的複習api

基本網絡請求:

  • 先作一點準備工做,iOS從9.0版本開始添加了對應用數據傳輸的安全性要求(ATS),咱們在這裏簡單的設置一下關閉ATS
    • info.plist中添加一個key:App Transport Security Settings,類型爲字典;
    • 再在這字典下添加另外一個key:Allow Arbitrary Loads,類型爲Boolean類型,值爲YES
    • 網上對於解決ATS問題的方法有不少,這裏不作贅述;
// Swift簡單網絡請求
let urlString = "http://rap2api.taobao.org/app/mock/228467/api/friend/list"
URLSession.shared.dataTask(with: URL(string: urlString)!) { (data, response, error) in
    if error != nil {
        print("\(String(describing: error))")
    }
    print("\(String(describing: response))")
}.resume()

//OC 網絡請求
NSString *urlString = [NSString stringWithFormat:@"http://rap2api.taobao.org/app/mock/228467/api/friend/list"];
[[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:urlString] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    if (!error) {
        NSLog(@"%@",error);
    }
    NSLog(@"%@", response);
}] resume];
複製代碼
  • resume重啓鏈接網絡請求,默認是掛起狀態,而在AFNetworkingAlamofire中咱們不須要關心這一步,它們已經幫咱們作了這一步的處理;
  • dataTask建立網絡會話任務
    • uploadTask文件上傳任務
    • downloadTask文件下載任務
    • streamTask用於對經過URLSession建立的TCP/IP流執行讀寫操做

網絡請求配置 - Configuration

1、模式
open class var `default`: URLSessionConfiguration { get }

open class var ephemeral: URLSessionConfiguration { get }

@available(iOS 8.0, *)
open class func background(withIdentifier identifier: String) -> URLSessionConfiguration
複製代碼
  • default默認配置,會本地存儲憑據、緩存和cookie
  • ephemeral臨時會話,不會將cookie、緩存或憑據儲存到本地只會放到內存中,當應用程序退出後數據也會消失,能夠用於實現「祕密瀏覽」;
  • background創建後臺會話,能夠在應用程序掛起、退出、崩潰的狀況下運行上傳和下載任務,後臺另起一個線程。另外,系統會根據設備的負載程度決定分配下載的資源,所以有可能會很慢甚至超時失敗;
    • background須要有一個惟一標識符identifier用於標識任務

後臺執行任務的時候注意點緩存

  • 蘋果官方文檔提供的後臺任務的四步操做
//Listing 1 Creating a background URL session
private lazy var urlSession: URLSession = {
    let config = URLSessionConfiguration.background(withIdentifier: "MySession")
    config.isDiscretionary = true
    config.sessionSendsLaunchEvents = true
    return URLSession(configuration: config, delegate: self, delegateQueue: nil)
}()

//Listing 2 Creating a download task from a URL session
let backgroundTask = urlSession.downloadTask(with: url)
backgroundTask.earliestBeginDate = Date().addingTimeInterval(60 * 60)
backgroundTask.countOfBytesClientExpectsToSend = 200
backgroundTask.countOfBytesClientExpectsToReceive = 500 * 1024
backgroundTask.resume()

//Listing 3 Storing the background download completion handler sent to the application delegate
var backgroundCompletionHandler: (() -> Void)?
func application(_ application: UIApplication,
                 handleEventsForBackgroundURLSession identifier: String,
                 completionHandler: @escaping () -> Void) {
    backgroundCompletionHandler = completionHandler
}

//Listing 4 Executing the background URL session completion handler on the main queue
func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
    DispatchQueue.main.async {
        guard let appDelegate = UIApplication.shared.delegate as? AppDelegate,
            let backgroundCompletionHandler =
            appDelegate.backgroundCompletionHandler else {
                return
        }
        backgroundCompletionHandler()
    }
}
複製代碼
  • 給咱們的信息是後臺任務建立並執行還不夠,還須要開啓權限
  • 在任務完成,系統將執行在AppDelegate中保存的閉包backgroundCompletionHandler回調,更新屏幕

PS: 官方文檔查看方法: 安全

2、請求緩存策略
public enum CachePolicy : UInt {
   //默認策略
   case useProtocolCachePolicy 
   //指定應從原始源加載URL加載的數據, 沒有本地緩存數據
   case reloadIgnoringLocalCacheData 
   //指定不只應忽略本地緩存數據,並且應指示代理和其餘中間人在協議容許的狀況下忽略其緩存。未實現
   case reloadIgnoringLocalAndRemoteCacheData
   //與reloadIgnoringLocalCacheData相同
   public static var reloadIgnoringCacheData: NSURLRequest.CachePolicy { get }
    //指定應使用現有緩存數據來知足URL加載請求,無論其生命週期或到期日期。 可是,若是緩存中沒有與URL加載請求相對應的現有數據,則從原始源加載URL
   case returnCacheDataElseLoad
   //指定應使用現有緩存數據來知足URL加載請求,無論其生命週期或到期日期。 可是,若是緩存中沒有與URL加載請求相對應的現有數據,則不會嘗試從源源加載URL,而且認爲加載失敗。 此常量指定相似於「脫機」模式的行爲。
   case returnCacheDataDontLoad
   //指定可使用現有緩存數據,前提是源源確認其有效性,不然從原始源加載URL。未實現。
   case reloadRevalidatingCacheData
}
複製代碼
3、經常使用的屬性
  • identifier後臺會話標識符
  • timeoutIntervalForRequest請求超時,若是在設定的超時時間內沒有傳輸數據,將致使超時,而且每當傳輸數據時都會重置。
  • timeoutIntervalForResource請求超時。 若是在給定超時內沒法檢索到資源,則會致使超時。
  • networkServiceType網絡服務類型
  • allowsCellularAccess是否容許蜂窩網絡
  • waitsForConnectivity任務等待網絡鏈接是否可用,後臺會話時會忽略,由於後臺會話始終等待鏈接。
4、安全策略
  • TLSMinimumSupportedProtocol容許最小TLS協議版本
  • TLSMaximumSupportedProtocol容許最大TLS協議版本
  • urlCredentialStorage存儲身份驗證憑證的庫
5、HTTP策略、代理屬性
  • HTTPShouldUsePipelining容許使用HTTP流水線
  • HTTPMaximumConnectionsPerHost給定主機的最大併發持久鏈接數
6、Cookie設置
  • HTTPShouldSetCookies是否容許請求包含一個Cookie庫中的Cookie
  • HTTPCookieAcceptPolicy肯定什麼時候接受Cookie策略
  • HTTPCookieStorage 保存當前會話的 Cookie的庫

這裏只是介紹了SwiftURLSession中一些基本的屬性的用途,關於URLSessionDataTask作另外一篇章來說。bash

PS:鄙人小小碼農一枚,限於能力,官方文檔或許理解有誤,文章中有錯誤、不足之處,歡迎各位大神指正。cookie

相關文章
相關標籤/搜索