如何用Moya自定义插件打印网络请求日志
Moya本身不提供详细的日志打印功能,但可以通过自定义插件来实现。以下步骤展示如何创建并配置一个日志插件。
创建自定义日志插件
定义一个遵守PluginType
协议的插件类,实现必要的协议方法:
import Moya
final class NetworkLoggerPlugin: PluginType {
func willSend(_ request: RequestType, target: TargetType) {
guard let urlRequest = request.request else { return }
print("\n🚀 Request:")
print("URL: \(urlRequest.url?.absoluteString ?? "")")
print("Method: \(urlRequest.httpMethod ?? "")")
print("Headers: \(urlRequest.allHTTPHeaderFields ?? [:])")
if let body = urlRequest.httpBody, let bodyString = String(data: body, encoding: .utf8) {
print("Body: \(bodyString)")
}
}
func didReceive(_ result: Result<Response, MoyaError>, target: TargetType) {
switch result {
case .success(let response):
print("\n✅ Response:")
print("Status Code: \(response.statusCode)")
print("Headers: \(response.response?.allHeaderFields ?? [:])")
if let json = try? response.mapJSON() {
print("Response Data: \(json)")
} else if let string = try? response.mapString() {
print("Response Data: \(string)")
}
case .failure(let error):
print("\n❌ Error:")
print("Error: \(error.localizedDescription)")
}
}
}
将插件添加到Moya Provider
创建Moya Provider实例时,将自定义插件添加到plugins数组中:
let provider = MoyaProvider<YourTargetType>(plugins: [NetworkLoggerPlugin()])
优化日志输出格式
如果需要更美观的日志输出,可以改进打印格式:
func willSend(_ request: RequestType, target: TargetType) {
guard let urlRequest = request.request else { return }
let output = """
\n
╔═══════════════════════════════════════════════════════════
║ 🚀 Request
║ URL: \(urlRequest.url?.absoluteString ?? "")
║ Method: \(urlRequest.httpMethod ?? "")
║ Headers: \(urlRequest.allHTTPHeaderFields ?? [:])
║ Body: \(urlRequest.httpBody.flatMap { String(data: $0, encoding: .utf8) } ?? "None")
╚═══════════════════════════════════════════════════════════
"""
print(output)
}
使用第三方日志库
对于更专业的日志记录,可以集成CocoaLumberjack等日志库:
import CocoaLumberjack
final class NetworkLoggerPlugin: PluginType {
func willSend(_ request: RequestType, target: TargetType) {
DDLogInfo("Request: \(request.request?.url?.absoluteString ?? "")")
}
func didReceive(_ result: Result<Response, MoyaError>, target: TargetType) {
switch result {
case .success(let response):
DDLogInfo("Response: \(response.statusCode)")
case .failure(let error):
DDLogError("Error: \(error.localizedDescription)")
}
}
}
过滤敏感信息
在打印日志时,建议过滤掉授权头等敏感信息:
func willSend(_ request: RequestType, target: TargetType) {
guard let urlRequest = request.request else { return }
var headers = urlRequest.allHTTPHeaderFields ?? [:]
headers["Authorization"] = headers["Authorization"] != nil ? "*****" : nil
print("Headers: \(headers)")
}