参考原码解析:https://www.cnblogs.com/machao/p/6856603.html
安装使用参考一:http://blog.csdn.net/codingfire/article/details/51940212
安装使用参考二:https://www.jianshu.com/p/42aa9b5b70a3
原码解读: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
原码解析:https://www.jianshu.com/p/f39ad2a3c10b
使用参考:https://www.jianshu.com/p/f8c3adb056cf、https://www.jianshu.com/p/903b678d2d3f
参考使用:https://github.com/WangLiquan/EWAlamofireEncapsulation
https://www.jianshu.com/p/c3980b4c07c5
==============get、post请求的简单封装=========
/**
网络请求中心 get post请求
使用:
let loginhttp:LYBHttpManager=LYBHttpManager()
let paramas:[String:String]=["username":"133355" ,"password":"11111"]
let url:String="\(BASEURL)"+"index.php?m=Api&c=User&a=login"
loginhttp.requestWithJson(url: url, httpMethod: .get, params: paramas, success: { (res) in
if ((res["result"]) != nil) {//判断res中是否存在result这个键
let resultDict=res["result"] as? NSDictionary
let loginresultModel=LYBLoginResultModel.deserialize(from: resultDict)//这是根据字典转模型,还可以直接字符串转模型
LYBLoginVC.model=loginresultModel//静态变量存储,整个程序生命周期期间且所有类中都可以用
print("\(String(describing: loginresultModel?.token))")
}else{
print("没有")
}
}) { (error) in
//返回的错误
let s = String.init(describing: error)// 吧返回的错误转换成字符串
MBProgressHUD.showError(s)
}
}
*/
import UIKit
class LYBHttpManager: NSObject,URLSessionDelegate,URLSessionDataDelegate {
//*******注意自定义的manager必须是强引用,否则请求结果都是code=-999 cancelled
static var manager: SessionManager?=nil
/**
SessionManager的配置和创建
*/
func createManage(){
let config:URLSessionConfiguration = URLSessionConfiguration.default
//创建httpHeader
var defaultHeaders = Alamofire.SessionManager.defaultHTTPHeaders
//给httpheader添加内容
// defaultHeaders["token"] = "token的内容"
// defaultHeaders["Authorization"] = ""
defaultHeaders.updateValue("application/json", forKey: "Accept")
config.httpAdditionalHeaders = defaultHeaders
// config.httpAdditionalHeaders=[:]//http请求头,或者直接这样写
//配置证书验证
// let serverTrustPolicies: [String: ServerTrustPolicy] = [
// ///正式环境的证书配置,修改成自己项目的正式url
// "www.baidu.com": .pinCertificates(
// certificates: ServerTrustPolicy.certificates(),
// validateCertificateChain: true,
// validateHost: true
// ),
// //测试环境的证书配置,不验证证书,无脑通过
// "192.168.1.213:8002": .disableEvaluation,
// ]
config.timeoutIntervalForRequest = 20
config.httpMaximumConnectionsPerHost=5;//最大连接数
// //根据config创建manager-----带验证域名
// LYBHttpManager.manager = Alamofire.SessionManager(configuration: config,
// delegate: SessionDelegate(),
// serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies))
//根据config创建manager-----不验证域名
LYBHttpManager.manager = Alamofire.SessionManager(configuration: config)
}
//========================================
/**
核心的方法:get post请求,返回的是json数据
pamara1: 请求的地址
parama2:.get .post
parama3:参数
parama4:成功的回调
parama5:失败的回调
*/
public func requestWithJson(url: String,
httpMethod: HTTPMethod,
params: Dictionary?,
success: @escaping success,
failure: @escaping failure){
createManage()//配置创建sessionmanager
if httpMethod == HTTPMethod.get{
LYBHttpManager.manager!.request(url,
method: .get,
parameters: params,
encoding: URLEncoding.default,
headers: nil).responseJSON {
(response) in
// print("\(response)")
/*这个的结果(前面有一层SUCCESS,可以用response.result.value取到服务器返回的数据)----SUCCESS: {
msg = "\U767b\U9646\U6210\U529f";
result = {agent = 0;};
status = 1;
}*/
// print("\(response.result)")//结果是SUCCESS或者
// print("\(response.result.value)")//服务器返回的数据
switch response.result{
case .success(let data)://这里的data就是response的数据
if let value = response.result.value as? Dictionary{//吧返回的数据转换成字典
///添加一些全部接口都有的一些状态判断
if value["status"] as! Int == 1010 {
return
}
success(value as NSDictionary)
}
case .failure(let err)://这里的err就是网路链接失败返回的数据
failure(err as AnyObject)
}
}
}
else{
//post
LYBHttpManager.manager!.request(url,method: .post,parameters: params!,
encoding: JSONEncoding.default,
headers: nil).responseJSON { (response) in
success(response as AnyObject)
switch response.result{
case .success:
///添加一些全部接口都有的一些状态判断
if let value = response.result.value as? Dictionary {
if value["status"] as! Int == 1010 {
success(value as AnyObject)
return
}
success(value as NSDictionary)
}
case .failure(let err):
failure(err as AnyObject)
break
}
}
}
}
}
===========
Alamofire进行Https网络请求自签名证书:https://www.jianshu.com/p/1005ce8fec8e
let url="\(BASEURL)"+LUNBOURL
let image:UIImage=UIImage.init(named:"bannerhomeOne")!
//获取数据
func normalGetData() {
//get--01--response
Alamofire.request(url).response { (returnResult)in
if let data = returnResult.data,let utf8Text =String(data: data, encoding: .utf8) {
print(" utf8Text =\(utf8Text)")
}
}
// get--02---responseData
Alamofire.request(url).responseData { (returnResult)in
debugPrint(" returnResult =\(returnResult)")
if let data = returnResult.data,let utf8Text =String(data: data, encoding: .utf8) {
print(" utf8Text =\(utf8Text)")
}
}
//get--03--responseString
Alamofire.request(url).responseString { (returnResult)in
debugPrint(" Sucess =\(returnResult.result.isSuccess)")
print(" returnResult =\(returnResult)")
}
//get --04--responseJSON
Alamofire.request(url).responseJSON { (returnResult)in
debugPrint("responseJSON -->\(returnResult)")
if let json = returnResult.result.value {//这个转换的json数据比较正规
print("responseJSON -->\(json)")
/* 返回请求地址、数据、和状态结果等信息
print(" responseJSON() --> \(returnResult.request!)")
print("responseJSON() --> \(returnResult.data!)")
print(" responseJSON() --> \(returnResult.result)")
*/
}
}
// get--05---queue
// 补充:1.参数:queue:请求队列 --> 就是默认在主线程中执行~我们可以自定义调度队列。
// 官方解释:Response handlers by default are executed on the main dispatch queue. However, a custom dispatch queue can be provided instead.
let customQueue = DispatchQueue.global(qos: .utility)
Alamofire.request(url).responseJSON(queue: customQueue) { (returnResult)in
print("请求队列 -->\(returnResult)")
}
//get---06带请求头设置获取数据
let headers: HTTPHeaders = [
"Accept":"application/json"//设置客户端以什么格式解析服务器返回的数据
]
Alamofire.request(url, headers: headers).responseJSON { (returnResult)in
print("获取数据并设置请求头 --> returnResult =\(returnResult)")
}
}
//GET请求---无参数
func getData() {
Alamofire.request(url, method: .get).responseJSON { (returnResult)in
print("GET 请求无参数 --> returnResult =\(returnResult)")
}
}
//POST请求----无参数
func postData(){
Alamofire.request(url, method: .post).responseJSON { (returnResult)in
print("POST 请求无参数 --> returnResult =\(returnResult)")
}
}
//POST请求有参数
func postDataWithParams() {
let param = [String:String]()
Alamofire.request(url, method: .post, parameters: param).responseJSON { (returnResult)in
print(" POST 请求有参数参数 --> returnResult =\(returnResult)")
}
}
// URLRequest的方式请求
func URLRequestWidth() {
let urls = URL(string: url)
var urlRequest = URLRequest(url: urls!)
urlRequest.httpMethod = "POST"
let param = ["type":"","key":""]
do {
urlRequest.httpBody = try JSONSerialization.data(withJSONObject: param, options: [])
} catch {
print(error)
}
urlRequest.setValue("application/json", forHTTPHeaderField:"Content-Type")
Alamofire.request(urlRequest).responseData { (returnResult)in
debugPrint(returnResult)
if let data = returnResult.data,let utf8Text = String(data: data, encoding: .utf8) {
print(" URLRequest请求方式 --> utf8Text =\(utf8Text)")
}
}
}
//下载不带进度
func download() {
// 1.下载图片
Alamofire.download(url).responseData { (returnResult)in
if let data = returnResult.result.value {
let image = UIImage(data: data)
print("image =\(image!)")
} else {
print("下载失败")
}
}
}
//下载带进度
func downoadWithProgress() {
Alamofire.download(url).downloadProgress { (progress)in
print("下载进度 =\(progress.fractionCompleted)")
}.responseData { (returnResult) in
if let data = returnResult.result.value {
let image = UIImage(data: data)
print("image =\(image!)")
} else {
print("下载失败")
}
}
}
//uploadData----上传data数据
func uploadData() {
let imageData =UIImagePNGRepresentation(image)!
Alamofire.upload(imageData, to: url).responseJSON { response in
debugPrint(response)
}
}
//uploadFile----上传文件
func uploadFile() {
let fileURL = Bundle.main.url(forResource:"video", withExtension:"mov")
Alamofire.upload(fileURL!, to: url).responseJSON { response in
debugPrint(response)
}
}
//uploadMultiFormData----上传多个表单数据
func uploadMultiFormData() {
Alamofire.upload(
multipartFormData: { multipartFormData in//添加多个表单数据是吧本地url传上去
// multipartFormData.append(unicornImageURL, withName: "unicorn")
// multipartFormData.append(rainbowImageURL, withName: "rainbow")
},
to: url,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload,_,_):
upload.responseJSON { responsein
debugPrint(response)
}
case .failure(let encodingError):
print(encodingError)
}
}
)
}
//上传带进度条
func uploadWithProgress() {
let fileURL = Bundle.main.url(forResource:"video", withExtension:"mov")
Alamofire.upload(fileURL!, to: url)
.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)
}
}
上传下载参考:https://www.jianshu.com/p/f8c3adb056cf
下载参考:http://www.hangge.com/blog/cache/detail_972.html
=============创建sessionManager和设置Configuration
Session Manager
高级别的方便的方法,例如Alamofire.request,使用的是默认的Alamofire.SessionManager,并且这个SessionManager是用默认URLSessionConfiguration配置的。
例如,下面两个语句是等价的:
***Alamofire.request("https://httpbin.org/get")
***let sessionManager = Alamofire.SessionManager.default
sessionManager.request("https://xx.com")
我们可以自己创建后台会话和短暂会话的session manager,还可以自定义默认的会话配置来创建新的session manager,例如修改默认的header httpAdditionalHeaders和timeoutIntervalForRequest。
方式一:
let configuration =URLSessionConfiguration.default
let sessionManager = Alamofire.SessionManager(configuration: configuration)
方式二:
let configuration = URLSessionConfiguration.background(withIdentifier:"com.example.app.background")
let sessionManager = Alamofire.SessionManager(configuration: configuration)
方式三:
let configuration =URLSessionConfiguration.ephemeral
let sessionManager = Alamofire.SessionManager(configuration: configuration)
更改configration:
var defaultHeaders = Alamofire.SessionManager.defaultHTTPHeaders
defaultHeaders["DNT"] ="1 (Do Not Track Enabled)"
let configuration =URLSessionConfiguration.default
configuration.httpAdditionalHeaders =defaultHeaders
let sessionManager = Alamofire.SessionManager(configuration:configuration)
=============序列化=解析数据====================================
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对象(即字典,或字典数组)
if let dictArr:[[String:Any]]=(tryJSONSerialization.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{
}
=================================================================
=======================Alamofire中sessionManager的使用=============
===========请求获取数据=====
在LYBHomeHttp类中:
static var sessionManager:SessionManager? = nil//这里的自定义sessionManager必须被强引用,否则不起作用
//============//static修饰的属性只能用类调用,
func sessionM(){
let config=URLSessionConfiguration.default
config.timeoutIntervalForRequest=30//超时时间
config.httpMaximumConnectionsPerHost=2//最大连接数
let defaultHeaderss = Alamofire.SessionManager.defaultHTTPHeaders
// defaultHeaderss["DNT"] = "1 (Do Not Track Enabled)"
config.httpAdditionalHeaders = defaultHeaderss
LYBHomeHttp.sessionManager=Alamofire.SessionManager(configuration: config)
LYBHomeHttp.sessionManager?.request(url, method: .get, parameters: nil, encoding:URLEncoding.default, headers: defaultHeaderss).responseJSON { (response) in
print(response)//请求到的全部数据--控制台打印SUCCESS:{}
print(response.result)//控制台打印出SUCCESS或者FAILURE
switch response.result{
case .success(let value):
print(value)//控制台打印出SUCCESS对应的数据{请求到的后台数据}
case .failure(let error):
print(error)//控制台打印出FAILURE对应的错误信息{返回的错误信息}
}
}
}
=============请求code=-999报错的解决:https://www.jianshu.com/p/e62d87b2e174======
解决: static var sessionManager:SessionManager? = nil//这里的自定义sessionManager必须被强引用,否则不起作用
=======sessionManager上传=====sessionManager下载======
/**
网络下载,暂停下载,继续接着上一次下载,上传数据
*/
import UIKit
class LYBDownAndUpLoadHttpManager: NSObject {
static var manager:SessionManager? = nil//这里的sessionManager需要被强引用,否则不起作用
var cancelledData:Data?//已下载的数据临时存储起来
let serviceAddresss="http://";//上传到服务器资源地址--上传
let downloadUrl="http://"//服务器的资源地址--下载
var downrequest:Request?=nil//下载的请求
var uprequest:Request? = nil//上传的请求
func createManage(){
let config=URLSessionConfiguration.default
config.timeoutIntervalForRequest=30//超时时间
config.httpMaximumConnectionsPerHost=2//最大连接数
var defaultHeaderss = Alamofire.SessionManager.defaultHTTPHeaders
defaultHeaderss.updateValue("application/json", forKey: "Accept")
config.httpAdditionalHeaders = defaultHeaderss
//根据config创建manager-----不验证域名
LYBDownAndUpLoadHttpManager.manager=SessionManager(configuration: config)
}
//指定下载路径(文件名不变)-这是一个闭包
let destination: DownloadRequest.DownloadFileDestination = {
_, response in
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let fileURL = documentsURL.appendingPathComponent(response.suggestedFilename!)//response.suggestedFilename!是系统推荐的路径,也可以自己定义路径:"file/mypath.png"
//两个参数表示如果有同名文件则会覆盖,如果路径中文件夹不存在则会自动创建
return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}
/**
创建下载请求,
parama1:url 服务器的下载地址
parama2:destination 本地存储的地址
*/
func createDownloadRequest(downloadUrl: String,success: @escaping success,
failure: @escaping failure){
createManage()
downrequest = ( LYBDownAndUpLoadHttpManager.manager!.download(URLRequest.init(url:URL.init(string: downloadUrl)!), to: destination).responseJSON(completionHandler: { (response) in
print(response.result)
switch response.result {
case .success( _):
success(response as AnyObject)
case .failure:
self.cancelledData = response.resumeData //意外终止的话,把已下载的数据储存起来
failure(response as AnyObject)
}
}))
}
func cancelDownload(){
downrequest?.cancel()//暂停下载
}
/**
继续下载
parama1:cancelledDatay上次下载的数数据
parama2:destination 本地存储的地址
*/
func continueDownLoad(success: @escaping success,
failure: @escaping failure){
createManage()
LYBDownAndUpLoadHttpManager.manager!.download(resumingWith: self.cancelledData!, to: destination).responseJSON(completionHandler: { (response) in
print(response.result)
switch response.result {
case .success( _):
//self.image = UIImage(data: data)
success(response as AnyObject)
case .failure:
self.cancelledData = response.resumeData //意外终止的话,把已下载的数据储存起来
failure(response as AnyObject)
}
})
}
//=================================================
/**
上传data数据到服务器
*/
public func uploadWithData(url: String,
data: Data,
success: @escaping success,
failure: @escaping failure){
createManage()
let data:Data=UIImage.init(named: "bannerhomeOne")!.pngData()!
uprequest = ( LYBDownAndUpLoadHttpManager.manager!.upload(data, to: serviceAddresss, method: .post, headers: nil).responseJSON(completionHandler: { (response) in
switch response.result {
case .success( _):
print("文件下载完毕: \(response)")
case .failure(let error):
print(error)
}
}))
}
func cancelUpload(){
uprequest?.cancel()//取消
}
/**
吧本地路径的资源上传到服务器
parama1:服务器地址
parama2:本地路径
*/
public func uploadWithLocalpath(url: String,
path: String,
success: @escaping success,
failure: @escaping failure){
createManage()
let path=NSHomeDirectory() + "file"
LYBDownAndUpLoadHttpManager.manager!.upload(URL.init(string: path)!, to: serviceAddresss).responseJSON(completionHandler: { (response) in
switch response.result {
case .success( _):
print("文件上传完毕: \(response)")
case .failure(let error):
print(error)
}
})
}
}
=================设置httpheder=========
//*********在iOS7中要中以下方法才有效
private func getRequest(method: Method, _ URLString: URLStringConvertible, parameters: [String: AnyObject]? = nil) -> NSMutableURLRequest {
let request = NSMutableURLRequest(URL: NSURL(string: URLString.URLString)!)
request.HTTPMethod = method.rawValue
if parameters != nil {
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(parameters!, options: nil, error: nil)
}
request.setValue(API_UA, forHTTPHeaderField: "User-Agent")
request.setValue(HEADER_ACCEPT, forHTTPHeaderField: "Accept")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
return request
}
//************iOS8中的社会httpheader要用httpAdditionalHeaders
//创建httpHeader
var defaultHeaders = Alamofire.SessionManager.defaultHTTPHeaders
//给httpheader添加内容
defaultHeaders["token"] = "token的内容"
defaultHeaders["Authorization"] = ""
defaultHeaders.updateValue("application/json", forKey: "Accept")
config.httpAdditionalHeaders = defaultHeaders // config.httpAdditionalHeaders=[:]//http请求头,或者直接这样写
===========全局请求头和局部请求头==========
.*******局部请求头*********
客户端每发起一次HTTP请求,请求头信息是必不可少的。这也是同服务器交流的一种手段,在实际的开发中,也肯定会遇到需要自定义请求头的需求,在Alamofire中如何设置请求头:
let headers: HTTPHeaders = [
"Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==",
"Accept": "application/json"
]
Alamofire.request("https://httpbin.org/headers", headers: headers).responseJSON { response in
debugPrint(response)
}
在request(...)函数中,存在headers这么一个参数,我们只要传入提前写好的字典就行了。
********全局请求头*********
使用URLSessionConfiguration来配置全局的属性,
需要说明的是,Alamofire为每一个请求都设置了默认的请求头,我们简单介绍一下:
(1)Accept-Encoding 表示可接受的编码方式,值为:gzip;q=1.0, compress;q=0.5
(2)Accept-Language 表示可接受的语言,这个在后边的文章中会详细说明
(3)User-Agent 表示用户代理信息,比如:iOS Example/1.0 (com.alamofire.iOS-Example; build:1; iOS 10.0.0) Alamofire/4.0.0
默认的请求头配置,我们通过SessionManager.default来创建SessionManager:
open static let `default`: SessionManager = {
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders
return SessionManager(configuration: configuration)
}()