1、枚举 HTTPMethod
rawValue
属性值关联
public enum HTTPMethod: String {
case options = "OPTIONS"
case get = "GET"
case head = "HEAD"
case post = "POST"
case put = "PUT"
case patch = "PATCH"
case delete = "DELETE"
case trace = "TRACE"
case connect = "CONNECT"
}
2、单例 SessionManager.default
public static let `default`: SessionManager = {
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders
return SessionManager(configuration: configuration)
}()
3、SessionManager.defaultHTTPHeaders
/// Creates default values for the "Accept-Encoding", "Accept-Language" and "User-Agent" headers.
public static let defaultHTTPHeaders: HTTPHeaders = {
// Accept-Encoding HTTP Header; see https://tools.ietf.org/html/rfc7230#section-4.2.3
let acceptEncoding: String = "gzip;q=1.0, compress;q=0.5"
// Accept-Language HTTP Header; see https://tools.ietf.org/html/rfc7231#section-5.3.5
let acceptLanguage = Locale.preferredLanguages.prefix(6).enumerated().map { index, languageCode in
let quality = 1.0 - (Double(index) * 0.1)
return "\(languageCode);q=\(quality)"
}.joined(separator: ", ")
// User-Agent Header; see https://tools.ietf.org/html/rfc7231#section-5.5.3
// Example: `iOS Example/1.0 (org.alamofire.iOS-Example; build:1; iOS 10.0.0) Alamofire/4.0.0`
let userAgent: String = {
if let info = Bundle.main.infoDictionary {
let executable = info[kCFBundleExecutableKey as String] as? String ?? "Unknown"
let bundle = info[kCFBundleIdentifierKey as String] as? String ?? "Unknown"
let appVersion = info["CFBundleShortVersionString"] as? String ?? "Unknown"
let appBuild = info[kCFBundleVersionKey as String] as? String ?? "Unknown"
let osNameVersion: String = {
let version = ProcessInfo.processInfo.operatingSystemVersion
let versionString = "\(version.majorVersion).\(version.minorVersion).\(version.patchVersion)"
let osName: String = {
#if os(iOS)
return "iOS"
#elseif os(watchOS)
return "watchOS"
#elseif os(tvOS)
return "tvOS"
#elseif os(macOS)
return "OS X"
#elseif os(Linux)
return "Linux"
#else
return "Unknown"
#endif
}()
return "\(osName) \(versionString)"
}()
let alamofireVersion: String = {
guard
let afInfo = Bundle(for: SessionManager.self).infoDictionary,
let build = afInfo["CFBundleShortVersionString"]
else { return "Unknown" }
return "Alamofire/\(build)"
}()
return "\(executable)/\(appVersion) (\(bundle); build:\(appBuild); \(osNameVersion)) \(alamofireVersion)"
}
return "Alamofire"
}()
return [
"Accept-Encoding": acceptEncoding,
"Accept-Language": acceptLanguage,
"User-Agent": userAgent
]
}()
4、return SessionManager(configuration: configuration)
4.1、public let delegate: SessionDelegate
4.2、self.delegate = delegate
4.3、代理移交
public init(
configuration: URLSessionConfiguration = URLSessionConfiguration.default,
delegate: SessionDelegate = SessionDelegate(),
serverTrustPolicyManager: ServerTrustPolicyManager? = nil)
{
self.delegate = delegate
self.session = URLSession(configuration: configuration, delegate: delegate, delegateQueue: nil)
commonInit(serverTrustPolicyManager: serverTrustPolicyManager)
}
5、commonInit(serverTrustPolicyManager: serverTrustPolicyManager)
5.1、delegate.sessionManager = self
5.2、weak var sessionManager: SessionManager?
5.3、后台下载事件,闭包
//SessionManager
private func commonInit(serverTrustPolicyManager: ServerTrustPolicyManager?) {
session.serverTrustPolicyManager = serverTrustPolicyManager
delegate.sessionManager = self
delegate.sessionDidFinishEventsForBackgroundURLSession = { [weak self] session in
guard let strongSelf = self else { return }
DispatchQueue.main.async { strongSelf.backgroundCompletionHandler?() }
}
}
6、Alamofire
进入后台暂停下载,再次进入继续下载
SessionManager.default
.download(self.urlDownloadStr1) { (url, response) -> (destinationURL: URL, options: DownloadRequest.DownloadOptions) in
let documentUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let fileUrl = documentUrl?.appendingPathComponent(response.suggestedFilename!)
return (fileUrl!,[.removePreviousFile,.createIntermediateDirectories])
}
.downloadProgress { (progress) in
print("下载进度 : \(progress)")
}
.response { (downloadResponse) in
print("下载回调信息: \(downloadResponse)")
}
7、全局搜索urlSessionDidFinishEvents
7.1、执行步骤5初始化的delegate.sessionDidFinishEventsForBackgroundURLSession
闭包
7.2、SessionManager
中有open var backgroundCompletionHandler: (() -> Void)?
属性闭包
//extension SessionDelegate: URLSessionDelegate
open func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
sessionDidFinishEventsForBackgroundURLSession?(session)
}
8、解决6的问题
8.1、配置成background。
会遇到Code=-999问题,断了,变量释放了
let configuration = URLSessionConfiguration.background(withIdentifier: "com.lgcooci.backgroundDownload")
let manager = SessionManager(configuration: configuration)
manager
.download(self.urlDownloadStr1) { (url, response) -> (destinationURL: URL, options: DownloadRequest.DownloadOptions) in
let documentUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let fileUrl = documentUrl?.appendingPathComponent(response.suggestedFilename!)
return (fileUrl!,[.removePreviousFile,.createIntermediateDirectories])
}
.downloadProgress { (progress) in
print("下载进度 : \(progress)")
}
.response { (downloadResponse) in
print("下载回调信息: \(downloadResponse)")
}
8.2、临时变量会释放,所以不能使用临时变量,改成全局变量,保存对象
有后台权限问题,解决Appdelegat。-> 回调 Alamofire-系统URLSession中后台下载
但是没有用到Alamofire的闭包回调,所以有了8.3
var manager = SessionManager()
let configuration = URLSessionConfiguration.background(withIdentifier: "com.lgcooci.backgroundDownload")
manager = SessionManager(configuration: configuration)
manager
.download(self.urlDownloadStr1) { (url, response) -> (destinationURL: URL, options: DownloadRequest.DownloadOptions) in
let documentUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let fileUrl = documentUrl?.appendingPathComponent(response.suggestedFilename!)
return (fileUrl!,[.removePreviousFile,.createIntermediateDirectories])
}
.downloadProgress { (progress) in
print("下载进度 : \(progress)")
}
.response { (downloadResponse) in
print("下载回调信息: \(downloadResponse)")
}
manager.backgroundCompletionHandler = {
print("下载完成来了")
}
8.3、最终版本->单例和AppDelegate
//单例
struct DYZBackgroundManger {
static let shared = DYZBackgroundManger()
let manager: SessionManager = {
let configuration = URLSessionConfiguration.background(withIdentifier: "com.lgcooci.AlamofireTest.demo")
configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders
// configuration.timeoutIntervalForRequest = 10
// configuration.timeoutIntervalForResource = 10
// configuration.sharedContainerIdentifier = "group.com.dyz.AlamofireTest"
return SessionManager(configuration: configuration)
}()
}
DYZBackgroundManger.shared.manager
.download(self.urlDownloadStr) { (url, response) -> (destinationURL: URL, options: DownloadRequest.DownloadOptions) in
let documentUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
let fileUrl = documentUrl?.appendingPathComponent(response.suggestedFilename!)
return (fileUrl!,[.removePreviousFile,.createIntermediateDirectories])
}
.downloadProgress { (progress) in
print("下载进度 : \(progress)")
}
.response { (downloadResponse) in
print("下载回调信息: \(downloadResponse)")
}
//AppDelegate
var backgroundSessionCompletionHandler: (() -> Void)?
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
DYZBackgroundManger.shared.manager.backgroundCompletionHandler = completionHandler
}
9、链式
返回自己
10、cURL
终端 输入 curl http://www.baidu.com
html在线解析工具 https://c.runoob.com/front-end/61