From c298da6883267e5b50a6a21f4ae1c371fd55cd0a Mon Sep 17 00:00:00 2001 From: Dominic Go <18517029+dominicstop@users.noreply.github.com> Date: Fri, 12 May 2023 14:45:26 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A0=20Refactor:=20Update=20Native=20Er?= =?UTF-8?q?ror=20Handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Related: * `TODO:2023-03-27-23-55-09` Refactor: Re-write `RNIModalView` error creation and handling. Summary: Update to use `RNIModalError`. --- .../RNIModalView/RNIModalView.swift | 143 +++++------------- .../RNIModalViewModule.swift | 113 ++++++++------ 2 files changed, 109 insertions(+), 147 deletions(-) diff --git a/ios/src_library/React Native/RNIModalView/RNIModalView.swift b/ios/src_library/React Native/RNIModalView/RNIModalView.swift index 15eb6746..28cd6c04 100644 --- a/ios/src_library/React Native/RNIModalView/RNIModalView.swift +++ b/ios/src_library/React Native/RNIModalView/RNIModalView.swift @@ -12,7 +12,7 @@ public class RNIModalView: UIView, RNIIdentifiable, RNIModalPresentationNotifying, RNIModalState, RNIModalPresentation { - public typealias CompletionHandler = (_ isSuccess: Bool, _ error: RNIModalViewError?) -> Void; + public typealias CompletionHandler = () -> Void; enum NativeIDKey: String { case modalViewContent; @@ -530,6 +530,10 @@ public class RNIModalView: return gestureRecognizers.first; }; + var debugData: Dictionary { + self.synthesizedModalData.synthesizedJSDictionary + }; + // MARK: - Init // ------------ @@ -550,15 +554,17 @@ public class RNIModalView: public override func didMoveToWindow() { super.didMoveToWindow(); + if self.presentViaMount { - self.dismissModal(); + try? self.dismissModal(); }; }; public override func didMoveToSuperview() { super.didMoveToSuperview(); + if self.presentViaMount { - self.presentModal(); + try? self.presentModal(); }; }; @@ -777,56 +783,40 @@ public class RNIModalView: // MARK: - Functions - Public // -------------------------- - public func presentModal(completion: CompletionHandler? = nil) { + public func presentModal(completion: CompletionHandler? = nil) throws { guard self.window != nil else { - #if DEBUG - print( - "Error - RNIModalView.presentModal" - + " - self.modalNativeID: \(self.modalNativeID)" - + " - Guard check failed: no window" + throw RNIModalError( + code: .runtimeError, + message: "Guard check failed, window is nil", + debugData: self.debugData ); - #endif - completion?(false, nil); - return; }; guard !self.computedIsModalPresented else { - #if DEBUG - print( - "Error - RNIModalView.presentModal" - + " - self.modalNativeID: \(self.modalNativeID)" - + " - Guard check failed: modal already presented" + throw RNIModalError( + code: .modalAlreadyVisible, + message: "Guard check failed, modal already presented", + debugData: self.debugData ); - #endif - completion?(false, .modalAlreadyPresented); - return; }; let presentedViewControllers = RNIPresentedVCListCache.getPresentedViewControllers(forWindow: window); guard let topMostPresentedVC = presentedViewControllers.last else { - #if DEBUG - print( - "Error - RNIModalView.presentModal" - + " - self.modalNativeID: \(self.modalNativeID)" - + " - Guard check failed: could not get topMostPresentedVC" + throw RNIModalError( + code: .runtimeError, + message: "Guard check failed, could not get topMostPresentedVC", + debugData: self.debugData ); - #endif - completion?(false, nil); - return; }; guard let modalVC = self.modalVC else { - #if DEBUG - print( - "Error - RNIModalView.presentModal" - + " - self.modalNativeID: \(self.modalNativeID)" - + " - Guard check failed: Could not get modalVC" + throw RNIModalError( + code: .runtimeError, + message: "Guard check failed, could not get modalVC", + debugData: self.debugData ); - #endif - completion?(false, nil); - return; }; modalVC.modalTransitionStyle = self.synthesizedModalTransitionStyle; @@ -878,7 +868,7 @@ public class RNIModalView: self.synthesizedBaseEventData.synthesizedJSDictionary ); - completion?(true, nil); + completion?(); #if DEBUG print( @@ -891,30 +881,21 @@ public class RNIModalView: }; }; - public func dismissModal(completion: CompletionHandler? = nil) { + public func dismissModal(completion: CompletionHandler? = nil) throws { guard self.computedIsModalPresented else { - #if DEBUG - print( - "Error - RNIModalView.dismissModal" - + " - self.modalNativeID: \(self.modalNativeID)" - + " - self.modalIndex: \(self.modalIndex!)" - + " - Guard check failed: Modal presented state unknown" + throw RNIModalError( + code: .modalAlreadyHidden, + message: "Guard check failed, modal already dismissed", + debugData: self.debugData ); - #endif - completion?(false, .modalAlreadyDismissed); - return; }; guard let modalVC = self.modalVC else { - #if DEBUG - print( - "Error - RNIModalView.dismissModal" - + " - self.modalNativeID: \(self.modalNativeID)" - + " - Guard check failed: Unable to get modalVC" + throw RNIModalError( + code: .runtimeError, + message: "Guard check failed, Unable to get modalVC", + debugData: self.debugData ); - #endif - completion?(false, .none); - return; }; let isModalInFocus = self.computedIsModalInFocus; @@ -924,17 +905,11 @@ public class RNIModalView: : self.allowModalForceDismiss; guard shouldDismiss else { - #if DEBUG - print( - "Error - RNIModalView.dismissModal" - + " - self.modalNativeID: \(self.modalNativeID)" - + " - Guard check failed: Unable to dismiss" - + " - shouldDismiss: \(shouldDismiss)" - + " - isModalInFocus: \(computedIsModalInFocus)" + throw RNIModalError( + code: .dismissRejected, + message: "Guard check failed, shouldDismiss prop is false", + debugData: self.debugData ); - #endif - completion?(false, .modalDismissFailedNotInFocus); - return; }; /// TODO:2023-03-22-12-12-05 - Remove? @@ -967,7 +942,7 @@ public class RNIModalView: self.synthesizedBaseEventData.synthesizedJSDictionary ); - completion?(true, nil); + completion?(); #if DEBUG print( @@ -978,40 +953,6 @@ public class RNIModalView: #endif }; }; - - // MARK: - Functions - Module-Related - // ---------------------------------- - - public func setModalVisibility( - visibility: Bool, - completion: CompletionHandler? = nil - ){ - var params: Dictionary = [ - "visibility": visibility, - ]; - - let baseEventDataDict = - self.synthesizedBaseEventData.synthesizedJSDictionary; - - baseEventDataDict.forEach { (key, value) in - params[key] = value - }; - - let modalAction = visibility - ? self.presentModal - : self.dismissModal; - - modalAction() { (success, error) in - params["success"] = success; - - if let errorCode = error { - params["errorCode"] = errorCode.rawValue; - params["errorMessage"] = RNIModalViewError.getErrorMessage(for: errorCode); - }; - - completion?(success, error); - }; - }; }; // MARK: - UIAdaptivePresentationControllerDelegate @@ -1150,7 +1091,7 @@ extension RNIModalView: UISheetPresentationControllerDelegate { extension RNIModalView: RNIModalRequestable { public func requestModalToShow( - sender:any RNIModal, + sender: any RNIModal, onRequestApprovedBlock: () -> Void, onRequestDeniedBlock: (String) -> Void ) { diff --git a/ios/src_library/React Native/RNIModalViewModule/RNIModalViewModule.swift b/ios/src_library/React Native/RNIModalViewModule/RNIModalViewModule.swift index dd24ce08..da1bacf0 100644 --- a/ios/src_library/React Native/RNIModalViewModule/RNIModalViewModule.swift +++ b/ios/src_library/React Native/RNIModalViewModule/RNIModalViewModule.swift @@ -53,7 +53,9 @@ class RNIModalViewModule: RCTEventEmitter { // MARK: - Module Functions // ------------------------ - + + // TODO: `TODO:2023-05-12-14-11-25` + // TODO: `TODO:2023-05-12-14-40-46` @objc func dismissModalByID( _ modalID: NSString, callback: @escaping RCTResponseSenderBlock @@ -62,13 +64,18 @@ class RNIModalViewModule: RCTEventEmitter { let listPresentedVC = RNIUtilities.getPresentedViewControllers(); guard listPresentedVC.count > 0 else { - #if DEBUG - print( - "Error - RNIModalViewModule.dismissModalByID" - + " - arg modalID: \(modalID)" - + " - listPresentedVC is empty" + let errorMessage = + "The list of presented view controllers is empty" + + " modalID: \(modalID)"; + + let _ = RNIModalError( + code: .runtimeError, + message: errorMessage, + debugData: [ + "modalID": modalID + ] ); - #endif + callback([false]); return; }; @@ -82,44 +89,46 @@ class RNIModalViewModule: RCTEventEmitter { }; guard let targetModalView = targetModalVC?.modalViewRef else { - #if DEBUG - print( - "Error - RNIModalViewModule.dismissModalByID" - + " - arg modalID: \(modalID)" - + " - Could not get matching 'RNIModalView' instance." + let errorMessage = + "Unable to get the matching RNIModalView instance for" + + " modalID: \(modalID)"; + + let _ = RNIModalError( + code: .runtimeError, + message: errorMessage, + debugData: [ + "modalID": modalID + ] ); - #endif + callback([false]); return; }; - targetModalView.dismissModal { isSuccess, error in - guard isSuccess else { - #if DEBUG - print( - "Error - RNIModalViewModule.dismissModalByID" - + " - arg modalID: \(modalID)" - + " - Invoke: RNIModalView.dismissModal" - + " - Error: \(error?.errorMessage ?? "N/A")" - ); - #endif - callback([false]); - return; + do { + try targetModalView.dismissModal { + // modal dismissed + callback([true]); }; - // modal dismissed - callback([true]); - #if DEBUG print( "Log - RNIModalViewModule.dismissModalByID - Dismissing modal" + " - target modalID: '\(targetModalView.modalID!)'" ); #endif + + // } catch let error as RNIModalError { + // callback([false]); + + } catch { + let _ = RNIModalError(code: .unknownError); + callback([false]); }; }; }; + // TODO: `TODO:2023-05-12-14-40-46` @objc func dismissAllModals( _ animated: Bool, callback: @escaping RCTResponseSenderBlock @@ -145,23 +154,34 @@ class RNIModalViewModule: RCTEventEmitter { ){ DispatchQueue.main.async { guard let modalView = self.getModalViewInstance(for: node) else { - let message = - "RNIModalViewModule.setModalVisibility - Unable to get the " - + "corresponding 'RNIModalView' instance for node: \(node)" - - reject(nil, message, nil); + let error = RNIModalError( + code: .runtimeError, + message: "Unable to get the matching RNIModalView instance for node", + debugData: [ + "node": node, + "visibility": visibility + ] + ); + + error.invokePromiseRejectBlock(reject); return; }; - modalView.setModalVisibility(visibility: visibility) { isSuccess, error in - if isSuccess { - resolve( - modalView.synthesizedBaseEventData.synthesizedJSDictionary - ); - - } else { - reject(nil, error?.errorMessage, nil); + let modalAction = visibility + ? modalView.presentModal + : modalView.dismissModal; + + do { + try modalAction() { + resolve([:]); }; + + } catch let error as RNIModalError { + error.invokePromiseRejectBlock(reject) + + } catch { + let error = RNIModalError(code: .unknownError); + error.invokePromiseRejectBlock(reject); }; }; }; @@ -174,11 +194,12 @@ class RNIModalViewModule: RCTEventEmitter { ){ DispatchQueue.main.async { guard let modalView = self.getModalViewInstance(for: node) else { - let message = - "RNIModalViewModule.requestModalInfo - Unable to get the " - + "corresponding 'RNIModalView' instance for node: \(node)" - - reject(nil, message, nil); + let errorMessage = + "Unable to get the corresponding RNIModalView instance" + + " for node: \(node)" + + let error = RNIModalError(code: .runtimeError, message: errorMessage); + error.invokePromiseRejectBlock(reject); return; };