博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
swift之网络请求框架Alamofire
阅读量:4290 次
发布时间:2019-05-27

本文共 33697 字,大约阅读时间需要 112 分钟。

 

原码解读: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(
{ 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请求身份验证====

有(url资格验证) and 两种

//在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)//方式十一loglet 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                    }

还有一些用法,如合并请求,序列请求。

 

 

 

你可能感兴趣的文章
全网最详细的一篇SpringCloud总结
查看>>
消息中间件中的有序消息,其实是排队但是不能插队
查看>>
不知道分布式事务,还想进互联网大厂
查看>>
mysql为什么使用B+树作为索引的结构
查看>>
mysql索引总结(1)-mysql 索引类型以及创建(文章写的不错!!!)
查看>>
聊聊CAS - 面试官最喜欢问的并发编程专题
查看>>
Spring Boot 中使用一个注解轻松将 List 转换为 Excel 下载
查看>>
高并发环境下,先操作数据库还是先操作缓存?
查看>>
MySQL Explain详解
查看>>
一直搞不清楚什么是读写分离,主从复制的原理,今天总算搞懂了
查看>>
消息队列 mq 必会面试题
查看>>
线程池的工作原理是啥?能手写一个线程池吗?
查看>>
一口气说出 6种 延时队列的实现方案,大厂offer稳稳的
查看>>
原来redis这么简单,跟着文章操作一遍你就会了
查看>>
Redis两种持久化机制RDB和AOF详解(面试常问,工作常用)
查看>>
事务隔离级别中的可重复读能防幻读吗?
查看>>
老伙计,关于JDK并发包,这些不为人知的秘密你知道多少?
查看>>
图片的左右切换
查看>>
进级的RecyclerView——LRecyclerView
查看>>
Android 利用Gradle实现app的环境分离
查看>>