Skip to content

Commit

Permalink
Add support for OSLog (#9)
Browse files Browse the repository at this point in the history
* Add support for OSLog
  • Loading branch information
mdb1 committed Mar 19, 2024
1 parent b7fb577 commit 6b313bc
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 135 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/swift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
runs-on: macos-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Build
run: swift build -v
- name: Run tests
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import PackageDescription
let package = Package(
name: "CoreNetworking",
platforms: [
.iOS(.v15),
.iOS(.v16),
.macOS(.v12)
],
products: [
Expand Down
87 changes: 2 additions & 85 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,91 +26,8 @@ HTTPClient.shared.networkLogger = .init(

### Success Example:

```swift
🛜 ===> Network Request started:
3 key/value pairs
(2 elements)
- key: "Request\'s Internal Id"
- value: "[CA5C3]"
(2 elements)
- key: "URL"
- value: "https://catfact.ninja/fact/?"
(2 elements)
- key: "HTTP Method"
- value: "GET"
🛜 <==== Network Response received:
3 key/value pairs
(2 elements)
- key: "Status Code"
- value: "200"
(2 elements)
- key: "Request\'s Internal Id"
- value: "[CA5C3]"
(2 elements)
- key: "URL"
- value: "https://catfact.ninja/fact/?"
==> JSON Decoding start:
CoreNetworkingTests.CatFact
- fact: "Cats are now Britain\'s favourite pet: there are 7.7 million cats as opposed to 6.6 million dogs."
- length: 96
ℹ️ Additional Info:
ℹ️ 🔍 Expected Model: CatFact
ℹ️ 📝 Pretty Printed JSON:
{
"fact" : "Cats are now Britain's favourite pet: there are 7.7 million cats as opposed to 6.6 million dogs.",
"length" : 96
}
<== JSON Decoding end.
🏁 <==== Network Request finished.
```
![success](/resources/network-success.png)

### Decoding Issue Example:

```swift
🛜 ===> Network Request started:
3 key/value pairs
(2 elements)
- key: "HTTP Method"
- value: "GET"
(2 elements)
- key: "Request\'s Internal Id"
- value: "[79B5E]"
(2 elements)
- key: "URL"
- value: "https://catfact.ninja/facts/?"
🛜 <==== Network Response received:
3 key/value pairs
(2 elements)
- key: "Request\'s Internal Id"
- value: "[79B5E]"
(2 elements)
- key: "Status Code"
- value: "200"
(2 elements)
- key: "URL"
- value: "https://catfact.ninja/facts/?"
==> JSON Decoding issue start:
Error description: Key 'CodingKeys(stringValue: "fact", intValue: nil)' not found
ℹ️ Additional Info:
ℹ️ 🔍 Expected Model: CatFact
ℹ️ 📝 Pretty Printed JSON:
{
"last_page_url" : "https:\/\/catfact.ninja\/facts?page=34",
"prev_page_url" : null,
"from" : 1,
"total" : 332,
"path" : "https:\/\/catfact.ninja\/facts",
"first_page_url" : "https:\/\/catfact.ninja\/facts?page=1",
"last_page" : 34,
"next_page_url" : "https:\/\/catfact.ninja\/facts?page=2",
"current_page" : 1,
"per_page" : 10,
"to" : 10
}
1 key/value pair
(2 elements)
- key: "Context"
- value: "No value associated with key CodingKeys(stringValue: \"fact\", intValue: nil) (\"fact\")."
<== JSON Decoding issue end.
🏁 <==== Network Request finished.
```
![error](/resources/network-error.png)
8 changes: 8 additions & 0 deletions Sources/CoreNetworking/Current.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Foundation
import OSLog

let Current = World()

struct World {
var logger: Logger { Logger(subsystem: "CoreNetworking", category: "CoreNetworking") }
}
30 changes: 19 additions & 11 deletions Sources/CoreNetworking/Extension/Data+PrettyPrinted.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,25 @@ import Foundation

extension Data {
var prettyPrintedJSONString: NSString {
guard let object = try? JSONSerialization.jsonObject(
with: self,
options: []
), let data = try? JSONSerialization.data(
withJSONObject: object,
options: [.prettyPrinted]
), let prettyPrintedString = NSString(
data: data,
encoding: String.Encoding.utf8.rawValue
) else { return "" }
guard let object = try? JSONSerialization.jsonObject(with: self, options: []),
let data = try? JSONSerialization.data(withJSONObject: object, options: [.prettyPrinted]),
var prettyPrintedString = String(data: data, encoding: .utf8) else {
return ""
}

return prettyPrintedString
prettyPrintedString = prettyPrintedString.replacingOccurrences(of: "\\/", with: "/")
return prettyPrintedString as NSString
}
}

extension Dictionary where Key == String, Value == Any {
func toJSONData() -> Data? {
do {
let jsonData = try JSONSerialization.data(withJSONObject: self, options: [.prettyPrinted])
return jsonData
} catch {
Current.logger.error("Error converting dictionary to JSON data: \(error.localizedDescription)")
return nil
}
}
}
4 changes: 1 addition & 3 deletions Sources/CoreNetworking/HTTPClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,11 @@ public class HTTPClient {
_ request: Request,
responseType: Response.Type
) async throws -> Response {
defer { networkLogger.logRequestFinished() }

networkLogger.logRequest(request)
let (data, response) = try await URLSession.shared.data(
for: request.urlRequest,
delegate: nil
)
networkLogger.logRequest(request)

guard let response = response as? HTTPURLResponse else {
throw Request.RequestError.noResponse
Expand Down
60 changes: 26 additions & 34 deletions Sources/CoreNetworking/NetworkLogger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ public struct NetworkLogger {
case let .verbose(logRequests, _):
guard logRequests else { return }

print("🛜 ===> Network Request started:")
dump(request.logProperties)
Current.logger.debug("""
🛜 ===> Network Request started:
\(request.logProperties.toJSONData()?.prettyPrintedJSONString)
""")
case .quiet:
return
}
Expand All @@ -40,14 +42,16 @@ public struct NetworkLogger {
switch configuration {
case let .verbose(_, logResponses):
guard logResponses else { return }

print("🛜 <==== Network Response received:")
var logProperties: [String: Any] = [:]
logProperties["Request's Internal Id"] = request.internalId
logProperties.merge(response.logProperties) { _, new in
new
}
dump(logProperties)

Current.logger.debug("""
🛜 <==== Network Response received:"
\(logProperties.toJSONData()?.prettyPrintedJSONString)
""")

case .quiet:
return
Expand All @@ -59,13 +63,12 @@ public struct NetworkLogger {
case let .verbose(_, logResponses):
guard logResponses else { return }

print("✅ ==> JSON Decoding start:")
dump(model)
print("ℹ️ Additional Info:")
print("ℹ️ 🔍 Expected Model: \(type)")
print("ℹ️ 📝 Pretty Printed JSON:")
print(data.prettyPrintedJSONString)
print("✅ <== JSON Decoding end.")
Current.logger.debug("""
✅ ==> JSON Decoding Success:
ℹ️ 🔍 Expected Model: \(type)
ℹ️ 📝 Pretty Printed JSON:
\(data.prettyPrintedJSONString)
""")
case .quiet:
return
}
Expand All @@ -76,7 +79,7 @@ public struct NetworkLogger {
case let .verbose(_, logResponses):
guard logResponses else { return }
var errorDescription: String = ""
var logProperties: [String: String] = [:]
var logProperties: [String: Any] = [:]

if let decodingError = error as? DecodingError {
switch decodingError {
Expand All @@ -102,26 +105,15 @@ public struct NetworkLogger {
}
}

print("❌ ==> JSON Decoding issue start:")
print("Error description: \(errorDescription)")
print("ℹ️ Additional Info:")
print("ℹ️ 🔍 Expected Model: \(type)")
print("ℹ️ 📝 Pretty Printed JSON:")
print(data.prettyPrintedJSONString)
dump(logProperties)
print("❌ <== JSON Decoding issue end.")
case .quiet:
return
}
}

func logRequestFinished() {
switch configuration {
case let .verbose(_, logResponses):
guard logResponses else { return }

print("🏁 <==== Network Request finished.")
print("")
Current.logger.error("""
❌ ==> JSON Decoding issue:
Error description: \(errorDescription)
ℹ️ 🔍 Expected Model: \(type)
ℹ️ 📝 Pretty Printed JSON:
\(data.prettyPrintedJSONString)
ℹ️ 📝 Underlying decoding issue:
\(logProperties.toJSONData()?.prettyPrintedJSONString)
""")
case .quiet:
return
}
Expand All @@ -132,7 +124,7 @@ private extension NetworkLogger {
/// Add Decoding Error context information to the dictionary.
func addContext(
_ context: DecodingError.Context,
logProperties: inout [String: String]
logProperties: inout [String: Any]
) {
logProperties["Context"] = context.debugDescription
if context.codingPath.count > 0 {
Expand Down
Binary file added resources/network-error.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added resources/network-success.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 6b313bc

Please sign in to comment.