Swift3.0 Alamofire初级应用
来源:互联网 发布:mac加密文件夹弹出 编辑:程序博客网 时间:2024/06/05 11:20
序:做过iOS开发的人肯定都知道AFN,现在Swift逐渐流行AFN团队又用Swift写了Alamofire。从头开始学习一下,看看新的Alamofire有什么性能的优化和不同。
大家都知道Alamofire是一个HTTP的网络封装库,首先我们肯定要先知道用Alamofire我们可以干什么。
功能特点
1、请求连接,处理接受不同类型的返回
2、 URL / JSON / plist 参数编码
3、上传 File / Data / Stream / MultipartFormData
4、用请求或者恢复数据下载文件
5、身份认证和url凭证
6、HTTP 返回验证
7、上传或者下载进程显示
8、cURL命令输出
9、动态适应和重试请求
10、TLS证书和公钥锁
11、网络是否可用判断
12、完整的单元检测
组件库
- AlamofireImage
- AlamofireNetworkActivityIndicator
环境要求
- iOS 8.0+ / macOS 10.10+ / tvOS 9.0+ / watchOS 2.0+
- Xcode 8.1+
- Swift 3.0+
安装
CocoaPods
podfile文件:
source 'https://github.com/CocoaPods/Specs.git'platform :ios, '10.0'use_frameworks!target '<Your Target Name>' do pod 'Alamofire', '~> 4.4'end
然后到终端进入项目目录:
$ pod install
其他安装方法见gitHub
应用
首先导入Alamofire模块,发一个简单的GET请求import AlamofireAlamofire.request("https://httpbin.org/get")
返回的回调:
Alamofire.request("https://httpbin.org/get").responseJSON { response in print("Request: \(String(describing: response.request))") // original url request print("Response: \(String(describing: response.response))") // http url response print("Result: \(response.result)") // response serialization result if let json = response.result.value { print("JSON: \(json)") // serialized json response } if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) { print("Data: \(utf8Text)") // original server data as UTF8 string }}
Alamofire 包括默认回调总共有五种返回类型回调包括:
// Response Handler - Unserialized Responsefunc response( queue: DispatchQueue?, completionHandler: @escaping (DefaultDataResponse) -> Void) -> Self// Response Data Handler - Serialized into Datafunc responseData( queue: DispatchQueue?, completionHandler: @escaping (DataResponse<Data>) -> Void) -> Self// Response String Handler - Serialized into Stringfunc responseString( queue: DispatchQueue?, encoding: String.Encoding?, completionHandler: @escaping (DataResponse<String>) -> Void) -> Self// Response JSON Handler - Serialized into Anyfunc responseJSON( queue: DispatchQueue?, completionHandler: @escaping (DataResponse<Any>) -> Void) -> Self// Response PropertyList (plist) Handler - Serialized into Anyfunc responsePropertyList( queue: DispatchQueue?, completionHandler: @escaping (DataResponse<Any>) -> Void)) -> Self
响应验证
在默认情况下,Alamofire对待任何完整的请求不管什么响应内容都是成功的,加上验证之后,在得到响应回调之前,先要经过验证,类型或者状态不匹配的则会报错。
手动验证
Alamofire.request("https://httpbin.org/get") .validate(statusCode: 200..<300) .validate(contentType: ["application/json"]) .responseData { response in switch response.result { case .success: print("Validation Successful") case .failure(let error): print(error) } }
自动验证
自动验证状态码在200-300之间的区间,且内容类型是响应能接受的匹配类型。
Alamofire.request("https://httpbin.org/get").validate().responseJSON { response in switch response.result { case .success: print("Validation Successful") case .failure(let error): print(error) }}
响应缓存
响应缓存依赖于系统框架URLCache.
HTTP 请求方式
HTTP请求方式的枚举列表在下面的文件定义 RFC 7231 §4.3:
public enum HTTPMethod: String { case options = "OPTIONS" case get = "GET" case head = "HEAD" case post = "POST" case put = "PUT" case patch = "PATCH" case delete = "DELETE" case trace = "TRACE" case connect = "CONNECT"}
上面的那些方式的值可以当做Alamofire.request的method的参数设置
Alamofire.request("https://httpbin.org/get") // method defaults to `.get`Alamofire.request("https://httpbin.org/post", method: .post)Alamofire.request("https://httpbin.org/put", method: .put)Alamofire.request("https://httpbin.org/delete", method: .delete)
参数编码
Alamofire支持三种类型的参数编码包括:URL、JSON和PropertyList。它还可以支持任何自定义编码符合ParameterEncoding协议。
URL Encoding
GET请求的URL编码
let parameters: Parameters = ["foo": "bar"]// All three of these calls are equivalentAlamofire.request("https://httpbin.org/get", parameters: parameters) // encoding defaults to `URLEncoding.default`Alamofire.request("https://httpbin.org/get", parameters: parameters, encoding: URLEncoding.default)Alamofire.request("https://httpbin.org/get", parameters: parameters, encoding: URLEncoding(destination: .methodDependent))// https://httpbin.org/get?foo=bar
POST请求的URL编码
let parameters: Parameters = [ "foo": "bar", "baz": ["a", 1], "qux": [ "x": 1, "y": 2, "z": 3 ]]// All three of these calls are equivalentAlamofire.request("https://httpbin.org/post", method: .post, parameters: parameters)Alamofire.request("https://httpbin.org/post", method: .post, parameters: parameters, encoding: URLEncoding.default)Alamofire.request("https://httpbin.org/post", method: .post, parameters: parameters, encoding: URLEncoding.httpBody)// HTTP body: foo=bar&baz[]=a&baz[]=1&qux[x]=1&qux[y]=2&qux[z]=3
JSON Encoding
let parameters: Parameters = [ "foo": [1,2,3], "bar": [ "baz": "qux" ]]// Both calls are equivalentAlamofire.request("https://httpbin.org/post", method: .post, parameters: parameters, encoding: JSONEncoding.default)Alamofire.request("https://httpbin.org/post", method: .post, parameters: parameters, encoding: JSONEncoding(options: []))// HTTP body: {"foo": [1, 2, 3], "bar": {"baz": "qux"}}
Property List Encoding
PropertyListEncoding使用PropertyListSerialization创建一个参数对象的plist表示,根据相关的格式和写作选项值,设置为请求的主体。content - type HTTP请求头字段的编码设置为application/x-plist
.。Custom Encoding
struct JSONStringArrayEncoding: ParameterEncoding {private let array: [String] init(array: [String]) { self.array = array } func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest { var urlRequest = try urlRequest.asURLRequest() let data = try JSONSerialization.data(withJSONObject: array, options: []) if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil { urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type") } urlRequest.httpBody = data return urlRequest }}
给URLRequest 的参数手动编码
let url = URL(string: "https://httpbin.org/get")!var urlRequest = URLRequest(url: url)let parameters: Parameters = ["foo": "bar"]let encodedURLRequest = try URLEncoding.queryString.encode(urlRequest, with: parameters)
HTTP Headers(请求头)
给一个请求添加一个自定义的请求头,这个请求头必须是全局的,在你请求的时候更容易去获取和改变请求头。let headers: HTTPHeaders = [ "Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==", "Accept": "application/json"]Alamofire.request("https://httpbin.org/headers", headers: headers).responseJSON { response in debugPrint(response)}
身份认证
Authentication依赖于URLCredential
和URLAuthenticationChallenge
.这两个系统框架。Supported Authentication Schemes
- HTTP Basic
- HTTP Digest
- Kerberos
- NTLM
HTTP Basic Authentication
let user = "user"let password = "password"Alamofire.request("https://httpbin.org/basic-auth/\(user)/\(password)") .authenticate(user: user, password: password) .responseJSON { response in debugPrint(response) }
根据服务器的实现方法,也可能需要一个授权头
let user = "user"let password = "password"var headers: HTTPHeaders = [:]if let authorizationHeader = Request.authorizationHeader(user: user, password: password) { headers[authorizationHeader.key] = authorizationHeader.value}Alamofire.request("https://httpbin.org/basic-auth/user/password", headers: headers) .responseJSON { response in debugPrint(response) }
证书认证
let user = "user"let password = "password"let credential = URLCredential(user: user, password: password, persistence: .forSession)Alamofire.request("https://httpbin.org/basic-auth/\(user)/\(password)") .authenticate(usingCredential: credential) .responseJSON { response in debugPrint(response) }
下载文件
Alamofire.download("https://httpbin.org/image/png").responseData { response in if let data = response.result.value { let image = UIImage(data: data) }}
下载文件目的地
let destination: DownloadRequest.DownloadFileDestination = { _, _ in let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let fileURL = documentsURL.appendingPathComponent("pig.png") return (fileURL, [.removePreviousFile, .createIntermediateDirectories])}Alamofire.download(urlString, to: destination).response { response in print(response) if response.error == nil, let imagePath = response.destinationURL?.path { let image = UIImage(contentsOfFile: imagePath) }}
let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory)Alamofire.download("https://httpbin.org/image/png", to: destination)
下载进度
Alamofire.download("https://httpbin.org/image/png") .downloadProgress { progress in print("Download Progress: \(progress.fractionCompleted)") } .responseData { response in if let data = response.result.value { let image = UIImage(data: data) } }
下载进度的API还可以设置线程参数,线程参数可以决定下载进度在哪个线程调起。
let utilityQueue = DispatchQueue.global(qos: .utility)Alamofire.download("https://httpbin.org/image/png") .downloadProgress(queue: utilityQueue) { progress in print("Download Progress: \(progress.fractionCompleted)") } .responseData { response in if let data = response.result.value { let image = UIImage(data: data) } }
恢复下载
class ImageRequestor { private var resumeData: Data? private var image: UIImage? func fetchImage(completion: (UIImage?) -> Void) { guard image == nil else { completion(image) ; return } let destination: DownloadRequest.DownloadFileDestination = { _, _ in let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] let fileURL = documentsURL.appendingPathComponent("pig.png") return (fileURL, [.removePreviousFile, .createIntermediateDirectories]) } let request: DownloadRequest if let resumeData = resumeData { request = Alamofire.download(resumingWith: resumeData) } else { request = Alamofire.download("https://httpbin.org/image/png") } request.responseData { response in switch response.result { case .success(let data): self.image = UIImage(data: data) case .failure: self.resumeData = response.resumeData } } }}
上传数据到服务器
上传Data类型:
let imageData = UIPNGRepresentation(image)!Alamofire.upload(imageData, to: "https://httpbin.org/post").responseJSON { response in debugPrint(response)}
上传一个文件:
let fileURL = Bundle.main.url(forResource: "video", withExtension: "mov")Alamofire.upload(fileURL, to: "https://httpbin.org/post").responseJSON { response in debugPrint(response)}
上传Multipart Form Data
Alamofire.upload( multipartFormData: { multipartFormData in multipartFormData.append(unicornImageURL, withName: "unicorn") multipartFormData.append(rainbowImageURL, withName: "rainbow") }, to: "https://httpbin.org/post", encodingCompletion: { encodingResult in switch encodingResult { case .success(let upload, _, _): upload.responseJSON { response in debugPrint(response) } case .failure(let encodingError): print(encodingError) } })
上传进度
let fileURL = Bundle.main.url(forResource: "video", withExtension: "mov")Alamofire.upload(fileURL, to: "https://httpbin.org/post") .uploadProgress { progress in // main queue by default print("Upload Progress: \(progress.fractionCompleted)") } .downloadProgress { progress in // main queue by default print("Download Progress: \(progress.fractionCompleted)") } .responseJSON { response in debugPrint(response) }
阅读全文
0 0
- Swift3.0 Alamofire初级应用
- Swift3.0后Alamofire报错的解决方法
- [绍棠_Swift] Swift3.0中的Alamofire网络请求的封装
- Swift3.0-初级用法(适合初学者)
- Xcode8.1 swift3.0 引入Alamofire 3.5.0 支持iOS版本8.0 设置
- Xcode升级到8.0,Swift3.0之后,出现的alamofire问题
- Swift3.0 Alamofire 网络请求的封装--->get,post,upload图片上传
- Xcode8 适配 Swift3/Swift2.3 关于Alamofire
- swift3 用Alamofire下载视频、断点续传
- swift3面向协议编程实现Alamofire封装
- swift3.0 属性文件plist的应用
- Alamofire
- Swift3.0
- swift3.0
- Swift3.0
- Alamofire json Alamofire2.0使用
- swift3.0的改变
- Swift3.0学习
- Codeforeces #420 E. Okabe and El Psy Kongroo 递推加矩阵快速幂
- 关于时间处理的相关类
- iOS 开发 push进入一个视图控制器,返回的时候删除中间某一个视图控制器
- linux 查找相关
- eclipse 中git解决冲突
- Swift3.0 Alamofire初级应用
- com.mysql.jdbc.PacketTooBigException: 解决方案
- awk print 的用法
- Android Studio工程目录介绍
- webpack 打包成相对路径 css url路径问题
- 关于RXbinding的一些常规使用
- [Caffe]ubuntu无cuda安装caffe
- linux下生成动态库和静态库
- 在springmvc中 @RequestMapping(value={"", "/"})是什么意思?