3 //  alamofire_activity_logger
 
   5 //  Created by Manuel García-Estañ on 14/9/16.
 
   6 //  Copyright © 2016 manuege. All rights reserved.
 
  11 private let nullString = "(null)"
 
  12 private let separatorString = "*******************************"
 
  15  A set of static methods which logs request and responses
 
  17 internal struct Logger {
 
  19     internal static func logRequest(request: URLRequest?, level: LogLevel, options: [LogOption], printer: Printer) {
 
  21         guard let request = request else {
 
  25         let method = request.httpMethod!
 
  26         let url = request.url?.absoluteString ?? nullString
 
  27         let headers = prettyPrintedString(from: request.allHTTPHeaderFields) ?? nullString
 
  30         let openSeparator = options.contains(.includeSeparator) ? "\(separatorString)\n" : ""
 
  31         let closeSeparator = options.contains(.includeSeparator) ? "\n\(separatorString)" : ""
 
  35             let prettyPrint = options.contains(.jsonPrettyPrint)
 
  36             let body = string(from: request.httpBody, prettyPrint: prettyPrint) ?? nullString
 
  37             printer.print("\(openSeparator)[Request] \(method) '\(url)':\n\n[Headers]\n\(headers)\n\n[Body]\n\(body)\(closeSeparator)", phase: .request)
 
  40             printer.print("\(openSeparator)[Request] \(method) '\(url)'\(closeSeparator)", phase: .request)
 
  47     internal static func logResponse(request: URLRequest?, response: ResponseInfo, level: LogLevel, options: [LogOption], printer: Printer) {
 
  49         guard level != .none else {
 
  53         let httpResponse = response.httpResponse
 
  54         let data = response.data
 
  55         let elapsedTime = response.elapsedTime
 
  56         let error = response.error
 
  58         if request == nil && response.httpResponse == nil {
 
  63         let prettyPrint = options.contains(.jsonPrettyPrint)
 
  66         let requestMethod = request?.httpMethod ?? nullString
 
  67         let requestUrl = request?.url?.absoluteString ?? nullString
 
  70         let responseStatusCode = httpResponse?.statusCode ?? 0
 
  71         let responseHeaders = prettyPrintedString(from: httpResponse?.allHeaderFields) ?? nullString
 
  72         let responseData = string(from: data, prettyPrint: prettyPrint) ?? nullString
 
  75         let elapsedTimeString = String(format: "[%.4f s]", elapsedTime)
 
  78         let openSeparator = options.contains(.includeSeparator) ? "\(separatorString)\n" : ""
 
  79         let closeSeparator = options.contains(.includeSeparator) ? "\n\(separatorString)" : ""
 
  82         let success = (error == nil)
 
  83         let responseTitle = success ? "Response" : "Response Error"
 
  86             printer.print("\(openSeparator)[\(responseTitle)] \(responseStatusCode) '\(requestUrl)' \(elapsedTimeString):\n\n[Headers]:\n\(responseHeaders)\n\n[Body]\n\(responseData)\(closeSeparator)", phase: .response(success: success))
 
  88             printer.print("\(openSeparator)[\(responseTitle)] \(responseStatusCode) '\(requestUrl)' \(elapsedTimeString)\(closeSeparator)", phase: .response(success: success))
 
  90             if let error = error {
 
  91                 printer.print("\(openSeparator)[\(responseTitle)] \(requestMethod) '\(requestUrl)' \(elapsedTimeString) s: \(error)\(closeSeparator)", phase: .response(success: success))
 
  98     // MARK: - Private helpers
 
  99     private static func string(from data: Data?, prettyPrint: Bool) -> String? {
 
 101         guard let data = data else {
 
 105         var response: String? = nil
 
 108             let json = try? JSONSerialization.jsonObject(with: data, options: []),
 
 109             let prettyString = prettyPrintedString(from: json) {
 
 110             response = prettyString
 
 113         else if let dataString = String.init(data: data, encoding: .utf8) {
 
 114             response = dataString
 
 120     private static func prettyPrintedString(from json: Any?) -> String? {
 
 121         guard let json = json else {
 
 125         var response: String? = nil
 
 127         if let data = try? JSONSerialization.data(withJSONObject: json, options: .prettyPrinted),
 
 128             let dataString = String.init(data: data, encoding: .utf8) {
 
 129             response = dataString