原码解读:https://www.cnblogs.com/machao/p/6640248.html?utm_source=tuicool&utm_medium=referral
官网:https://github.com/Alamofire/Alamofire/blob/master/Documentation/Usage.md#http-methods
=============序列化=解析数据====================================
1.**********************IOS系统的序列化器,吧JSON字符串解析成JSON对象(字典)
//1.这是一个JSON字符串
let jsonStr ="[{\"name\": \"hangge\", \"age\": 100, \"phones\": [{\"name\": \"公司\",\"number\": \"123456\"}, {\"name\": \"家庭\",\"number\": \"001\"}]}, {\"name\": \"big boss\",\"age\": 1,\"phones\": [{ \"name\": \"公司\",\"number\": \"111111\"}]}]"
//2.吧JSON字符串变成data数据
if let jsonData = jsonStr.data(using:String.Encoding.utf8, allowLossyConversion:false)
do{
//3.吧jsondata转换成JSON对象(即字典,或字典数组)
let dictArr:[[String:Any]]=try? JSONSerialization.jsonObject(with:jsonData,options:.allowFragments)as?[[String :Any]]或者下面
if let dictArr:[[String:Any]]=(try JSONSerialization.jsonObject(with:jsonData,options:.allowFragments)as?[[String :Any]]) {
let phones = dictArr[0]["phones"]as?[[String:Any]]
if let name = phones![0]["name"]as?String{
print("\(name)")
}
}
}
catch{
}
}
=================SwiftJson是Swift 界 JSON 解析之王(不是字典转模型)。=============
下载地址:https://github.com/SwiftyJSON/SwiftyJSON
coacaopods导入SwiftJson框架;
在工程中导入第三方的头文件时,会报以下的错误:cannot load underlying module for ‘***’
这个问题出现的原因还是因为podfile文件,你需要在文件里再加上一句话 source 'https://github.com/CocoaPods/Specs.git'
如果还是这样,需要在LinkFrameworkAndLibrary中加入SwiftFramework.frame work
2.//**************swiftyjson吧JSON字符串解析成JSON对象(字典)******************不用担心数组越界,不用判断节点,拆包什么的
do{
let json = try JSON(data: jsonData, options:.allowFragments)
if let number = json[0]["phones"][0]["number"].string {
// 找到电话号码
print("第一个联系人的第一个电话号码:",number)
}else {
// 打印错误信息
print(json[0]["phones"][0]["number"])
}
}catch{
}
****************************基础使用*******************************
===========HTTP Headers请求头的设置:在请求中作为参数添加Headers配置、在session中添加Headers配置、URLRequest的headers添加配置
.*******在请求中作为参数添加配置*********
客户端每发起一次HTTP请求,请求头信息是必不可少的。这也是同服务器交流的一种手段,在实际的开发中,也肯定会遇到需要自定义请求头的需求,在Alamofire中如何设置请求头:
以字典的形式创建请求头:
let headers: HTTPHeaders = [
"Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==",
"Accept": "application/json"
]
以数组的请示创建请求头:
let headers: HTTPHeaders = [
.authorization(username: "Username", password: "Password"),
.accept("application/json")
]
Alamofire.request("https://httpbin.org/headers", headers: headers).responseJSON { response in
debugPrint(response)
}
在request(...)函数中,存在headers这么一个参数,我们只要传入提前写好的字典就行了。
*********在session中添加Header配置*************
let configuration = URLSessionConfiguration.af.default
let headers:HTTPHeaders = ["auth": "lambo"]
configuration.headers=headers
configuration.httpAdditionalHeaders = [
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "application/vnd.lichess.v1+json",
"X-Requested-With": "XMLHttpRequest",
"User-Agent": "iMchess"
]
let session = Session(configuration: configuration)
*********URLRequest的headers添加配置**********
let url = URL(string: "http://localhost:8080/login")!
var urlRequest = URLRequest(url: url)
urlRequest.headers.add(.contentType("application/json"))//方式一
urlRequest.setValue("lambo", forHTTPHeaderField: "Authorization")//方式二
AF.request(urlRequest).responseString{response in
}
//带请求头参数
class func requestWithHeader(){
struct Login: Encodable {
let username: String
let password: String
}
let login = Login(username: "lambo", password: "123")
let headers: HTTPHeaders = [
.authorization(username: "Username", password: "Password"),
.accept("application/json")
]
AF.request("http://localhost:8080/regist",
method: .post,
parameters: login,
encoder: JSONParameterEncoder.default,headers:headers).response { response in
switch response.result {
case .success:
// debugPrint(response)
//这里是response接收。返回的是data数据
let dict = try? JSONSerialization.jsonObject(with: response.value!!, options: JSONSerialization.ReadingOptions.allowFragments)as? [String:String]
let username=dict!["username"]
print("\(String(describing: username))")
debugPrint(username as Any)
case let .failure(error):
print(error)
}
}
}
======请求的结果类型=====
returnResult.request:
Optional(http://localhost:8080/login)
returnResult.result:
success({
username = lam;
})
returnResult.value:
responseJSON接收:
Optional({
username = lam;
})
response接收:
Optional(18 bytes)
解析:如果是json格式的,就强制转成字典[:]
let json = returnResult.value! as! [String:String]
print("result\(json["username"] )")
returnResult.data:
Optional(18 bytes)
解析:data转成json格式,然后转成字典[:]
let json = try? JSONSerialization.jsonObject(with: returnResult.data!, options: JSONSerialization.ReadingOptions.allowFragments)as? [String:String]
let username=json!["username"]
returnResult.response:
Optional(<NSHTTPURLResponse: 0x600001e45460> { URL: http://localhost:8080/login } { Status Code: 200, Headers {
Connection = (
"keep-alive"
);
"Content-Type" = (
"application/json"
);
Date = (
"Sat, 30 Jan 2021 12:16:42 GMT"
);
"Keep-Alive" = (
"timeout=60"
);
"Transfer-Encoding" = (
Identity
);
Vary = (
Origin,
"Access-Control-Request-Method",
"Access-Control-Request-Headers"
);
} })
=====Response Validation请求结果过滤验证====
//返回结果带validate验证
class func responsewithvalidate(){
AF.request("http://localhost:8080/regist")
.validate(statusCode: 200..<300)//如果返回的statuscode在这个返回内才会走.success中
.validate(contentType: ["application/json"])
.responseData { response in
switch response.result {
case .success:
let dict = try? JSONSerialization.jsonObject(with: response.value!, options: JSONSerialization.ReadingOptions.allowFragments)as? [String:String]
let username=dict!["username"]
print("\(String(describing: username))")
debugPrint(username as Any)
print("Validation Successful")
case let .failure(error):
print(error)
}
}
}
=====Authentication请求身份验证====
有URLCredential(url资格验证)
and URLAuthenticationChallenge两种
//在header中添加authorization验证方式一
class func requestWithHTTPBasicAuthenticationone(){
let username = "username"
let password = "password"
let param = ["username":"lambo","password":"123456"]
let headers: HTTPHeaders = [.authorization(username: username, password: password)]
AF.request("http://localhost:8080/regist", method: .post,parameters: param, headers: headers)
.responseJSON { response in
switch response.result {
case .success:
//获取value(也是就后台传递的json数据),然后直接强转成字典
let dict = response.value! as! [String:String]
print("result\(String(describing: dict["username"]) )")
print("Validation Successful")
case let .failure(error):
print(error)
}
}
}
//authorization验证方式二
class func requestWithHTTPBasicAuthenticationtwo(){
let user = "user"
let password = "password"
AF.request("http://localhost:8080/regist/\(user)/\(password)")
.authenticate(username: user, password: password)
.responseJSON { response in
switch response.result {
case .success:
//获取value(也是就后台传递的json数据),然后直接强转成字典
let dict = response.value! as! [String:String]
print("result\(String(describing: dict["username"]) )")
print("Validation Successful")
case let .failure(error):
print(error)
}
}
}
//authorization验证方式三
class func requestWithHTTPBasicAuthenticationthree(){
let user = "user"
let password = "password"
let credential = URLCredential(user: user, password: password, persistence: .forSession)
AF.request("http://localhost:8080/regist/\(user)/\(password)")
.authenticate(with: credential)
.responseJSON { response in
switch response.result {
case .success:
//获取value(也是就后台传递的json数据),然后直接强转成字典
let dict = response.value! as! [String:String]
print("result\(String(describing: dict["username"]) )")
print("Validation Successful")
case let .failure(error):
print(error)
}
}
}
===响应的方式,六种
//response接收返回数据,返回的是data数据,需要反序列化成json,然后转成字典。
//response接收返回数据
class func requestAndresponse() {
let param = ["username":"lambo","password":"123456"]
AF.request("http://localhost:8080/regist", method: .post, parameters: param).response { response in
switch response.result {
case .success:
//这里是response接收。返回的是data数据
let dict = try? JSONSerialization.jsonObject(with: response.value!!, options: JSONSerialization.ReadingOptions.allowFragments)as? [String:String]
let username=dict!["username"]
print("\(String(describing: username))")
case let .failure(error):
print(error)
}
}
}
//--responseJSON接收结果,返回的是json格式。可以接收data类型数据然后反序列化成json再转成字典;也可以直接接收json然后强转成字典。
//responseJSON接收结果
class func requestAndresponseJSON() {
// let param = [String:String]()
let param = ["username":"lambo"]
AF.request(urlstr, method: .post, parameters: param).responseJSON { (response) in
// 这里responseJSON接收,返回的是json格式的数据
/* 返回请求地址、数据、和状态结果等信息
数据 returnResult.data!----
returnResult.value ---
结果转成字符串 String(data: returnResult.data ?? NSData.init() as Data, encoding: .utf8)
*/
//获取data,然后转成字典
// let dict = try? JSONSerialization.jsonObject(with: returnResult.data!, options: JSONSerialization.ReadingOptions.allowFragments)as? [String:String]
// let username=dict!["username"]
// print("\(returnResult.data)")
switch response.result {
case .success:
//获取value(也是就后台传递的json数据),然后直接强转成字典
let dict = response.value! as! [String:String]
print("result\(String(describing: dict["username"]) )")
print("Validation Successful")
case let .failure(error):
print(error)
}
}
}
//responseData接收返回结果;
//responseData接收返回结果
class func requestAndresponseData(){
let param = ["username":"lambo"]
AF.request("http://localhost:8080/regist",method: .post,parameters: param)
.responseData { response in
//response.value返回的是data
switch response.result {
case .success:
let dict = try? JSONSerialization.jsonObject(with: response.value!, options: JSONSerialization.ReadingOptions.allowFragments)as? [String:String]
let username=dict!["username"]
print("\(String(describing: username))")
debugPrint(username as Any)
print("Validation Successful")
case let .failure(error):
print(error)
}
}
}
//responseString接收返回结果
//responseString接收返回结果
class func requestAndresponseString(){
let param = ["username":"lambo"]
AF.request("http://localhost:8080/regist",method: .post,parameters: param)
.responseString{ response in
//response.value返回的是json字符串,要先转成data,再转成字典
switch response.result {
case .success:
let dataValue: Data = response.value!.data(using: String.Encoding(rawValue: String.Encoding.utf8.rawValue), allowLossyConversion: true)! as Data//字符串转data
let dict = try? JSONSerialization.jsonObject(with: dataValue, options: JSONSerialization.ReadingOptions.allowFragments)as? [String:String]
let username=dict!["username"]
print("\(String(describing: username))")
debugPrint(username as Any)
print("Validation Successful")
case let .failure(error):
print(error)
}
}
}
//responseDecodable接收返回结果
//responseDecodable接收返回结果
class func requestAndDecodable(){
let param = ["username":"lambo"]
struct HTTPBinResponse: Decodable {
//这里设置的字段要和后台返回的字段一样,否则就报错
let username: String
let password:String
}
AF.request("http://localhost:8080/regist", method: .post,parameters: param).responseDecodable(of: HTTPBinResponse.self) { response in
switch response.result {
case .success:
//这里response.value返回的就是response.value结构体,直接.获取属性
let dict = response.value
print("\(String(describing: dict?.username))")
print("Validation Successful")
case let .failure(error):
print(error)
}
}
}
//设置队列,在子线程执行闭包
//设置队列
class func requestAndQueue(){
// 默认情况下,传递给响应处理程序的闭包在.main队列上执行;但有时需要在子线程执行
let utilityQueue = DispatchQueue.global(qos: .utility)
AF.request("http://localhost:8080/regist").responseJSON(queue: utilityQueue) { response in
switch response.result {
case .success:
//获取value(也是就后台传递的json数据),然后直接强转成字典
let dict = response.value! as! [String:String]
print("result\(String(describing: dict["username"]) )")
print("Validation Successful")
case let .failure(error):
print(error)
}
}
}
========上传==========
Alamofire:Uploading Multipart Form Data表单上传URL,//@RequestParam("file") MultipartFile file 和 HttpServletRequest request都可以接收表单数据,如果使用@RequestParam("file") MultipartFile file的话,就要和Alammofire传递的withName一致
func uploadFormdataWithfileURL(){
let fileURL = Bundle.main.url(forResource: "lunbothree", withExtension: "png")//图片的URL
let data = UIImage.init(named: "003")?.pngData()//图片的Data数据
AF.upload(multipartFormData: { multipartFormData in
/*
fileURL:上传的文件路径,URL类型
withName:后台接收文件的字段名
fileName:文件的原始名称,后台接收到就是这个名称
mimeType:文件类型
*/
multipartFormData.append(fileURL!, withName: "file",fileName:"lunbo.png",mimeType: "image/png")// URL上传图片
}, to: urlstr)
.responseString{ response in
print("\(response.value)")
}
}
Alamofire:Uploading Multipart Form Data表单上传Data,//@RequestParam("file") MultipartFile file 和 HttpServletRequest request都可以接收表单数据,如果使用@RequestParam("file") MultipartFile file的话,就要和Alammofire传递的withName一致
func uploadFormdataWithdata(){
let data = UIImage.init(named: "003")?.pngData()//图片的Data数据
AF.upload(multipartFormData: { multipartFormData in
/*
fileURL:上传的文件路径,URL类型
withName:后台接收文件的字段名
fileName:文件的原始名称,后台接收到就是这个名称
mimeType:文件类型
*/
multipartFormData.append(data!, withName: "file",fileName:"lunbo.png",mimeType: "image/png")//Data上传图片\
multipartFormData.append(data, withName: "file")//这个在后台就获取不到原始的名称
}, to: urlstr)
.responseString{ response in
print("\(response.value)")
}
}
Alamofire:Uploading Multipart Form Data表单上传多张图片,有Data、URL、其他数据类型,//@RequestParam("file") MultipartFile file 和 HttpServletRequest request都可以接收表单数据,如果使用@RequestParam("file") MultipartFile file的话,就要和Alammofire传递的withName一致
func uploadFormdataWithMuti(){
let data = (UIImage.init(named: "003")?.pngData())!
let dict=["age":"18"]
let dictdata = (try? JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted))!
let fileURL = Bundle.main.url(forResource: "lunbothree", withExtension: "png")!
AF.upload(multipartFormData: { multipartFormData in
/*
fileURL:上传的文件路径,URL类型
withName:后台接收文件的字段名
fileName:文件的原始名称,后台接收到就是这个名称
mimeType:文件类型
*/
multipartFormData.append(data, withName: "file",fileName:"lunbo.png",mimeType: "image/png")
multipartFormData.append(fileURL, withName: "file",fileName:"lunbo1.png",mimeType: "image/png")
multipartFormData.append(dictdata, withName: "age")//携带其他数据,这个数据必须能转化成NSData
}, to: urlstr)
.responseString{ response in
print("\(String(describing: response.value))")
}
}
Uploading Data上传NSData数据,这里传递其他参数要用url拼接的形式,后台接收用InputStream stream接收图片流,HttpServletRequest request接收其他参数
func uploadData(){
let data = UIImage.init(named: "003")?.pngData()
AF.upload(data!, to: "http://localhost:8080/uploadimage?age=18").responseString{response in
debugPrint(response)
}
}
Uploading a File上传一个URL,后台接收用InputStream stream接收图片流,HttpServletRequest request接收其他参数
func uploadFile(){
let fileURL = Bundle.main.url(forResource: "lunbothree", withExtension: "png")
AF.upload(fileURL!, to:"http://localhost:8080/uploadimage?age=18").responseString{ response in
debugPrint(response)
}
}
Upload Progress上传数据带进度,后台接收用InputStream stream接收图片流,HttpServletRequest request接收其他参数
func uploadWithprogress(){
let fileURL = Bundle.main.url(forResource: "lunbothree", withExtension: "png")!
AF.upload(fileURL, to: "http://localhost:8080/uploadimage?age=18")
.uploadProgress { progress in
print("Upload Progress: \(progress.totalUnitCount)----\(progress.completedUnitCount)")
}
.downloadProgress { progress in
print("Download Progress:\(progress.totalUnitCount)----\(progress.completedUnitCount)")
}
.responseString{ response in
debugPrint(response)
}
}
========下载==========
基础下载
//基础下载
func downloadtofile(){
let urlstr="https://bkimg.cdn.bcebos.com/pic/c2cec3fdfc039245b3888b558e94a4c27d1e25ae?x-bce-process=image/resize,m_lfit,w_268,limit_1/format,f_jpg"//这是一个图片地址
AF.download(urlstr).responseURL{ [self] response in
debugPrint(response.fileURL!.path as String)
//从下临时的图片地址获取图片数据
//这个是下载下来的图片的临时存储地址,是一个file://XXX.temp文件,使用的时候需要吧file://去除掉,最好移动到一个能长久保存的地方
var filestr=response.value!.absoluteString as String
let startIndex = filestr.index(filestr.startIndex, offsetBy: 0)
let endIndex = filestr.index(filestr.startIndex, offsetBy: 6)
filestr.removeSubrange(startIndex...endIndex)
// imagev.image=UIImage.init(contentsOfFile: filestr)
//copy图片临时地址到新的地址
let documentPath = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory,FileManager.SearchPathDomainMask.userDomainMask,true).last
let endfile=documentPath?.appending("/image.png")
let filemanger=FileManager.init()
try? filemanger.copyItem(atPath: filestr, toPath: endfile!)
imagev.image = UIImage.init(contentsOfFile: endfile!)
//通过response.fileURL?.path获取图片路径,response.value!.absoluteString也是获取图片路径,但是要把前面的file://前缀去掉
if response.error == nil, let imagePath = response.fileURL?.path {
let image = UIImage(contentsOfFile: imagePath)
imagev.image=image
}
}
}
下载到目标设置,有设置
//下载到目标地址带设置
func downloadFileDestinationone(){
let urlstr="https://bkimg.cdn.bcebos.com/pic/c2cec3fdfc039245b3888b558e94a4c27d1e25ae?x-bce-process=image/resize,m_lfit,w_268,limit_1/format,f_jpg"//这是一个图片地址
//定义下载的目标地址和设置
let destination: DownloadRequest.Destination = { _, _ in
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let fileURL = documentsURL.appendingPathComponent("image2.png")
return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}
AF.download(urlstr, to: destination).response { [weak self] response in
debugPrint(response)
if response.error == nil, let imagePath = response.fileURL?.path {
let image = UIImage(contentsOfFile: imagePath)
self!.imagev.image=image
}
}
}
下载到目标地址,默认设置
//下载到目标地址,默认配置
func downloadFileDestinationtwo(){
let urlstr="https://bkimg.cdn.bcebos.com/pic/c2cec3fdfc039245b3888b558e94a4c27d1e25ae?x-bce-process=image/resize,m_lfit,w_268,limit_1/format,f_jpg"//这是一个图片地址
let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory)
AF.download(urlstr, to: destination).response{ [weak self]
response in
if response.error == nil, let imagePath = response.fileURL?.path {
let image = UIImage(contentsOfFile: imagePath)
self!.imagev.image=image
}
}
}
下载进度
//下载带进度
func downloadProgress(){
let urlstr="https://bkimg.cdn.bcebos.com/pic/c2cec3fdfc039245b3888b558e94a4c27d1e25ae?x-bce-process=image/resize,m_lfit,w_268,limit_1/format,f_jpg"//这是一个图片地址
AF.download(urlstr)
.downloadProgress { progress in
print("Download Progress: \(progress.fractionCompleted)")
}
.responseData { [weak self] response in
//这里用responsData接收,response.value就是data二进制数据
if let data = response.value {
let image = UIImage(data: data)
self!.imagev.image=image
}
}
}
下载设置队列
//下载设置队列
func downloadProgressQueue(){
let urlstr="https://bkimg.cdn.bcebos.com/pic/c2cec3fdfc039245b3888b558e94a4c27d1e25ae?x-bce-process=image/resize,m_lfit,w_268,limit_1/format,f_jpg"//这是一个图片地址
let progressQueue = DispatchQueue(label: "com.alamofire.progressQueue", qos: .utility)
AF.download(urlstr)
.downloadProgress(queue: progressQueue) { progress in
print("Download Progress: \(progress.fractionCompleted)")
}
.responseData {[weak self] response in
if let data = response.value {
let image = UIImage(data: data)
self!.imagev.image=image
}
}
}
Canceling and Resuming a Download取消下载和继续下载
var resumeData: Data!
let download = AF.download(urlstr).responseData { response in
if let data = response.value {
let image = UIImage(data: data)
}
}
// download.cancel(producingResumeData: true) // Makes resumeData available in response only.
download.cancel { data in
resumeData = data
}
AF.download(resumingWith: resumeData).responseData { response in
if let data = response.value {
let image = UIImage(data: data)
}
}
//Streaming Data from a Server流的方式下载,不会存储在内存或者磁盘中,不会积累数据
和普通的请求有点类似,还有其他几种接收数据的方式,如responseStreamString,responseStreamDecodable,
func downloadwithstream(){
let urlstr="https://bkimg.cdn.bcebos.com/pic/c2cec3fdfc039245b3888b558e94a4c27d1e25ae?x-bce-process=image/resize,m_lfit,w_268,limit_1/format,f_jpg"//这是一个图片地址
AF.streamRequest(urlstr).responseStream{ [weak self]stream in
switch stream.event {
case let .stream(result):
switch result {
case let .success(data):
print(data)
//需要流数据全部存储下来,才能使用
}
case let .complete(completion):
print(completion)
}
}
}
========有关参数设置========
带有超时参数:
//带有超时参数设置 requestModifier: { $0.timeoutInterval = 5 }
class func requestDatawithtimeout(){
let param = ["username":"lambo","password":"123456"]
AF.request("http://localhost:8080/regist", method: .post, parameters: param, requestModifier: { $0.timeoutInterval = 5 }).response { response in
switch response.result {
case .success:
//这里是response接收。返回的是data数据
let dict = try? JSONSerialization.jsonObject(with: response.value!!, options: JSONSerialization.ReadingOptions.allowFragments)as? [String:String]
let username=dict!["username"]
print("\(String(describing: username))")
case let .failure(error):
print(error)
}
}
}
或者在闭包里面添加超时参数:
AF.request("http://localhost:8080/regist") { urlRequest in
urlRequest.timeoutInterval = 5
urlRequest.allowsConstrainedNetworkAccess = false
}
.response(...)
参数编码:有两种编码方式JSONParameterEncoder和URLEncodedFormParameterEncoder
//带编码方式的参数,直接把结构体实例化,然后编码作为参数,具体的参数编码有很多设置,不同类型的参数有不同的设置具体参考github
class func requestWithEcode(){
struct Login: Encodable {
let username: String
let password: String
}
let login = Login(username: "lambo", password: "123")
AF.request("http://localhost:8080/regist",
method: .post,
parameters: login,
encoder: JSONParameterEncoder.default).response { response in
switch response.result {
case .success:
debugPrint(response)
//这里是response接收。返回的是data数据
let dict = try? JSONSerialization.jsonObject(with: response.value!!, options: JSONSerialization.ReadingOptions.allowFragments)as? [String:String]
let username=dict!["username"]
print("\(String(describing: username))")
debugPrint(username as Any)
case let .failure(error):
print(error)
}
}
}
=======Response Caching缓存======
有内存和磁盘缓存
==============高级使用======================
Session的创建方式
//方式一 default
let session = Session.default
//方式二 startRequestsImmediately
let session1 = Session(startRequestsImmediately: false)
//方式三 URLSessionConfiguration
let configuration = URLSessionConfiguration.af.default
configuration.allowsCellularAccess = false
let session2 = Session(configuration: configuration)
//SessionDelegate
let delegate = SessionDelegate(fileManager: .default)
//方式四 Session’s DispatchQueues
let rootQueue = DispatchQueue(label: "com.app.session.rootQueue")
let requestQueue = DispatchQueue(label: "com.app.session.requestQueue")
let serializationQueue = DispatchQueue(label: "com.app.session.serializationQueue")
let session3 = Session(rootQueue: rootQueue,
requestQueue: requestQueue,
serializationQueue: serializationQueue)
//方式五 Adding a RequestInterceptor
let policy = RetryPolicy()
let session4 = Session(interceptor: policy)
//方式六 Adding a ServerTrustManager
let manager = ServerTrustManager(evaluators: ["httpbin.org": PinnedCertificatesTrustEvaluator()])
let session5 = Session(serverTrustManager: manager)
//方式七 Adding a RedirectHandler
let redirector = Redirector(behavior: .follow)
let session6 = Session(redirectHandler: redirector)
//方式八 Adding a CachedResponseHandler
let cacher = ResponseCacher(behavior: .cache)
let session7 = Session(cachedResponseHandler: cacher)
//方式九 Adding EventMonitors
let monitor = ClosureEventMonitor()
monitor.requestDidCompleteTaskWithError = { (request, task, error) in
debugPrint(request)
}
let session8 = Session(eventMonitors: [monitor])
//方式十
let rootQueue1 = DispatchQueue(label: "org.alamofire.customQueue")
let queue = OperationQueue()
queue.maxConcurrentOperationCount = 1
queue.underlyingQueue = rootQueue
let delegate1 = SessionDelegate()
let configuration1 = URLSessionConfiguration.af.default
let urlSession = URLSession(configuration: configuration1,
delegate: delegate1,
delegateQueue: queue)
let session9 = Session(session: urlSession, delegate: delegate, rootQueue: rootQueue)
//方式十一log
let logger = Logger()
let session = Session(eventMonitors: [logger])
Session可以替换AF来请求、上传、下载,用法和AF一模一样,只要把AF替换成session,Session还以有设置URLSessionConfiguration,URLSessionConfiguration中可以设置httpAdditionalHeaders等一些配置。
func requestWithsession(){
//
let configuration = URLSessionConfiguration.af.default
configuration.allowsCellularAccess = false
let session = Session(configuration: configuration)
session.request("http://localhost:8080/regist",method: .post).responseString{response in
}
//
let data = (UIImage.init(named: "003")?.pngData())!
session.upload(data, to: "http://localhost:8080/uploadimage",method: .post).responseString{response in
}
//
session.download("http://localhost:8080/erweima.png").responseString{response in
}
//
let urlstr="https://bkimg.cdn.bcebos.com/pic/c2cec3fdfc039245b3888b558e94a4c27d1e25ae?x-bce-process=image/resize,m_lfit,w_268,limit_1/format,f_jpg"//这是一个图片地址
session.streamRequest(urlstr).responseStream{ [weak self]stream in
switch stream.event {
case let .stream(result):
switch result {
case let .success(data):
print(data)
//需要流数据全部存储下来,才能使用
}
case let .complete(completion):
print(completion)
}
}
}
URLSessionConfiguration的配置
let configuration = URLSessionConfiguration.af.default
configuration.allowsCellularAccess = false
let headers:HTTPHeaders = ["auth": "lambo"]
configuration.headers=headers
configuration.httpAdditionalHeaders = [
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "application/vnd.lichess.v1+json",
"X-Requested-With": "XMLHttpRequest",
"User-Agent": "iMchess"
]
configuration.allowsConstrainedNetworkAccess=false
configuration.allowsExpensiveNetworkAccess=true
//有一个比较巧妙的用法,可以通过设置为空字典可以禁止代理抓包(charles、fiddler等)。
configuration.connectionProxyDictionary=[kCFNetworkProxiesHTTPProxy:"http:localhost",kCFNetworkProxiesHTTPEnable:NSNumber.init(value: 1),kCFNetworkProxiesHTTPPort:NSNumber.init(value: 8080)]
configuration.connectionProxyDictionary=["HTTPEnable":true,
"HTTPProxy":"http:localhost",
"HTTPPort":NSNumber.init(value: 8080),
"HTTPSEnable":true,
"HTTPSProxy":"http:localhost",
"HTTPSPort":NSNumber.init(value: 8080)]
// 禁止代理
configuration.connectionProxyDictionary = [:];
configuration.httpCookieAcceptPolicy = .never
configuration.httpCookieStorage = .none
configuration.httpMaximumConnectionsPerHost=5
configuration.timeoutIntervalForRequest=20
//....还有很多configuration的设置
let session = Session(configuration: configuration)
其他的一些设置和请求
//Handling Redirects
let redirector = Redirector(behavior: .follow)
AF.request("http://localhost:8080/login").redirect(using: redirector).responseString{ (response) in
debugPrint(response)
}
//Customizing Caching自定义缓存策略,可以覆盖默认的策略
let cacher = ResponseCacher(behavior: .cache)
AF.request("http://localhost:8080/login").cacheResponse(using: cacher).responseString{ (response) in
debugPrint(response)
}
//Credentials
AF.request("http://localhost:8080/login")
.authenticate(username: "uesername", password: "password").response{response in
debugPrint(response)
}
//onURLRequestCreation
AF.request("http://localhost:8080/login")
.onURLRequestCreation{ request in
print(request)
}.response{response in
debugPrint(response)
}
//onURLSessionTaskCreation
AF.request("http://localhost:8080/login")
.onURLSessionTaskCreation { task in
print(task)
}.response{response in
debugPrint(response)
}
//URLComponents
let urlString = "http://localhost:8080/login"
let url = URL(string: urlString)!
let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true)!
AF.request(urlComponents).responseString{ response in
}
//urlRequest
let url1 = URL(string: "http://localhost:8080/login")!
var urlRequest = URLRequest(url: url1)
urlRequest.method = .post
let parameters = ["foo": "bar"]
do {
urlRequest.httpBody = try JSONEncoder().encode(parameters)
} catch {
}
urlRequest.headers.add(.contentType("application/json"))
AF.request(urlRequest).responseString{response in
}
还有一些用法,如合并请求,序列请求。