如何使用 Alamofire 记录每个请求/响应?

是否有使用 Alamofire (类似于 AFNetworkActivityLogger)记录每个请求/响应的方法?

我知道 Printable,DebugPrintable 和 Output (cURL) ,但它们并不是我想要的。

45793 次浏览

这可能就是你要找的东西:

extension Request {
public func debugLog() -> Self {
#if DEBUG
debugPrint(self)
#endif
return self
}
}

用法:

Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
.debugLog()
.response {…}

如果您想打印所有的响应,您可以编写您自己的响应方法,类似于本教程顶部的 responseObject ()方法:

Http://www.raywenderlich.com/87595/intermediate-alamofire-tutorial

[更新: 根据@trauzti 的请求添加到下面。]

下面介绍如何使用 response seObject ()方法在 每个请求上打印输出。

注意: 我还没有亲自测试过这段代码,可能会在生产环境中做出不同的选择。这只是展示了 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)
})
}
}

你要找的是伐木工人。 Timberjack 是一个简单的、不受干扰的网络活动记录器。记录你的应用程序发出的每一个请求,或者如果你愿意的话,只限于那些使用某个 NSULSession 的请求。如果你喜欢 Alamofire 也可以。

Https://cocoapods.org/pods/timberjack

用途:

import Alamofire
import Timberjack


class HTTPManager: Alamofire.Manager {
static let sharedManager: HTTPManager = {
let configuration = Timberjack.defaultSessionConfiguration()
let manager = HTTPManager(configuration: configuration)
return manager
}()
}

补充上述答案 支持 Alamofire 4.0 + Swift 3

extension DataRequest {
public func LogRequest() -> Self {
//Your logic for logging
return self
}
}

请求时

Alamofire.request(requestUrl, method: .post, parameters: parameter, encoding: JSONEncoding.default)
.LogRequest()
.responseJSON { response in
//Do your thing
}

如果你想取消请求在任何情况下(这是我想要的东西) ,你可以 self.cancel()任何地方之前,你返回自己

有一个可爱的小豆荚: https://github.com/konkab/AlamofireNetworkActivityLogger

把这个添加到你的 podfile:

pod 'AlamofireNetworkActivityLogger', '~> 2.0'

在你的应用程序中代表:

import AlamofireNetworkActivityLogger

然后在你的 didFinishLaunchingWithOptions里加上这个:

NetworkActivityLogger.shared.level = .debug
NetworkActivityLogger.shared.startLogging()

编辑: 我在生产过程中碰到过这样的事故。为了安全起见,只在调试中使用“构建标志”,如下所示:

#if DEBUG
NetworkActivityLogger.shared.level = .debug
NetworkActivityLogger.shared.startLogging()
#endif

SWIFT 3.0 + 的解决方案

用于打印请求参数和标题:

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()

若要打印响应 ,请使用下面的扩展名。

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
}
}

给你个小建议: Https://gist.github.com/manishpathak99/348f2eb0167c0ff6e12ecd667612bc9b/edit

自 Alamofire 5以来,最简单的方法是定义一个 EventMonitor子类:

final class AlamofireLogger: EventMonitor {
func requestDidResume(_ request: Request) {
let body = request.request.flatMap { $0.httpBody.map { String(decoding: $0, 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)")
}
}

然后在你的 会议上使用它:

let session = Session(eventMonitors: [ AlamofireLogger() ])

此示例代码改编自 https://github.com/Alamofire/Alamofire/issues/2867#issuecomment-509662892

在 Alamofire 5.0.0中,我使用的答案是基于: Https://github.com/alamofire/alamofire/issues/2867#issuecomment-509662892 但是我必须用 AFDataResponse 代替 DataResponse,例如:

import Alamofire


final class AlamofireLogger: EventMonitor {


func requestDidResume(_ request: Request) {


let allHeaders = request.request.flatMap { $0.allHTTPHeaderFields.map { $0.description } } ?? "None"
let headers = """
⚡️⚡️⚡️⚡️ Request Started: \(request)
⚡️⚡️⚡️⚡️ Headers: \(allHeaders)
"""
NSLog(headers)




let body = request.request.flatMap { $0.httpBody.map { String(decoding: $0, 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))")
}
}

然后你可以用下面的方式使用它:

let session = Session(eventMonitors: [ AlamofireLogger() ])

正如前面提到的一篇文章中所解释的那样。

在 Alamofire 5 URLRequest 是异步创建的,这意味着

extension Request {
public func debugLog() -> Self {
#if DEBUG
debugPrint(self)
#endif
return self
}
}

不再是最好的解决方案。相反,建议拨打 cURLDescription如下:

let request = AF.request(<Your request>))
request.cURLDescription { (curl) in
print("CURL \(curl)")
}
request.responseJSON { response in
//Do something with your response...
}

或者

extension Request {
public func debugLog() -> Self {
#if DEBUG
cURLDescription(calling: { (curl) in
debugPrint("=======================================")
print(curl)
debugPrint("=======================================")
})
#endif
return self
}
}

在 Alamofire 5及以上版本中,你可以通过以下代码获得 curl请求的详细信息:

request.cURLDescription(calling: { (curl) in
print(curl)
})

以及响应/错误数据:

request.responseDecodable { (response:AFDataResponse<T>) in
            

switch response.result {
case .success(let value):
                

var responseMessage : String?
                

if let data = response.data {
let json = String(data: data, encoding: String.Encoding.utf8)
responseMessage = String(describing: json)
}
                

print(responseMessage)
                

break;
                

case .failure(let error):
                

var message : String?
                

if let data = response.data {
let json = String(data: data, encoding: String.Encoding.utf8)
message = String(describing: json)
}
                

print(message)
                

break
}
            

}

Alamofire 通过 EventMonitor协议提供了一个强大的方法来获得对所有内部事件的深入了解。EventMonitor包括几个 Alamofire 事件,例如 URLSessionDelegate请求事件。这使得 EventMonitor成为记录事件的理想工具。

import Alamofire


class NetworkLogger: EventMonitor {
  

let queue = DispatchQueue(label: "com.company.project.networklogger")
  

func requestDidFinish(_ request: Request) {
print(request.description)
}
  

func request<Value>(
_ request: DataRequest,
didParseResponse response: DataResponse<Value, AFError>
) {
guard let data = response.data else {
return
}
if let json = try? JSONSerialization
.jsonObject(with: data, options: .mutableContainers) {
print(json)
}
}
}

参考资料: https://www.raywenderlich.com/11668143-alamofire-tutorial-for-ios-advanced-usage#toc-anchor-004