From ce74f4dffd768969a74d7677df092af513854f17 Mon Sep 17 00:00:00 2001 From: BilalKhanWDI Date: Wed, 15 May 2024 10:52:14 +0530 Subject: [PATCH] - Added API for proceed login - Added guest login api - Handled response error - Created a dummy project for home side bar - Added alamofire logger. --- WOKA.xcodeproj/project.pbxproj | 4 + .../xcshareddata/xcschemes/WOKA.xcscheme | 7 + WOKA/Alerts/CustomAlerts.storyboard | 143 ++++++++++++++++++ WOKA/Alerts/YesNoAlertVC.swift | 73 +++++++++ WOKA/Authentication/Controller/LoginVC.swift | 5 + WOKA/Authentication/ViewModel/LoginVM.swift | 89 ++++++++++- WOKA/Constants K/OnBoardVM.swift | 37 +++++ WOKA/Constants K/StoryBoardID.swift | 1 + .../hi.lproj/Localizable.strings | 2 + WOKA/Main/AppDelegate.swift | 9 ++ WOKA/Network Adapter/APIEndPoints.swift | 7 + WOKA/Network Adapter/NetworkManager.swift | 34 ++++- .../Controller/OnBoardVC.swift | 1 + 13 files changed, 409 insertions(+), 3 deletions(-) create mode 100644 WOKA/Alerts/YesNoAlertVC.swift diff --git a/WOKA.xcodeproj/project.pbxproj b/WOKA.xcodeproj/project.pbxproj index 232d457..bd14ea1 100644 --- a/WOKA.xcodeproj/project.pbxproj +++ b/WOKA.xcodeproj/project.pbxproj @@ -89,6 +89,7 @@ 52D774EF2BDFC50D001D87DE /* StringValidations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52D774EE2BDFC50D001D87DE /* StringValidations.swift */; }; 52D774F12BDFC53B001D87DE /* StringSubScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52D774F02BDFC53B001D87DE /* StringSubScript.swift */; }; 52FB2D8F2BDF898F0009B0C7 /* TextFieldPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52FB2D8E2BDF898F0009B0C7 /* TextFieldPadding.swift */; }; + 52FDDAB52BF34DC300E037C1 /* YesNoAlertVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52FDDAB42BF34DC300E037C1 /* YesNoAlertVC.swift */; }; 619A5A1BD8BD968ADC83C106 /* Pods_WOKA.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BBA543A4216400A2864E3D3E /* Pods_WOKA.framework */; }; 9C0A853F2BEE35340093783D /* ForgotPassDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C0A853E2BEE35340093783D /* ForgotPassDM.swift */; }; 9C0A85412BEE35670093783D /* ResetPassUserNameVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C0A85402BEE35670093783D /* ResetPassUserNameVM.swift */; }; @@ -222,6 +223,7 @@ 52E7E0F62BDF7DD500C86E10 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/AuthenticationSB.strings; sourceTree = ""; }; 52E7E0F82BDF7DD900C86E10 /* hi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hi; path = hi.lproj/AuthenticationSB.strings; sourceTree = ""; }; 52FB2D8E2BDF898F0009B0C7 /* TextFieldPadding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldPadding.swift; sourceTree = ""; }; + 52FDDAB42BF34DC300E037C1 /* YesNoAlertVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YesNoAlertVC.swift; sourceTree = ""; }; 9C0A853E2BEE35340093783D /* ForgotPassDM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForgotPassDM.swift; sourceTree = ""; }; 9C0A85402BEE35670093783D /* ResetPassUserNameVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResetPassUserNameVM.swift; sourceTree = ""; }; 9C0A85422BEE3EC90093783D /* NewPasswordVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewPasswordVM.swift; sourceTree = ""; }; @@ -488,6 +490,7 @@ children = ( 5259542D2BEA393700191286 /* AlertCustomVC.swift */, 5259542F2BEA394300191286 /* CustomAlerts.storyboard */, + 52FDDAB42BF34DC300E037C1 /* YesNoAlertVC.swift */, ); path = Alerts; sourceTree = ""; @@ -879,6 +882,7 @@ 5272FCE32BDFDB05000ECB1D /* UserDetailsRegisterVC.swift in Sources */, 525954102BE8B72900191286 /* FontCustom.swift in Sources */, 5202AAFE2BDF90590043B7BD /* TextFieldImage.swift in Sources */, + 52FDDAB52BF34DC300E037C1 /* YesNoAlertVC.swift in Sources */, 52C6E0232BE3B3E300E22D59 /* SelectAvatarVC.swift in Sources */, 5259545C2BEBB80400191286 /* AvatarDM.swift in Sources */, 52C8B06C2BDA6E87003B51D0 /* LocalizedString.swift in Sources */, diff --git a/WOKA.xcodeproj/xcshareddata/xcschemes/WOKA.xcscheme b/WOKA.xcodeproj/xcshareddata/xcschemes/WOKA.xcscheme index 26a8273..e31268e 100644 --- a/WOKA.xcodeproj/xcshareddata/xcschemes/WOKA.xcscheme +++ b/WOKA.xcodeproj/xcshareddata/xcschemes/WOKA.xcscheme @@ -74,6 +74,13 @@ ReferencedContainer = "container:WOKA.xcodeproj"> + + + + + + + Exo2-Bold + Exo2-Regular @@ -117,13 +121,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WOKA/Alerts/YesNoAlertVC.swift b/WOKA/Alerts/YesNoAlertVC.swift new file mode 100644 index 0000000..a6f440d --- /dev/null +++ b/WOKA/Alerts/YesNoAlertVC.swift @@ -0,0 +1,73 @@ +// +// YesNoAlertVC.swift +// WOKA +// +// Created by MacBook Pro on 14/05/24. +// + +import UIKit + +enum YesNoMode{ + case yes + case no +} + +class YesNoAlertVC: UIViewController { + + @IBOutlet weak var yesBtn: UIButton! + @IBOutlet weak var noBtn: UIButton! + @IBOutlet weak var content: UILabel! + + // Properties + var contentLabel = String() + var yesBtnText: String? + var noBtnText: String? + var mainTitleText: String? + + // Completion block to be executed when the alert is dismissed + var onDoneBlock: ((YesNoMode) -> Void)? + + // MARK: - View LifeCycle + + override func viewDidLoad() { + super.viewDidLoad() + + yesBtn.roundCorner() + noBtn.roundCorner() + self.content.text = contentLabel + + if let yesBtnText{ + self.yesBtn.setTitle(yesBtnText, for: .normal) + } + if let noBtnText{ + self.yesBtn.setTitle(noBtnText, for: .normal) + } + } + + // MARK: - Button Handler + + @IBAction func closeBtnTapped(_ sender: UIButton) { + self.dismiss() + } + + @IBAction func btnTapped(_ sender: UIButton) { + switch sender{ + case yesBtn: + self.onDoneBlock?(.yes) + self.dismiss() + case noBtn: + self.onDoneBlock?(.no) + self.dismiss() + default: + break + } + } + + // Dismiss the alert with fade transition + private func dismiss() { + let transition = CATransition().fadeTransition() + self.view.layer.add(transition, forKey: kCATransition) + self.dismiss(animated: true) + } + +} diff --git a/WOKA/Authentication/Controller/LoginVC.swift b/WOKA/Authentication/Controller/LoginVC.swift index e683036..b62543d 100644 --- a/WOKA/Authentication/Controller/LoginVC.swift +++ b/WOKA/Authentication/Controller/LoginVC.swift @@ -24,6 +24,9 @@ class LoginVC: UIViewController { super.viewDidLoad() vm.vc = self vm.initView() + + self.userNameTF.text = "tests104" + self.passwordTF.text = "123456" } @IBAction func loginBtnTapped(_ sender: LocalisedElementsButton) { @@ -47,6 +50,7 @@ class LoginVC: UIViewController { vcPush.contentLabel = "Password is too short.".localized(loc: AuthFunc.shareInstance.languageSelected.rawValue) vcPush.mainTitleText = "Error".localized(loc: AuthFunc.shareInstance.languageSelected.rawValue) + // vcPush.onDoneBlock = { isDone in } vcPush.modalPresentationStyle = .overCurrentContext vcPush.modalTransitionStyle = .crossDissolve @@ -63,6 +67,7 @@ class LoginVC: UIViewController { } @IBAction func continueGuestBtnTapped(_ sender: UIButton) { + vm.guestLogin() } @IBAction func forgotPasswordBtnTapped(_ sender: UIButton) { diff --git a/WOKA/Authentication/ViewModel/LoginVM.swift b/WOKA/Authentication/ViewModel/LoginVM.swift index 102783a..d9eb8c5 100644 --- a/WOKA/Authentication/ViewModel/LoginVM.swift +++ b/WOKA/Authentication/ViewModel/LoginVM.swift @@ -70,7 +70,94 @@ class LoginVM{ "Accept-Language" : AuthFunc.shareInstance.languageSelected == .english ? "English" : "Hindi"] Utilities.startProgressHUD() - NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Auth.login, method: .post ,parameters: params, headers: header) {(result : Result, NetworkManager.APIError>) in + NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Auth.login, method: .post ,parameters: params, headers: header) {(result : Result, NetworkManager.APIError>) in + switch result{ + case .success(let data): + switch data.success{ + case 0: + Utilities.dismissProgressHUD() + self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2) + case 1: + Utilities.dismissProgressHUD() + guard let dataResult = data.data?.result, let loginStatus = dataResult.alreadyLoggedIn else{return} + if loginStatus == true{ // user is already loginned in other device + let sb = UIStoryboard(name: K.StoryBoard.customAlerts, bundle: nil) + let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.CustomAlerts.yesNoAlertVC) as! YesNoAlertVC + vcPush.contentLabel = data.message ?? K.ConstantString.unRecognised + vcPush.onDoneBlock = { mode in + switch mode{ + case .yes: + //If user clicked to proceed on login. Call the api. + self.proceedLogin() + case .no: + print("no") + } + } + vcPush.modalPresentationStyle = .overCurrentContext + vcPush.modalTransitionStyle = .crossDissolve + self.vc.present(vcPush, animated: true) + }else{ // fresh login + /* + if user is not logined on other device directly nav him to home + */ + } + default: + break + } + case .failure(let error): + Utilities.dismissProgressHUD() + self.vc.toast(msg: error.localizedDescription, time: 2) + } + } + } + + /* + After all checks do the api call + */ + func proceedLogin(){ + let params: Parameters = [ + "username": vc.userNameTF.text!, + "password": vc.passwordTF.text! + ] + let header : HTTPHeaders = ["device-id" : AuthFunc.shareInstance.getDeviceUUID(), + "Accept-Language" : AuthFunc.shareInstance.languageSelected == .english ? "English" : "Hindi"] + + Utilities.startProgressHUD() + NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Auth.login_proceed, method: .post ,parameters: params, headers: header) {(result : Result, NetworkManager.APIError>) in + switch result{ + case .success(let data): + switch data.success{ + case 0: + Utilities.dismissProgressHUD() + self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2) + case 1: + Utilities.dismissProgressHUD() + self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2) + default: + break + } + case .failure(let error): + Utilities.dismissProgressHUD() + self.vc.toast(msg: error.localizedDescription, time: 2) + } + } + } + + /* + Guest Login + */ + func guestLogin(){ + let params: Parameters = [ + "user_type": 3, // 1- kid , 2 - guardian , 3 - guest + "one_signal_player_id": "Test", + "language_id": AuthFunc.shareInstance.languageSelected == .english ? 1 : 2, //1-eng, 2 - hindi + "device_type": 1 // 1- android , 2 - iOS + ] + let header : HTTPHeaders = ["device-id" : AuthFunc.shareInstance.getDeviceUUID(), + "Accept-Language" : AuthFunc.shareInstance.languageSelected == .english ? "English" : "Hindi"] + + Utilities.startProgressHUD() + NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Auth.guest_login, method: .post ,parameters: params, headers: header) {(result : Result, NetworkManager.APIError>) in switch result{ case .success(let data): switch data.success{ diff --git a/WOKA/Constants K/OnBoardVM.swift b/WOKA/Constants K/OnBoardVM.swift index d3a37fa..7df06d9 100644 --- a/WOKA/Constants K/OnBoardVM.swift +++ b/WOKA/Constants K/OnBoardVM.swift @@ -7,6 +7,7 @@ import UIKit import Lottie +import Alamofire class OnBoardVM{ @@ -105,4 +106,40 @@ class OnBoardVM{ func resumeBackGroundAnimationJSON(){ animationView?.play() } + + // MARK: - Create Guest + /* + Guest Login + */ + func guestLogin(){ + let params: Parameters = [ + "user_type": 3, // 1- kid , 2 - guardian , 3 - guest + "one_signal_player_id": "Test", + "language_id": AuthFunc.shareInstance.languageSelected == .english ? 1 : 2, //1-eng, 2 - hindi + "device_type": 1 // 1- android , 2 - iOS + ] + let header : HTTPHeaders = ["device-id" : AuthFunc.shareInstance.getDeviceUUID(), + "Accept-Language" : AuthFunc.shareInstance.languageSelected == .english ? "English" : "Hindi"] + + Utilities.startProgressHUD() + NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Auth.guest_login, method: .post ,parameters: params, headers: header) {(result : Result, NetworkManager.APIError>) in + switch result{ + case .success(let data): + switch data.success{ + case 0: + Utilities.dismissProgressHUD() + self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2) + case 1: + Utilities.dismissProgressHUD() + self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2) + default: + break + } + case .failure(let error): + Utilities.dismissProgressHUD() + self.vc.toast(msg: error.localizedDescription, time: 2) + } + } + } + } diff --git a/WOKA/Constants K/StoryBoardID.swift b/WOKA/Constants K/StoryBoardID.swift index 2ddd8a6..f9e3f47 100644 --- a/WOKA/Constants K/StoryBoardID.swift +++ b/WOKA/Constants K/StoryBoardID.swift @@ -35,6 +35,7 @@ extension K{ struct CustomAlerts{ static let alertCustomVC = "AlertCustomVC" + static let yesNoAlertVC = "YesNoAlertVC" } } diff --git a/WOKA/Localized Module/hi.lproj/Localizable.strings b/WOKA/Localized Module/hi.lproj/Localizable.strings index 85d0582..bc760d4 100644 --- a/WOKA/Localized Module/hi.lproj/Localizable.strings +++ b/WOKA/Localized Module/hi.lproj/Localizable.strings @@ -1,5 +1,7 @@ "Hello" = "नमस्ते"; +"Yes" = "हाँ"; +"No" = "नहीं"; "Error" = "गलती"; "Retry?" = "पुनः प्रयास करें?"; "Please wait..." = "कृपया प्रतीक्षा करें"; diff --git a/WOKA/Main/AppDelegate.swift b/WOKA/Main/AppDelegate.swift index efe3fab..63b0de7 100644 --- a/WOKA/Main/AppDelegate.swift +++ b/WOKA/Main/AppDelegate.swift @@ -30,6 +30,15 @@ class AppDelegate: UIResponder, UIApplicationDelegate { LottieConfiguration.shared.renderingEngine = .mainThread return true } + +// func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { +// print("URL-> " ,url) +//// if let referralCode = getReferralCode(from: url) { +//// // Do something with the referral code +//// print("Referral code: \(referralCode)") +//// } +// return true +// } // MARK: UISceneSession Lifecycle diff --git a/WOKA/Network Adapter/APIEndPoints.swift b/WOKA/Network Adapter/APIEndPoints.swift index 0b45934..e0647a8 100644 --- a/WOKA/Network Adapter/APIEndPoints.swift +++ b/WOKA/Network Adapter/APIEndPoints.swift @@ -25,8 +25,15 @@ struct APIEndPoints { struct Auth { static let check_exist_email = makeURL(path: "check_exist_email") + + /* + Login User + */ static let login = makeURL(path: "login") static let login_proceed = makeURL(path: "login_proceed") + static let guest_login = makeURL(path: "guest_login") + + static let user_email_verification = makeURL(path: "user_email_verification") static let validate_otp = makeURL(path: "validate_otp") static let interest_topic_listing = makeURL(path: "interest_topic_listing") diff --git a/WOKA/Network Adapter/NetworkManager.swift b/WOKA/Network Adapter/NetworkManager.swift index e6dac48..6fd7c98 100644 --- a/WOKA/Network Adapter/NetworkManager.swift +++ b/WOKA/Network Adapter/NetworkManager.swift @@ -10,7 +10,8 @@ import Alamofire class NetworkManager{ static let shareInstance = NetworkManager() - + private let alamofireLogger = AlamofireLogger() + private init() {} enum APIError: Error { @@ -46,13 +47,14 @@ class NetworkManager{ ) { // 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 }) .authenticate(username: "admin", password: "Woka@1234") .validate(statusCode: 200..<300) .responseDecodable(of: T.self) { response in +// alamofireLogger.request(response.da, didParseResponse: response) switch response.result { case .success(let value): // Handle successful response on the main thread @@ -107,3 +109,31 @@ class NetworkManager{ } } } + + +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(_ request: DataRequest, didParseResponse response: AFDataResponse) { + + NSLog("⚡️⚡️⚡️⚡️ Response Received: \(response.debugDescription)") + NSLog("⚡️⚡️⚡️⚡️ Response All Headers: \(String(describing: response.response?.allHeaderFields))") + } +} diff --git a/WOKA/OnBoarding Module/Controller/OnBoardVC.swift b/WOKA/OnBoarding Module/Controller/OnBoardVC.swift index f7fe5f6..eb66315 100644 --- a/WOKA/OnBoarding Module/Controller/OnBoardVC.swift +++ b/WOKA/OnBoarding Module/Controller/OnBoardVC.swift @@ -67,6 +67,7 @@ class OnBoardVC: UIViewController { @IBAction func guestLoginBtnTapped(_ sender: UIButton) { + vm.guestLogin() }