一、response
的使用
SessionManager.default
.request(urlString)
.response { (response) in
print("数据接收:\(response)数据接收")
}
打印了一堆的有用的数据
:DefaultDataResponse(request: Optional(http://www.douban.com/j/app/radio/channels), response: Optional(<NSHTTPURLResponse: 0x600000ea4f80> { URL: https://www.douban.com/j/app/radio/channels } { Status Code: 200, Headers {
"Cache-Control" = (
"must-revalidate, no-cache, private"
);
Connection = (
"keep-alive"
);
"Content-Encoding" = (
gzip
);
"Content-Type" = (
"application/json; charset=utf-8"
);
Date = (
"Mon, 26 Aug 2019 02:27:16 GMT"
);
Expires = (
"Sun, 1 Jan 2006 01:00:00 GMT"
);
"Keep-Alive" = (
"timeout=30"
);
Pragma = (
"no-cache"
);
Server = (
dae
);
"Strict-Transport-Security" = (
"max-age=15552000;"
);
"Transfer-Encoding" = (
Identity
);
Vary = (
"Accept-Encoding"
);
"X-DAE-App" = (
fm
);
"X-DAE-Node" = (
anson10
);
"X-Douban-Mobileapp" = (
0
);
"X-Xss-Protection" = (
"1; mode=block"
);
} }), data: Optional(3433 bytes), error: nil, timeline: Timeline: { "Request Start Time": 588479236.618, "Initial Response Time": 588479236.791, "Request Completed Time": 588479236.804, "Serialization Completed Time": 588479236.804, "Latency": 0.173 secs, "Request Duration": 0.186 secs, "Serialization Duration": 0.001 secs, "Total Duration": 0.186 secs }, _metrics: Optional((Task Interval) <_NSConcreteDateInterval: 0x600000ed6100> (Start Date) 2019-08-26 02:27:16 +0000 + (Duration) 0.174134 seconds = (End Date) 2019-08-26 02:27:16 +0000
(Redirect Count) 1
(Transaction Metrics) (Request) <NSURLRequest: 0x600000c8c520> { URL: http://www.douban.com/j/app/radio/channels }
(Response) <NSHTTPURLResponse: 0x600000ed5bc0> { URL: http://www.douban.com/j/app/radio/channels } { Status Code: 301, Headers {
"Cache-Control" = (
"max-age=604800"
);
Connection = (
"keep-alive"
);
"Content-Length" = (
162
);
"Content-Type" = (
"text/html"
);
Date = (
"Mon, 26 Aug 2019 02:11:18 GMT"
);
"Keep-Alive" = (
"timeout=30"
);
Location = (
"https://www.douban.com/j/app/radio/channels"
);
Server = (
dae
);
} }
(Fetch Start) 2019-08-26 02:27:16 +0000
(Domain Lookup Start) (null)
(Domain Lookup End) (null)
(Connect Start) (null)
(Secure Connection Start) (null)
(Secure Connection End) (null)
(Connect End) (null)
(Request Start) 2019-08-26 02:27:16 +0000
(Request End) 2019-08-26 02:27:16 +0000
(Response Start) 2019-08-26 02:27:16 +0000
(Response End) 2019-08-26 02:27:16 +0000
(Protocol Name) (null)
(Proxy Connection) NO
(Reused Connection) YES
(Fetch Type) Local Cache
(Request) <NSURLRequest: 0x600000c8c690> { URL: https://www.douban.com/j/app/radio/channels }
(Response) <NSHTTPURLResponse: 0x600000ed5d40> { URL: https://www.douban.com/j/app/radio/channels } { Status Code: 200, Headers {
"Cache-Control" = (
"must-revalidate, no-cache, private"
);
Connection = (
"keep-alive"
);
"Content-Encoding" = (
gzip
);
"Content-Type" = (
"application/json; charset=utf-8"
);
Date = (
"Mon, 26 Aug 2019 02:26:56 GMT"
);
Expires = (
"Sun, 1 Jan 2006 01:00:00 GMT"
);
"Keep-Alive" = (
"timeout=30"
);
Pragma = (
"no-cache"
);
Server = (
dae
);
"Strict-Transport-Security" = (
"max-age=15552000;"
);
"Transfer-Encoding" = (
Identity
);
Vary = (
"Accept-Encoding"
);
"X-DAE-App" = (
fm
);
"X-DAE-Node" = (
fram12
);
"X-Douban-Mobileapp" = (
0
);
"X-Xss-Protection" = (
"1; mode=block"
);
} }
(Fetch Start) 2019-08-26 02:27:16 +0000
(Domain Lookup Start) (null)
(Domain Lookup End) (null)
(Connect Start) (null)
(Secure Connection Start) (null)
(Secure Connection End) (null)
(Connect End) (null)
(Request Start) 2019-08-26 02:27:16 +0000
(Request End) 2019-08-26 02:27:16 +0000
(Response Start) 2019-08-26 02:27:16 +0000
(Response End) 2019-08-26 02:27:16 +0000
(Protocol Name) (null)
(Proxy Connection) NO
(Reused Connection) YES
(Fetch Type) Local Cache
(Request) <NSURLRequest: 0x600000c8c760> { URL: https://www.douban.com/j/app/radio/channels }
(Response) <NSHTTPURLResponse: 0x600000ed5f80> { URL: https://www.douban.com/j/app/radio/channels } { Status Code: 200, Headers {
"Cache-Control" = (
"must-revalidate, no-cache, private"
);
Connection = (
"keep-alive"
);
"Content-Encoding" = (
gzip
);
"Content-Type" = (
"application/json; charset=utf-8"
);
Date = (
"Mon, 26 Aug 2019 02:27:16 GMT"
);
Expires = (
"Sun, 1 Jan 2006 01:00:00 GMT"
);
"Keep-Alive" = (
"timeout=30"
);
Pragma = (
"no-cache"
);
Server = (
dae
);
"Strict-Transport-Security" = (
"max-age=15552000;"
);
"Transfer-Encoding" = (
Identity
);
Vary = (
"Accept-Encoding"
);
"X-DAE-App" = (
fm
);
"X-DAE-Node" = (
anson10
);
"X-Douban-Mobileapp" = (
0
);
"X-Xss-Protection" = (
"1; mode=block"
);
} }
(Fetch Start) 2019-08-26 02:27:16 +0000
(Domain Lookup Start) 2019-08-26 02:27:16 +0000
(Domain Lookup End) 2019-08-26 02:27:16 +0000
(Connect Start) 2019-08-26 02:27:16 +0000
(Secure Connection Start) 2019-08-26 02:27:16 +0000
(Secure Connection End) 2019-08-26 02:27:16 +0000
(Connect End) 2019-08-26 02:27:16 +0000
(Request Start) 2019-08-26 02:27:16 +0000
(Request End) 2019-08-26 02:27:16 +0000
(Response Start) 2019-08-26 02:27:16 +0000
(Response End) 2019-08-26 02:27:16 +0000
(Protocol Name) http/1.1
(Proxy Connection) NO
(Reused Connection) NO
(Fetch Type) Network Load
))
请求的URL 、请求头、缓存控制方式、连接方式、编码方式、日期、时间轴等等信息。
那么这些信息是哪里来的呢?
通过跟踪源码可以看到
public func response(queue: DispatchQueue? = nil, completionHandler: @escaping (DefaultDataResponse) -> Void) -> Self {
delegate.queue.addOperation {
(queue ?? DispatchQueue.main).async {
var dataResponse = DefaultDataResponse(
request: self.request,
response: self.response,
data: self.delegate.data,
error: self.delegate.error,
timeline: self.timeline
)
dataResponse.add(self.delegate.metrics)
completionHandler(dataResponse)
}
}
return self
}
/// - Parameters:
/// - request: The URL request sent to the server.
/// - response: The server's response to the URL request.
/// - data: The data returned by the server.
/// - error: The error encountered while executing or validating the request.
/// - timeline: The timeline of the complete lifecycle of the request. `Timeline()` by default.
/// - metrics: The task metrics containing the request / response statistics. `nil` by default.
这里会给response初始化默认值。
二、多表单上传
在上传文件的时候经常会上传视频或者图片
mutilPartData.append("cooci".data(using: .utf8)!, withName: "name")
mutilPartData.append("LGCooci".data(using: .utf8)!, withName: "username")
mutilPartData.append("123456".data(using: .utf8)!, withName: "PASSWORD")
多表单上传.jpg
1:
boundary
分隔符。2:
\r\n
换行处理。3: --拼接关键字。
拼接表单 multipartFormData
struct EncodingCharacters {
static let crlf = "\r\n"
}
struct BoundaryGenerator {
enum BoundaryType {
case initial, encapsulated, final
}
static func randomBoundary() -> String {
return String(format: "alamofire.boundary.%08x%08x", arc4random(), arc4random())
}
static func boundaryData(forBoundaryType boundaryType: BoundaryType, boundary: String) -> Data {
let boundaryText: String
switch boundaryType {
case .initial:
boundaryText = "--\(boundary)\(EncodingCharacters.crlf)"// crlf = "\r\n"
case .encapsulated:
boundaryText = "\(EncodingCharacters.crlf)--\(boundary)\(EncodingCharacters.crlf)"
case .final:
boundaryText = "\(EncodingCharacters.crlf)--\(boundary)--\(EncodingCharacters.crlf)"
}
return boundaryText.data(using: String.Encoding.utf8, allowLossyConversion: false)!
}
}
网友评论