3lvis / Networking

Swift HTTP Networking with stubbing and caching support
MIT License
1.36k stars 112 forks source link

Troubleshooting Logging Errors in Xcode #274

Open jonghun-sun-hyperlounge-ai opened 10 months ago

jonghun-sun-hyperlounge-ai commented 10 months ago

GitHub Logging Errors Explanation Error logging is a default feature and can be accomplished without any additional settings. In case error logging needs to be disabled, use the following code snippet: ** swift code ================================================================== let networking = Networking(baseURL: "http://httpbin.org") networking.disableErrorLogging = true

=============================================================================

Queries:

  1. As of version 6.3.0, it appears that the disableErrorLogging property is no longer present, and only isErrorLoggingEnabled is available. Has there been a change in error logging settings from disableErrorLogging to isErrorLoggingEnabled?

  2. Currently, when an error occurs during API requests using the networking instance, logging does not occur, regardless of the disableErrorLogging or isErrorLoggingEnabled properties. Is there a specific configuration needed for error logging in version 6.3.0? If so, could you provide details on what needs to be set up?

  3. Even if no errors occur, is there a way to print logs for network communication through configuration settings? If not, is it a feature that each developer needs to implement individually? I ask this because, considering the support for error logging functionality, it seems plausible that logging for all communication (not just errors) might be available.

  4. For your reference, I am using the latest version, 6.3.0. Below is the relevant code snippet. Your insights and suggestions are highly appreciated.

** swift code ============================================================================= class APIClient { static let shared = APIClient() private var networking: Networking

init() {
    networking = Networking(baseURL: APIConstants.endpoint)
}

private func request(method: RequestType, header: HeaderType = .none, path: String,
                     parameters: [String: Any], parameterType: Networking.ParameterType = .formURLEncoded) async throws -> JSONResult {

    switch header {
    case .beare: networking.setAuthorizationHeader(username: APIConstants.clientId, password: APIConstants.clientSecret)
    case .accessToken: networking.headerFields = ["Authorization": "Bearer \(APIConstants.accessToken)"]
    case .none: break
    }

    switch method {
    case .get: return try await networking.get(path, parameters: parameters)
    case .post: return try await networking.post(path, parameterType: parameterType, parameters: parameters)
    case .put: return try await networking.put(path, parameterType: parameterType, parameters: parameters)
    case .patch: return try await networking.patch(path, parameterType: parameterType, parameters: parameters)
    case .delete: return try await networking.delete(path)
    }
}

private func handleResult<T: APIResponseProtocol>(result: JSONResult, responseType: T.Type) -> T where T.DataType: Decodable {
    var response: T

    switch result {
    case .success(let data):
        if data.data.isEmpty {
            return T(data: nil, error: nil)
        }

        switch decodeJSON(type: T.DataType.self, from: data.data) {
        case let decoded?:
            response = T(data: decoded, error: nil)
        case nil:
            print("decodeJSON Error : ", ErrorStatusCode.decode.rawValue)
            let errorResponse = ErrorResponse(statusCode: ErrorStatusCode.decode.rawValue, error: ErrorMessage(message: "Decode Json Error"))
            response = T(data: nil, error: errorResponse)
        }

    case .failure(let data):
        print("handleResult rrobbie failure data : ", data)
        response = T(data: nil, error: decodeJSON(type: ErrorResponse.self, from: data.data, statusCode: data.statusCode))
    }

    return response
}

func decodeJSON<T: Decodable>(type: T.Type, from data: Data, statusCode: Int? = nil) -> T? {
    let decoder = JSONDecoder()
    do {
        let decodedData = try decoder.decode(type, from: data)
        if var errorResponse = decodedData as? ErrorResponse, let statusCode = statusCode {
            errorResponse.statusCode = statusCode
            return errorResponse as? T
        }
        return decodedData
    } catch {
        print("Decode Error : ", error)
        return nil
    }
}

func send<T: APIRequest>(request: T) async -> T.Response where T.Response: APIResponseProtocol {
    do {
        let result = try await self.request(method: request.method, header: request.header, path: request.path, parameters: request.parameters())
        return handleResult(result: result, responseType: T.Response.self)
    } catch let error {
        let nsError = error as NSError
        // TODO : print 정의. network error인 경우...
        let errorMessage = ErrorMessage(code: nsError.domain, message: nsError.localizedDescription, print: "Network Error")
        let errorResponse = ErrorResponse(statusCode: nsError.code, error: errorMessage)
        return T.Response(data: nil, error: errorResponse)
    }
}

}

Please review the provided code and share any feedback or recommendations. Thank you.