Skip to content

Commit

Permalink
Remove RemoteLoggerURLProtocol automaticRegistration from PulseProxy
Browse files Browse the repository at this point in the history
  • Loading branch information
kean committed Sep 1, 2024
1 parent cbaf186 commit 4448379
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 35 deletions.
23 changes: 23 additions & 0 deletions Sources/Pulse/NetworkLogger/RemoteLoggerURLProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,26 @@ public final class RemoteLoggerURLProtocol: URLProtocol {

static let requestMockedHeaderName = "X-PulseRequestMocked"
}


// MARK: - RemoteLoggerURLProtocol (Automatic Regisration)

extension RemoteLoggerURLProtocol {
@MainActor
static func enableAutomaticRegistration() {
if let lhs = class_getClassMethod(URLSession.self, #selector(URLSession.init(configuration:delegate:delegateQueue:))),
let rhs = class_getClassMethod(URLSession.self, #selector(URLSession.pulse_init2(configuration:delegate:delegateQueue:))) {
method_exchangeImplementations(lhs, rhs)
}
}
}

private extension URLSession {
@objc class func pulse_init2(configuration: URLSessionConfiguration, delegate: URLSessionDelegate?, delegateQueue: OperationQueue?) -> URLSession {
guard isConfiguringSessionSafe(delegate: delegate) else {
return self.pulse_init2(configuration: configuration, delegate: delegate, delegateQueue: delegateQueue)
}
configuration.protocolClasses = [RemoteLoggerURLProtocol.self] + (configuration.protocolClasses ?? [])
return self.pulse_init2(configuration: configuration, delegate: delegate, delegateQueue: delegateQueue)
}
}
36 changes: 34 additions & 2 deletions Sources/Pulse/Pulse.docc/Articles/NetworkLogging-Article.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,42 @@
# Capturing Network Requests

Learn how to enable network logging.
Learn how to enable and configure network logging and debugging.

## Overview

Pulse works on the `URLSession` level and it needs access to its callbacks to log network requests and capture network metrics. There are multiple ways to do that and they are all covered in this article.
Pulse works on the `URLSession` level, and it needs access to its callbacks to log network requests and capture network metrics. The framework is modular and provides multiple options that can accommodate almost any system. By the end of this article, you will have a system that:

- Captures network requests and metrics
- Supports debugging features powered by Pulse Pro, such as mocking

## Capture Network Requests

### Option 1 (Quickest): PulseProxy.

**Option 1 (Quickest)**. If you are evaluating the framework, the quickest way to get started is with a proxy from the **PulseProxy** module.

```swift
import PulseProxy

#if DEBUG
NetworkLogger.enableProxy()
#endif
```

> Note: **PulseProxy** uses method swizzling and private APIs and it is not recommended to include it in the production builds of your app.
**Option 2 (Recommended)**. Use ``NetworkLogger/URLSession``, a thin wrapper on top of `URLSession`.

```swift
import Pulse

let session: URLSessionProtocol
#if DEBUG
session = NetworkLogger.URLSession(configuration: .default)
#else
session = URLSession(configuration: .default)
#endif
```

## Proxy Delegate

Expand Down
6 changes: 5 additions & 1 deletion Sources/Pulse/Pulse.docc/Pulse.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ Logger and network inspector for Apple platforms.
### Network Logging

- ``NetworkLogger``
- ``URLSessionProtocol``
- ``URLSessionProxyDelegate``
- ``Experimental``

### Remote Logging

Expand All @@ -30,3 +30,7 @@ Logger and network inspector for Apple platforms.
- ``NetworkTransactionMetricsEntity``
- ``NetworkRequestEntity``
- ``NetworkResponseEntity``

### Deprecated

- ``Experimental``
32 changes: 0 additions & 32 deletions Sources/PulseProxy/URLSessionSwizzler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ extension NetworkLogger {
let proxy = URLSessionSwizzler(logger: logger)
proxy.enable()
URLSessionSwizzler.shared = proxy

RemoteLoggerURLProtocol.enableAutomaticRegistration()
}

func enable() {
Expand Down Expand Up @@ -139,33 +137,3 @@ extension NetworkLogger {
}
}
}

func isConfiguringSessionSafe(delegate: URLSessionDelegate?) -> Bool {
if String(describing: delegate).contains("GTMSessionFetcher") {
return false
}
return true
}

// MARK: - RemoteLoggerURLProtocol (Automatic Regisration)

extension RemoteLoggerURLProtocol {
@MainActor
static func enableAutomaticRegistration() {
if let lhs = class_getClassMethod(URLSession.self, #selector(URLSession.init(configuration:delegate:delegateQueue:))),
let rhs = class_getClassMethod(URLSession.self, #selector(URLSession.pulse_init2(configuration:delegate:delegateQueue:))) {
method_exchangeImplementations(lhs, rhs)
}
}
}

private extension URLSession {
@objc class func pulse_init2(configuration: URLSessionConfiguration, delegate: URLSessionDelegate?, delegateQueue: OperationQueue?) -> URLSession {
guard isConfiguringSessionSafe(delegate: delegate) else {
return self.pulse_init2(configuration: configuration, delegate: delegate, delegateQueue: delegateQueue)
}
configuration.protocolClasses = [RemoteLoggerURLProtocol.self] + (configuration.protocolClasses ?? [])
return self.pulse_init2(configuration: configuration, delegate: delegate, delegateQueue: delegateQueue)
}
}

0 comments on commit 4448379

Please sign in to comment.