Showing
1 changed file
with
131 additions
and
1 deletions
... | @@ -35,7 +35,7 @@ extension UIDevice { | ... | @@ -35,7 +35,7 @@ extension UIDevice { |
35 | let machineMirror = Mirror(reflecting: systemInfo.machine) | 35 | let machineMirror = Mirror(reflecting: systemInfo.machine) |
36 | let identifier = machineMirror.children.reduce("") { identifier, element in | 36 | let identifier = machineMirror.children.reduce("") { identifier, element in |
37 | guard let value = element.value as? Int8, value != 0 else { return identifier } | 37 | guard let value = element.value as? Int8, value != 0 else { return identifier } |
38 | - return identifier + String(UnicodeScalar(UInt8(value))!) | 38 | + return identifier + String(UnicodeScalar(UInt8(value))) |
39 | } | 39 | } |
40 | return identifier | 40 | return identifier |
41 | } | 41 | } |
... | @@ -182,16 +182,27 @@ public final class NetworkService: NetworkServiceProtocol { | ... | @@ -182,16 +182,27 @@ public final class NetworkService: NetworkServiceProtocol { |
182 | private func performRequest(_ endpoint: Endpoint) async throws -> Data { | 182 | private func performRequest(_ endpoint: Endpoint) async throws -> Data { |
183 | // Check network connectivity | 183 | // Check network connectivity |
184 | guard isConnected else { | 184 | guard isConnected else { |
185 | + print("🔴 [NetworkService] No internet connection") | ||
185 | throw NetworkError.networkError(NSError(domain: "NetworkService", code: -1009, userInfo: [NSLocalizedDescriptionKey: "No internet connection"])) | 186 | throw NetworkError.networkError(NSError(domain: "NetworkService", code: -1009, userInfo: [NSLocalizedDescriptionKey: "No internet connection"])) |
186 | } | 187 | } |
187 | 188 | ||
188 | let request = try buildRequest(for: endpoint) | 189 | let request = try buildRequest(for: endpoint) |
189 | 190 | ||
191 | + // 📤 LOG REQUEST DETAILS | ||
192 | + logRequest(request, endpoint: endpoint) | ||
193 | + | ||
190 | do { | 194 | do { |
191 | let (data, response) = try await session.data(for: request) | 195 | let (data, response) = try await session.data(for: request) |
196 | + | ||
197 | + // 📥 LOG RESPONSE DETAILS | ||
198 | + logResponse(response, data: data, endpoint: endpoint) | ||
199 | + | ||
192 | try validateResponse(response) | 200 | try validateResponse(response) |
193 | return data | 201 | return data |
194 | } catch { | 202 | } catch { |
203 | + // 🔴 LOG ERROR DETAILS | ||
204 | + logError(error, endpoint: endpoint) | ||
205 | + | ||
195 | // Handle token refresh if needed | 206 | // Handle token refresh if needed |
196 | if let httpResponse = error as? HTTPURLResponse, httpResponse.statusCode == 401 { | 207 | if let httpResponse = error as? HTTPURLResponse, httpResponse.statusCode == 401 { |
197 | if endpoint.requiresAuthentication { | 208 | if endpoint.requiresAuthentication { |
... | @@ -358,6 +369,125 @@ public final class NetworkService: NetworkServiceProtocol { | ... | @@ -358,6 +369,125 @@ public final class NetworkService: NetworkServiceProtocol { |
358 | throw NetworkError.serverError(httpResponse.statusCode) | 369 | throw NetworkError.serverError(httpResponse.statusCode) |
359 | } | 370 | } |
360 | } | 371 | } |
372 | + | ||
373 | + // MARK: - Logging Methods | ||
374 | + | ||
375 | + /// Log detailed request information | ||
376 | + private func logRequest(_ request: URLRequest, endpoint: Endpoint) { | ||
377 | + print("\n📤 [NetworkService] REQUEST") | ||
378 | + print("🔗 URL: \(request.url?.absoluteString ?? "Unknown")") | ||
379 | + print("🔧 Method: \(request.httpMethod ?? "Unknown")") | ||
380 | + print("⏱️ Timeout: \(request.timeoutInterval)s") | ||
381 | + | ||
382 | + // Log headers | ||
383 | + print("📋 Headers:") | ||
384 | + if let headers = request.allHTTPHeaderFields { | ||
385 | + for (key, value) in headers.sorted(by: { $0.key < $1.key }) { | ||
386 | + // Mask sensitive headers for security | ||
387 | + let maskedValue = maskSensitiveHeader(key: key, value: value) | ||
388 | + print(" \(key): \(maskedValue)") | ||
389 | + } | ||
390 | + } else { | ||
391 | + print(" (No headers)") | ||
392 | + } | ||
393 | + | ||
394 | + // Log body | ||
395 | + if let body = request.httpBody { | ||
396 | + print("📦 Body Size: \(body.count) bytes") | ||
397 | + if let bodyString = String(data: body, encoding: .utf8) { | ||
398 | + print("📦 Body Content: \(bodyString)") | ||
399 | + } else { | ||
400 | + print("📦 Body Content: (Binary data)") | ||
401 | + } | ||
402 | + } else { | ||
403 | + print("📦 Body: (No body)") | ||
404 | + } | ||
405 | + | ||
406 | + print("🎯 Endpoint Info:") | ||
407 | + print(" Path: \(endpoint.path)") | ||
408 | + print(" Requires Auth: \(endpoint.requiresAuthentication)") | ||
409 | + print(" Parameters: \(endpoint.parameters?.count ?? 0) items") | ||
410 | + print("===============================") | ||
411 | + } | ||
412 | + | ||
413 | + /// Log detailed response information | ||
414 | + private func logResponse(_ response: URLResponse, data: Data, endpoint: Endpoint) { | ||
415 | + print("\n📥 [NetworkService] RESPONSE") | ||
416 | + print("🔗 URL: \(response.url?.absoluteString ?? "Unknown")") | ||
417 | + | ||
418 | + if let httpResponse = response as? HTTPURLResponse { | ||
419 | + let statusEmoji = httpResponse.statusCode >= 200 && httpResponse.statusCode < 300 ? "✅" : "❌" | ||
420 | + print("\(statusEmoji) Status: \(httpResponse.statusCode)") | ||
421 | + | ||
422 | + // Log response headers | ||
423 | + print("📋 Response Headers:") | ||
424 | + for (key, value) in httpResponse.allHeaderFields.sorted(by: { "\($0.key)" < "\($1.key)" }) { | ||
425 | + print(" \(key): \(value)") | ||
426 | + } | ||
427 | + } | ||
428 | + | ||
429 | + print("📦 Response Size: \(data.count) bytes") | ||
430 | + | ||
431 | + // Log response body | ||
432 | + if let responseString = String(data: data, encoding: .utf8) { | ||
433 | + print("📦 Response Body:") | ||
434 | + // Pretty print JSON if possible | ||
435 | + if let jsonData = responseString.data(using: .utf8), | ||
436 | + let jsonObject = try? JSONSerialization.jsonObject(with: jsonData, options: []), | ||
437 | + let prettyData = try? JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted), | ||
438 | + let prettyString = String(data: prettyData, encoding: .utf8) { | ||
439 | + print(prettyString) | ||
440 | + } else { | ||
441 | + print(responseString) | ||
442 | + } | ||
443 | + } else { | ||
444 | + print("📦 Response Body: (Binary data)") | ||
445 | + } | ||
446 | + print("===============================") | ||
447 | + } | ||
448 | + | ||
449 | + /// Log error information | ||
450 | + private func logError(_ error: Error, endpoint: Endpoint) { | ||
451 | + print("\n🔴 [NetworkService] ERROR") | ||
452 | + print("🔗 Endpoint: \(endpoint.path)") | ||
453 | + print("❌ Error: \(error.localizedDescription)") | ||
454 | + | ||
455 | + if let urlError = error as? URLError { | ||
456 | + print("🌐 URL Error Code: \(urlError.code.rawValue)") | ||
457 | + print("🌐 URL Error Description: \(urlError.localizedDescription)") | ||
458 | + } | ||
459 | + | ||
460 | + if let httpResponse = (error as NSError).userInfo["response"] as? HTTPURLResponse { | ||
461 | + print("📊 HTTP Status: \(httpResponse.statusCode)") | ||
462 | + } | ||
463 | + | ||
464 | + print("🔍 Error Details: \(error)") | ||
465 | + print("===============================") | ||
466 | + } | ||
467 | + | ||
468 | + /// Mask sensitive header values for security | ||
469 | + private func maskSensitiveHeader(key: String, value: String) -> String { | ||
470 | + let sensitiveHeaders = [ | ||
471 | + "authorization", | ||
472 | + "loyalty-signature", | ||
473 | + "access-token", | ||
474 | + "refresh-token", | ||
475 | + "api-key", | ||
476 | + "x-api-key" | ||
477 | + ] | ||
478 | + | ||
479 | + if sensitiveHeaders.contains(key.lowercased()) { | ||
480 | + if value.count > 8 { | ||
481 | + let prefix = String(value.prefix(4)) | ||
482 | + let suffix = String(value.suffix(4)) | ||
483 | + return "\(prefix)***\(suffix)" | ||
484 | + } else { | ||
485 | + return "***" | ||
486 | + } | ||
487 | + } | ||
488 | + | ||
489 | + return value | ||
490 | + } | ||
361 | } | 491 | } |
362 | 492 | ||
363 | // MARK: - Network Service Extensions | 493 | // MARK: - Network Service Extensions | ... | ... |
-
Please register or login to post a comment