ios 如何使用 Alamofire 记录每个请求/响应?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26736428/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I log each request/response using Alamofire?
提问by Cosmin
Is there a way to log each request / response using Alamofire (something similar to AFNetworkActivityLogger) ?
有没有办法使用 Alamofire(类似于 AFNetworkActivityLogger)记录每个请求/响应?
I am aware of Printable, DebugPrintable and Output (cURL) but they are not quite what I am looking for.
我知道 Printable、DebugPrintable 和 Output (cURL) 但它们并不是我想要的。
回答by clozach
Something like this might be what you were looking for:
像这样的东西可能就是你要找的:
extension Request {
public func debugLog() -> Self {
#if DEBUG
debugPrint(self)
#endif
return self
}
}
Usage:
用法:
Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
.debugLog()
.response {…}
If you want to print all responses, you could write your own response method, similar to the responseObject() method at the top of this tutorial:
如果要打印所有响应,可以编写自己的响应方法,类似于本教程顶部的 responseObject() 方法:
http://www.raywenderlich.com/87595/intermediate-alamofire-tutorial
http://www.raywenderlich.com/87595/intermediate-alamofire-tutorial
[Update: added below per the request from @trauzti.]
[更新:根据@trauzti 的要求在下面添加。]
Here's how one might do the responseObject() approach in order to print output on everyrequest.
下面是如何使用 responseObject() 方法来打印每个请求的输出。
Caveat lector: I haven't personally tested this code, and would probably make different choices in production. This simply shows how the Wenderlich tutorial code can include debug logging. Also note: since the tutorial is pre-Swift 2.0, I've used the old println() instead of print().
警告 lector:我没有亲自测试过这段代码,可能会在生产中做出不同的选择。这只是展示了 Wenderlich 教程代码如何包含调试日志。另请注意:由于本教程是 Swift 2.0 之前的版本,因此我使用了旧的 println() 而不是 print()。
@objc public protocol ResponseObjectSerializable {
init(response: NSHTTPURLResponse, representation: AnyObject)
}
extension Alamofire.Request {
public func responseObject<T: ResponseObjectSerializable>(completionHandler: (NSURLRequest, NSHTTPURLResponse?, T?, NSError?) -> Void) -> Self {
let serializer: Serializer = { (request, response, data) in
#if DEBUG
println("Request: \(request.URL)")
#endif
let JSONSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
let (JSON: AnyObject?, serializationError) = JSONSerializer(request, response, data)
if response != nil && JSON != nil {
#if DEBUG
println("Response:")
debugPrint(JSON)
#endif
return (T(response: response!, representation: JSON!), nil)
} else {
#if DEBUG
println("Failed Serialization:")
debugPrint(serializationError)
#endif
return (nil, serializationError)
}
}
return response(serializer: serializer, completionHandler: { (request, response, object, error) in
completionHandler(request, response, object as? T, error)
})
}
}
回答by ullstrm
There's a sweet little pod for this: https://github.com/konkab/AlamofireNetworkActivityLogger
有一个可爱的小吊舱:https: //github.com/konkab/AlamofireNetworkActivityLogger
Add this to your podfile:
将此添加到您的 podfile:
pod 'AlamofireNetworkActivityLogger', '~> 2.0'
In your AppDelegate:
在您的 AppDelegate 中:
import AlamofireNetworkActivityLogger
Then in your didFinishLaunchingWithOptions
, add this:
然后在您的 中didFinishLaunchingWithOptions
,添加以下内容:
NetworkActivityLogger.shared.level = .debug
NetworkActivityLogger.shared.startLogging()
EDIT: I've actually encountered crashes with this in production. To be on the safe side, use "build flags" to only use this in debug, something like this:
编辑:我实际上在生产中遇到过崩溃。为了安全起见,使用“构建标志”仅在调试中使用它,如下所示:
#if DEBUG
NetworkActivityLogger.shared.level = .debug
NetworkActivityLogger.shared.startLogging()
#endif
回答by ali
TimberHyman is what you are looking. TimberHyman is a simple, unintrusive network activity logger. Log every request your app makes, or limit to only those using a certain NSURLSession if you'd prefer. It also works with Alamofire, if that's your thing.
TimberHyman 就是你要找的。TimberHyman 是一个简单的、非侵入式的网络活动记录器。记录您的应用程序发出的每个请求,或者如果您愿意,只限于使用特定 NSURLSession 的那些请求。它也适用于 Alamofire,如果这是你的事。
https://cocoapods.org/pods/TimberHyman
https://cocoapods.org/pods/TimberHyman
usage:
用法:
import Alamofire
import TimberHyman
class HTTPManager: Alamofire.Manager {
static let sharedManager: HTTPManager = {
let configuration = TimberHyman.defaultSessionConfiguration()
let manager = HTTPManager(configuration: configuration)
return manager
}()
}
回答by 0xced
Since Alamofire 5, the easiest way is to define an EventMonitor
subclass:
从 Alamofire 5 开始,最简单的方法是定义一个EventMonitor
子类:
final class AlamofireLogger: EventMonitor {
func requestDidResume(_ request: Request) {
let body = request.request.flatMap { let session = Session(eventMonitors: [ AlamofireLogger() ])
.httpBody.map { String(decoding: extension DataRequest {
public func LogRequest() -> Self {
//Your logic for logging
return self
}
}
, as: UTF8.self) } } ?? "None"
let message = """
?? Request Started: \(request)
?? Body Data: \(body)
"""
NSLog(message)
}
func request<Value>(_ request: DataRequest, didParseResponse response: DataResponse<Value>) {
NSLog("?? Response Received: \(response.debugDescription)")
}
}
Then use it on your session:
然后在您的会话中使用它:
Alamofire.request(requestUrl, method: .post, parameters: parameter, encoding: JSONEncoding.default)
.LogRequest()
.responseJSON { response in
//Do your thing
}
This sample code was adapted from https://github.com/Alamofire/Alamofire/issues/2867#issuecomment-509662892
此示例代码改编自https://github.com/Alamofire/Alamofire/issues/2867#issuecomment-509662892
回答by vinbhai4u
Adding to above answer for Alamofire 4.0+ Swift 3
添加到 Alamofire 4.0+ Swift 3 的上述答案
import Alamofire
final class AlamofireLogger: EventMonitor {
func requestDidResume(_ request: Request) {
let allHeaders = request.request.flatMap { let session = Session(eventMonitors: [ AlamofireLogger() ])
.allHTTPHeaderFields.map { Alamofire.request(url, method: .get, parameters: parameters, headers: headers)
.validate()
.responseObject { (response: DataResponse<T>) in
self.pendingRequests.removeValue(forKey: endPoint)
completion!(response)
if(NetworkConfig.loggingEnable) {
debugPrint("************* printing REQUEST parameter and Headers *************")
debugPrint("RESPONSE : \(response.debugDescription)")
}
}.responseDebugPrint()
.description } } ?? "None"
let headers = """
???????? Request Started: \(request)
???????? Headers: \(allHeaders)
"""
NSLog(headers)
let body = request.request.flatMap { import Foundation
import Alamofire
extension Alamofire.DataRequest {
func responseDebugPrint() -> Self {
if NetworkConfig.loggingEnable {
return responseJSON() {
response in
if let JSON = response.result.value,
let JSONData = try? JSONSerialization.data(withJSONObject: JSON, options: .prettyPrinted),
let prettyString = NSString(data: JSONData, encoding: String.Encoding.utf8.rawValue) {
print(prettyString)
} else if let error = response.result.error {
print("Error Debug Print: \(error.localizedDescription)")
}
}
}
return self
}
}
.httpBody.map { String(decoding: ##代码##, as: UTF8.self) } } ?? "None"
let message = """
???????? Request Started: \(request)
???????? Body Data: \(body)
"""
NSLog(message)
}
func request<Value>(_ request: DataRequest, didParseResponse response: AFDataResponse<Value>) {
NSLog("???????? Response Received: \(response.debugDescription)")
NSLog("???????? Response All Headers: \(String(describing: response.response?.allHeaderFields))")
}
}
When Requesting
请求时
##代码##If you want to cancel the request in any case(which was something I wanted) you can self.cancel()
anywhere before you return self
如果你想在任何情况下取消请求(这是我想要的)你可以self.cancel()
在你返回之前的任何地方
回答by Genar
In Alamofire 5.0.0 I used the answer based on: https://github.com/Alamofire/Alamofire/issues/2867#issuecomment-509662892but I had to replace DataResponse by AFDataResponse. For example:
在 Alamofire 5.0.0 中,我使用了基于以下内容的答案:https: //github.com/Alamofire/Alamofire/issues/2867#issuecomment-509662892但我不得不用 AFDataResponse 替换 DataResponse。例如:
##代码##And then you can use it in the following way:
然后您可以通过以下方式使用它:
##代码##As it has explained by 0xced in an aforementioned post.
正如 0xced 在上述帖子中所解释的那样。
回答by MANISH PATHAK
SOLUTION FOR SWIFT 3.0+
Swift 3.0+ 解决方案
For Printing Request parameter and headers:
对于打印请求参数和标题:
##代码##For Printing Response. use below extension .
用于打印响应。使用以下扩展名。
##代码##Small gist for you : https://gist.github.com/manishpathak99/348f2eb0167c0ff6e12ecd667612bc9b/edit
给你的小要点:https: //gist.github.com/manishpathak99/348f2eb0167c0ff6e12ecd667612bc9b/edit