swift之网络请求框架Alamofire

 

原码解读: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
            
        }
        

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

 

 

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值