- updated cart icon in whole shop module , myoders - Finalsied the payment gateway response
193 lines
8.9 KiB
Swift
193 lines
8.9 KiB
Swift
//
|
|
// NetworkManager.swift
|
|
// WOKA
|
|
//
|
|
// Created by MacBook Pro on 06/05/24.
|
|
//
|
|
|
|
import Alamofire
|
|
|
|
class NetworkManager{
|
|
|
|
static let shareInstance = NetworkManager()
|
|
private let alamofireLogger = AlamofireLogger()
|
|
|
|
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 & ResponseProtocol>(
|
|
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()
|
|
let loginCred = getLoginIDPass()
|
|
// Execute the request on the specified queue
|
|
queue.async {
|
|
AF.request(url, method: method, parameters: parameters, encoding: encoding, headers: headers, requestModifier: { $0.timeoutInterval = 20 })
|
|
.authenticate(username: loginCred.0, password: loginCred.1)
|
|
.validate(statusCode: 200..<300)
|
|
.responseDecodable(of: T.self) { response in
|
|
// alamofireLogger.request(response.da, didParseResponse: response)
|
|
switch response.result {
|
|
case .success(let value):
|
|
/*
|
|
if Sucess == 4 menas user has logined in some other device, logout that user by saying session timeout
|
|
*/
|
|
if value.success == 4{
|
|
if let topController = UIApplication.topViewController() {
|
|
let sb = UIStoryboard(name: K.StoryBoard.customAlerts, bundle: nil)
|
|
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.CustomAlerts.alertCustomVC) as! AlertCustomVC
|
|
vcPush.contentLabel = "Please Login Again"
|
|
vcPush.mainTitleText = "Session Expired."
|
|
vcPush.yesBtnText = "Login"
|
|
vcPush.onDoneBlock = { isDone in
|
|
AuthFunc.shareInstance.logout()
|
|
UIApplication.setRootView(LoginNavVC.instantiate(from: .AuthenticationSB))
|
|
}
|
|
vcPush.modalPresentationStyle = .overCurrentContext
|
|
vcPush.modalTransitionStyle = .crossDissolve
|
|
topController.present(vcPush, animated: true)
|
|
|
|
// Utilities.alertWithBtnCompletion(title: "Session Expired", msgBody: "Please Login Again", okBtnStr: "OK", vc: topController) { isDone in
|
|
// AuthFunc.shareInstance.logout()
|
|
// UIApplication.setRootView(LoginNavVC.instantiate(from: .AuthenticationSB))
|
|
// }
|
|
}
|
|
return
|
|
}
|
|
|
|
// 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 getLoginIDPass()-> (String, String){
|
|
if let loginID = Bundle.main.infoDictionary?["API_KEY_ID"] as? String , let loginPaass = Bundle.main.infoDictionary?["API_KEY_PASS"] as? String{
|
|
let cleanedLoginID = loginID.trimmingCharacters(in: CharacterSet(charactersIn: "\""))
|
|
let cleanedLoginPass = loginPaass.trimmingCharacters(in: CharacterSet(charactersIn: "\""))
|
|
return (cleanedLoginID, cleanedLoginPass)
|
|
}
|
|
return ("","")
|
|
}
|
|
}
|
|
|
|
|
|
final class AlamofireLogger: EventMonitor {
|
|
|
|
func requestDidResume(_ request: Request) {
|
|
|
|
let allHeaders = request.request.flatMap { $0.allHTTPHeaderFields.map { $0.description } } ?? "None"
|
|
let headers = """
|
|
⚡️⚡️⚡️⚡️ Request Started: \(request)
|
|
⚡️⚡️⚡️⚡️ Headers: \(allHeaders)
|
|
"""
|
|
NSLog(headers)
|
|
|
|
|
|
let body = request.request.flatMap { $0.httpBody.map { String(decoding: $0, as: UTF8.self) } } ?? "None"
|
|
let message = """
|
|
⚡️⚡️⚡️⚡️ Request Started: \(request)
|
|
⚡️⚡️⚡️⚡️ Body Data: \(body)
|
|
"""
|
|
NSLog(message)
|
|
}
|
|
|
|
func request<Value>(_ request: DataRequest, didParseResponse response: AFDataResponse<Value>) {
|
|
|
|
NSLog("⚡️⚡️⚡️⚡️ Response Received: \(response.debugDescription)")
|
|
NSLog("⚡️⚡️⚡️⚡️ Response All Headers: \(String(describing: response.response?.allHeaderFields))")
|
|
}
|
|
}
|
|
|
|
|
|
extension UIApplication {
|
|
class func topViewController(_ base: UIViewController? = UIApplication.shared.mainKeyWindow?.rootViewController) -> UIViewController? {
|
|
if let nav = base as? UINavigationController {
|
|
return topViewController(nav.visibleViewController)
|
|
}
|
|
if let tab = base as? UITabBarController {
|
|
if let selected = tab.selectedViewController {
|
|
return topViewController(selected)
|
|
}
|
|
}
|
|
if let presented = base?.presentedViewController {
|
|
return topViewController(presented)
|
|
}
|
|
return base
|
|
}
|
|
}
|