174 lines
7.5 KiB
Swift
174 lines
7.5 KiB
Swift
//
|
|
// NetworkManager.swift
|
|
// WOKA
|
|
//
|
|
// Created by MacBook Pro on 06/05/24.
|
|
//
|
|
|
|
import Alamofire
|
|
|
|
class NetworkManager{
|
|
|
|
static let shareInstance = NetworkManager()
|
|
|
|
private init() {}
|
|
|
|
enum APIError: Error {
|
|
case networkError
|
|
case noNetwork(message:String)
|
|
case invalidURL
|
|
case parameterEncodingFailed
|
|
case responseValidationFailed
|
|
case unknown(message: String)
|
|
case custom(message: String)
|
|
}
|
|
|
|
/// This function will do the network call for HTTPMethod & Encoding is URLEncoding with contentType ["application/json"]
|
|
///
|
|
///
|
|
/// - Warning: The returned string is not localized.
|
|
///
|
|
/// Usage:
|
|
///
|
|
/// Alamofire network call Generic (.get , .post, .put.).
|
|
///
|
|
/// - Parameter (header : HTTPHeaders , Params :[String : Any] , URL , Dedocable Generic T Struct. , queue : dispatchQueue decide)
|
|
/// - NOTE Oncompletion will be called on main thread so no need to specify the main thread for UI updates
|
|
/// - Returns: This function returns a GENERIC response base on the T Model & APIError .
|
|
func apiRequest<T: Codable>(
|
|
url: URLConvertible,
|
|
method: HTTPMethod,
|
|
parameters: Parameters? = nil,
|
|
encoding: ParameterEncoding = URLEncoding.default,
|
|
headers: HTTPHeaders? = nil,
|
|
queue: DispatchQueue = QueueHelper.background,
|
|
completionHandler: @escaping (Result<T, APIError>) -> Void
|
|
) {
|
|
// Stop monitoring network reachability
|
|
NetworkReachibility.shared.stopMonitoring()
|
|
|
|
// Execute the request on the specified queue
|
|
queue.async {
|
|
AF.request(url, method: method, parameters: parameters, encoding: encoding, headers: headers, requestModifier: { $0.timeoutInterval = 30 })
|
|
.validate(statusCode: 200..<300)
|
|
.responseDecodable(of: T.self) { response in
|
|
switch response.result {
|
|
case .success(let value):
|
|
// Handle successful response on the main thread
|
|
DispatchQueue.main.async {
|
|
completionHandler(.success(value))
|
|
}
|
|
case .failure(let error):
|
|
// Handle failure cases
|
|
if let afError = error as? AFError {
|
|
switch afError {
|
|
case .sessionTaskFailed(let urlError):
|
|
if urlError._code == -1020 || urlError._code == -1009 {
|
|
// Handle network error on the main thread
|
|
DispatchQueue.main.async {
|
|
completionHandler(.failure(.noNetwork(message: K.ConstantString.noInternet)))
|
|
}
|
|
} else {
|
|
// Handle other network errors on the main thread
|
|
DispatchQueue.main.async {
|
|
completionHandler(.failure(.networkError))
|
|
}
|
|
}
|
|
case .invalidURL:
|
|
// Handle invalid URL error on the main thread
|
|
DispatchQueue.main.async {
|
|
completionHandler(.failure(.invalidURL))
|
|
}
|
|
case .parameterEncodingFailed:
|
|
// Handle parameter encoding failure on the main thread
|
|
DispatchQueue.main.async {
|
|
completionHandler(.failure(.parameterEncodingFailed))
|
|
}
|
|
case .responseValidationFailed:
|
|
// Handle response validation failure on the main thread
|
|
DispatchQueue.main.async {
|
|
completionHandler(.failure(.responseValidationFailed))
|
|
}
|
|
default:
|
|
// Handle other network errors on the main thread
|
|
DispatchQueue.main.async {
|
|
completionHandler(.failure(.networkError))
|
|
}
|
|
}
|
|
} else {
|
|
// Handle unrecognized errors on the main thread
|
|
DispatchQueue.main.async {
|
|
completionHandler(.failure(.unknown(message: K.ConstantString.unRecognised)))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// func handleAFError(error: Error)-> Int? {
|
|
// if let afError = error as? AFError {
|
|
// // This error is of type AFError, and you can access its properties.
|
|
// let errorCode = afError.responseCode
|
|
// return errorCode
|
|
// } else {
|
|
// // Handle other types of errors or unsupported cases
|
|
// return nil
|
|
// }
|
|
// }
|
|
//
|
|
// func uploadFormData<T: Codable>(
|
|
// url: URLConvertible,
|
|
// method: HTTPMethod,
|
|
// headers: HTTPHeaders? = nil,
|
|
// params : [String : Any]?,
|
|
// image : UIImage?,
|
|
// formData: [MultipartFormData],
|
|
// completionHandler: @escaping (Result<T, AFError>) -> Void
|
|
// ) {
|
|
//
|
|
// let imageData = image?.jpegData(compressionQuality: 0.4)!
|
|
// let imageKey = "contact_photo" // Change me
|
|
// AF.upload(multipartFormData: { multiPart in
|
|
// for (key, value) in (params ?? [:]) {
|
|
// if let arrayObj = value as? [Any] {
|
|
// for index in 0..<arrayObj.count {
|
|
// if key != "contact_photo"{
|
|
// multiPart.append("\(arrayObj[index])".data(using: .utf8)!, withName: "\(key)[\(index)]")
|
|
// }
|
|
// }
|
|
// } else {
|
|
// if key != "contact_photo"{
|
|
// multiPart.append("\(value)".data(using: .utf8)!, withName: key)
|
|
// }
|
|
// }
|
|
// }
|
|
// if let imageData{
|
|
// multiPart.append(imageData, withName: imageKey, fileName: "file.jpg", mimeType: "image/jpg")
|
|
// }
|
|
// }, to: url, headers: headers).responseDecodable { (response: DataResponse<T,AFError>) in
|
|
// switch response.result {
|
|
// case .success(let value):
|
|
// completionHandler(.success(value))
|
|
// case .failure(let error):
|
|
// if let statusCode = response.response?.statusCode {
|
|
// switch statusCode {
|
|
// case 400..<500:
|
|
// // Handle client-side errors (4xx)
|
|
// completionHandler(.failure(.custom(message: "Client-side error: \(statusCode)")))
|
|
// case 500..<600:
|
|
// // Handle server-side errors (5xx)
|
|
// completionHandler(.failure(.custom(message: "Server-side error: \(statusCode)")))
|
|
// default:
|
|
// completionHandler(.failure(.unknown))
|
|
// }
|
|
// } else {
|
|
// completionHandler(.failure(.unknown))
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
//}
|