相信所有的早期的iOS开发者都知道ASIHTTPRequest,然后知道了AFNetworking,方便性和实用性得到了大大的提高,成为了大家都在用的网络请求库。有了Swift后,AFNetworking的Swift版本Alamofire也应运而生,从这篇文章开始,慢慢的接触Alamofire。
先看一个简单的Swift版本原生的网络请求:
let urlStr = "https://www.apiopen.top/satinGodApi?type=1&page=1"
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
urlSessionTest()
}
func urlSessionTest() {
URLSession.shared.dataTask(with: URL(string: urlStr)!) { (data, response, error) in
if error == nil {
print("拿到数据:\(String(describing: response))")
}
}.resume()
}
再来一个下载视频的请求:
let videoUrlStr="https://cache.fotoplace.cc/181114/13404389/3832bf181a42f3b372156659dac6b731.mp4"
URLSession.shared.downloadTask(with: URL(string: videoUrlStr)!) { (url, response, error) in
if error == nil {
print("视频下载完成的地址:\n\(String(describing: url))")
do {
try FileManager.default.moveItem(at: url!, to: URL(fileURLWithPath: NSHomeDirectory().appending("/Documents/video.mp4")))
} catch {
}
}
}.resume()
开始下载的时候我们可以进入到沙盒看到一个临时的下载文件:
开始下载tmp.png
下载完成后根据代码可以在
Documents文件夹里看到:
下载完成移动后.png
一般情况下下载视频这种的会监听下载进度,直接上图示例:
带进度的下载.png
代码中有一个
URLSessionConfiguration.background这个玩意,点击去直接看源码:
open class URLSessionConfiguration : NSObject, NSCopying {
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、ephemeral和background。default就是默认的模式,会有一个持久的缓存容器,保存证书,两边有特殊的符号是表示取消这个default关键字。ephemeral没有持久的缓存容器,当session无效的时候就自动销毁。background顾名思义就是可以创建一个在后台甚至APP应关闭的时候仍可以下载数据的会话。
要想支持后台下载需要再AppDelegate文件中实现:
var window: UIWindow?
var backgroundSessionCompletionHandler:(() -> Void)?
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
self.backgroundSessionCompletionHandler=completionHandler
}
仅仅这样的确是支持了后台下载,但是是非常不友好的,去苹果的文档里查看:
完成告诉系统.png
也就是说当我们完成了自己的后台下载任务后一定要告诉系统我们完成了,要不然就会造成资源的浪费,性能的消耗。那如何来告诉系统的,URLSessionDownloadDelegate里面系统提供了方法
urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession):
extension ViewController:URLSessionDownloadDelegate {
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
try! FileManager.default.moveItem(at: location, to: URL(fileURLWithPath: NSHomeDirectory().appending("/Documents/video.mp4")))
}
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
print("=====> \(Double(totalBytesWritten)/Double(totalBytesExpectedToWrite))\n")
}
func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
DispatchQueue.main.async {
guard let appDele = UIApplication.shared.delegate as? AppDelegate, let backgroundHandle=appDele.backgroundSessionCompletionHandler else {return}
backgroundHandle()
}
}
}
大家都知道TCP的开始需要三次握手的,断开时候需要四次挥手的,如何能直观的看到,这里使用WireShark捕捉一下:
三次握手.png
四次挥手.png
三次握手.jpg
四次挥手.jpg
说了这么多,下面正式使用Alamofire来个请求:
func alamofireRequest() {
AF.request(urlStr)
.responseJSON { (response) in
print(response)
}
}
就是这么简单粗暴,链式的语法非常的方便使用。点进去直接看下源码:
public static func request(_ url: URLConvertible,
method: HTTPMethod = .get,
parameters: Parameters? = nil,
encoding: ParameterEncoding = URLEncoding.default,
headers: HTTPHeaders? = nil,
interceptor: RequestInterceptor? = nil) -> DataRequest {
return Session.default.request(url,
method: method,
parameters: parameters,
encoding: encoding,
headers: headers,
interceptor: interceptor)
}
我们只传了url其他的请求参数不用传,因为本来就是个get请求,也没有请求头的限制,全部用默认的就好了。有个参数类型是URLConvertible类型的,这个东西是什么鬼,继续深入:
/// Types adopting the `URLConvertible` protocol can be used to construct `URL`s, which can then be used to construct
/// `URLRequests`.
public protocol URLConvertible {
/// Returns a `URL` from the conforming instance or throws.
///
/// - Returns: The `URL` created from the instance.
/// - Throws: Any error thrown while creating the `URL`.
func asURL() throws -> URL
}
原来是一个协议,可以方便的把其他各种类型实现一个asURL方法转变为一个URL的类型。今天就先带着大家入个门,后面再详解!!!











网友评论