Pulse is designed to be as least intrusive as possible. It doesn't use swizzling, it doesn't create custom URL protocols. It does only what you ask it to without the risk of interfering with your network communications.
The primary component that you will use to log network requests is NetworkLogger
which is part of PulseUI
framework. It's easy to setup.
import Pulse
import PulseUI
import Logging
// 1. Setup the logging system to use Pulse.PersistentLogHandler
LoggingSystem.bootstrap(PersistentLogHandler.init)
// 2. Create NetworkLogger
let logger = NetworkLogger()
If you want to use
NetworkLogger
with a custom logger (without usingLoggingSystem.bootstrap
), please refer to SwiftLog documentation.
The logs are stored in a database. The request and response bodies are deduplicated and stored in the file system. Old messages and responses are removed when the size limit is reached. For customization options, please refer to NetworkLogger
inline documentation.
There are multiple options for logging network requests using Pulse.
Use URLSessionProxyDelegate
to automatically store all of the requried events.
let urlSession = URLSession(configuration: .default, delegate: URLSessionProxyDelegate(logger: logger, delegate: self), delegateQueue: nil)
// Use `URLSession` as usual.
URLSessionProxyDelegate
is extremely small and simply usesresponds(to:)
andforwardingTarget(for:)
methods to forward selectors to the actual session delegate when needed.
While you can use PulseUI.URLSessionProxyDelegate
, the recommended approach is to use Alamofire.EventMonitor
.
import Alamofire
// Don't forget to bootstrap the logging systme first.
let session = Alamofire.Session(eventMonitors: [NetworkLoggerEventMonitor(logger: logger)])
struct NetworkLoggerEventMonitor: EventMonitor {
let logger: NetworkLogger
func request(_ request: Request, didCreateTask task: URLSessionTask) {
logger.logTaskCreated(task)
}
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
logger.logDataTask(dataTask, didReceive: data)
}
func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) {
logger.logTask(task, didFinishCollecting: metrics)
}
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
logger.logTask(task, didCompleteWithError: error)
}
}
If none of the previous options work for you, you can use NetworkLogger
directly to log the network events. While technically none of the logs are required, you want to the very least log data, metrics, and completion events.
final class NetworkLogger {
func logTaskCreated(_ task: URLSessionTask)
func logDataTask(_ dataTask: URLSessionDataTask, didReceive response: URLResponse)
func logDataTask(_ dataTask: URLSessionDataTask, didReceive data: Data)
func logTask(_ task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics)
func logTask(_ task: URLSessionTask, didCompleteWithError error: Error?)
}