Merge branch 'feature/action_modernize' into 'develop'
Feature/action modernize See merge request BPHV_MIPS/mvm_core!223
This commit is contained in:
commit
dcbaa316ac
@ -92,6 +92,20 @@
|
|||||||
AF43A7411FC5FA6F008E9347 /* MVMCoreViewProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = AF43A7401FC5FA6F008E9347 /* MVMCoreViewProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
AF43A7411FC5FA6F008E9347 /* MVMCoreViewProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = AF43A7401FC5FA6F008E9347 /* MVMCoreViewProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
AF43A74C1FC6109F008E9347 /* MVMCoreSessionObject.h in Headers */ = {isa = PBXBuildFile; fileRef = AF43A74A1FC6109F008E9347 /* MVMCoreSessionObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
AF43A74C1FC6109F008E9347 /* MVMCoreSessionObject.h in Headers */ = {isa = PBXBuildFile; fileRef = AF43A74A1FC6109F008E9347 /* MVMCoreSessionObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
AF43A74D1FC6109F008E9347 /* MVMCoreSessionObject.m in Sources */ = {isa = PBXBuildFile; fileRef = AF43A74B1FC6109F008E9347 /* MVMCoreSessionObject.m */; };
|
AF43A74D1FC6109F008E9347 /* MVMCoreSessionObject.m in Sources */ = {isa = PBXBuildFile; fileRef = AF43A74B1FC6109F008E9347 /* MVMCoreSessionObject.m */; };
|
||||||
|
AF60A7F2289212CA00919EEB /* MVMError.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF60A7F1289212CA00919EEB /* MVMError.swift */; };
|
||||||
|
AF60A7F4289212EB00919EEB /* MVMCoreError.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF60A7F3289212EB00919EEB /* MVMCoreError.swift */; };
|
||||||
|
AF69D4E9286E54D500BC6862 /* ActionCallHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF69D4E8286E54D500BC6862 /* ActionCallHandler.swift */; };
|
||||||
|
AF69D4EB286E586200BC6862 /* ActionRestartHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF69D4EA286E586200BC6862 /* ActionRestartHandler.swift */; };
|
||||||
|
AF69D4ED286E5D8C00BC6862 /* ActionCancelHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF69D4EC286E5D8C00BC6862 /* ActionCancelHandler.swift */; };
|
||||||
|
AF69D4EF286E612800BC6862 /* ActionOpenSMSHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF69D4EE286E612800BC6862 /* ActionOpenSMSHandler.swift */; };
|
||||||
|
AF69D4F1286E9D8000BC6862 /* ActionNoopHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF69D4F0286E9D8000BC6862 /* ActionNoopHandler.swift */; };
|
||||||
|
AF69D4F3286E9DCE00BC6862 /* ActionActionsHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF69D4F2286E9DCE00BC6862 /* ActionActionsHandler.swift */; };
|
||||||
|
AF69D4F5286E9F5900BC6862 /* ActionSettingHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF69D4F4286E9F5900BC6862 /* ActionSettingHandler.swift */; };
|
||||||
|
AF69D4F7286EA0B800BC6862 /* ActionPreviousSubmitHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF69D4F6286EA0B800BC6862 /* ActionPreviousSubmitHandler.swift */; };
|
||||||
|
AF70699A287DD02400077CF6 /* ActionContactHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF706999287DD02400077CF6 /* ActionContactHandler.swift */; };
|
||||||
|
AF70699E2880D01400077CF6 /* ActionShareHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF70699D2880D01400077CF6 /* ActionShareHandler.swift */; };
|
||||||
|
AF7069A02880F0EB00077CF6 /* ActionOpenPageHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF70699F2880F0EB00077CF6 /* ActionOpenPageHandler.swift */; };
|
||||||
|
AF787413286DEF8B00670588 /* ActionBackHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF787412286DEF8B00670588 /* ActionBackHandler.swift */; };
|
||||||
AF8D13392774EA1D008AF4A9 /* ActionOpenUrlHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF8D13382774EA1D008AF4A9 /* ActionOpenUrlHandler.swift */; };
|
AF8D13392774EA1D008AF4A9 /* ActionOpenUrlHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF8D13382774EA1D008AF4A9 /* ActionOpenUrlHandler.swift */; };
|
||||||
AFBB96341FBA34310008D868 /* MVMCoreErrorConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB96321FBA34310008D868 /* MVMCoreErrorConstants.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
AFBB96341FBA34310008D868 /* MVMCoreErrorConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB96321FBA34310008D868 /* MVMCoreErrorConstants.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
AFBB96351FBA34310008D868 /* MVMCoreErrorConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB96331FBA34310008D868 /* MVMCoreErrorConstants.m */; };
|
AFBB96351FBA34310008D868 /* MVMCoreErrorConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB96331FBA34310008D868 /* MVMCoreErrorConstants.m */; };
|
||||||
@ -124,8 +138,6 @@
|
|||||||
AFBB96B21FBA3B590008D868 /* MVMCoreGetterUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB96AE1FBA3B590008D868 /* MVMCoreGetterUtility.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
AFBB96B21FBA3B590008D868 /* MVMCoreGetterUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB96AE1FBA3B590008D868 /* MVMCoreGetterUtility.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
AFBB96B31FBA3B590008D868 /* MVMCoreGetterUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB96AF1FBA3B590008D868 /* MVMCoreGetterUtility.m */; };
|
AFBB96B31FBA3B590008D868 /* MVMCoreGetterUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB96AF1FBA3B590008D868 /* MVMCoreGetterUtility.m */; };
|
||||||
AFBB96B81FBA3CEC0008D868 /* MVMCoreActionDelegateProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB96B51FBA3CEC0008D868 /* MVMCoreActionDelegateProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
AFBB96B81FBA3CEC0008D868 /* MVMCoreActionDelegateProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB96B51FBA3CEC0008D868 /* MVMCoreActionDelegateProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
AFBB96B91FBA3CEC0008D868 /* MVMCoreActionHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB96B61FBA3CEC0008D868 /* MVMCoreActionHandler.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
||||||
AFBB96BA1FBA3CEC0008D868 /* MVMCoreActionHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB96B71FBA3CEC0008D868 /* MVMCoreActionHandler.m */; };
|
|
||||||
AFBB96EC1FBA4A260008D868 /* MFHardCodedServerResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB96E91FBA4A260008D868 /* MFHardCodedServerResponse.h */; };
|
AFBB96EC1FBA4A260008D868 /* MFHardCodedServerResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB96E91FBA4A260008D868 /* MFHardCodedServerResponse.h */; };
|
||||||
AFBB96ED1FBA4A260008D868 /* MFHardCodedServerResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB96EA1FBA4A260008D868 /* MFHardCodedServerResponse.m */; };
|
AFBB96ED1FBA4A260008D868 /* MFHardCodedServerResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB96EA1FBA4A260008D868 /* MFHardCodedServerResponse.m */; };
|
||||||
AFEA17A8209B6A1C00BC6740 /* MVMCoreBlockOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = AFEA17A6209B6A1C00BC6740 /* MVMCoreBlockOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
AFEA17A8209B6A1C00BC6740 /* MVMCoreBlockOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = AFEA17A6209B6A1C00BC6740 /* MVMCoreBlockOperation.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
@ -149,8 +161,8 @@
|
|||||||
D268D82B26700292008BD413 /* MVMCoreViewManagerViewControllerProtocolHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = D268D82926700292008BD413 /* MVMCoreViewManagerViewControllerProtocolHelper.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
D268D82B26700292008BD413 /* MVMCoreViewManagerViewControllerProtocolHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = D268D82926700292008BD413 /* MVMCoreViewManagerViewControllerProtocolHelper.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
D268D82C26700292008BD413 /* MVMCoreViewManagerViewControllerProtocolHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = D268D82A26700292008BD413 /* MVMCoreViewManagerViewControllerProtocolHelper.m */; };
|
D268D82C26700292008BD413 /* MVMCoreViewManagerViewControllerProtocolHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = D268D82A26700292008BD413 /* MVMCoreViewManagerViewControllerProtocolHelper.m */; };
|
||||||
D27073B725BB45C4001C7246 /* ActionActionsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27073B625BB45C4001C7246 /* ActionActionsModel.swift */; };
|
D27073B725BB45C4001C7246 /* ActionActionsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27073B625BB45C4001C7246 /* ActionActionsModel.swift */; };
|
||||||
D27073CD25BB4CEF001C7246 /* MVMCoreActionHandler+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27073CC25BB4CEF001C7246 /* MVMCoreActionHandler+Extension.swift */; };
|
D27073CD25BB4CEF001C7246 /* MVMCoreActionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27073CC25BB4CEF001C7246 /* MVMCoreActionHandler.swift */; };
|
||||||
D27073D125BB844B001C7246 /* MVMCoreActionDelegateProtocol+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27073D025BB844B001C7246 /* MVMCoreActionDelegateProtocol+Extension.swift */; };
|
D27073D125BB844B001C7246 /* ActionDelegateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27073D025BB844B001C7246 /* ActionDelegateProtocol.swift */; };
|
||||||
D282AAB62240085300C46919 /* MVMCoreGetterUtility+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AAB52240085300C46919 /* MVMCoreGetterUtility+Extension.swift */; };
|
D282AAB62240085300C46919 /* MVMCoreGetterUtility+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AAB52240085300C46919 /* MVMCoreGetterUtility+Extension.swift */; };
|
||||||
D282AAB82240342D00C46919 /* NSNumber+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AAB72240342D00C46919 /* NSNumber+Extension.swift */; };
|
D282AAB82240342D00C46919 /* NSNumber+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AAB72240342D00C46919 /* NSNumber+Extension.swift */; };
|
||||||
D288D5F526C6EFE000A5C365 /* MVMCoreLoggingHandler+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D288D5F426C6EFE000A5C365 /* MVMCoreLoggingHandler+Extension.swift */; };
|
D288D5F526C6EFE000A5C365 /* MVMCoreLoggingHandler+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D288D5F426C6EFE000A5C365 /* MVMCoreLoggingHandler+Extension.swift */; };
|
||||||
@ -242,6 +254,20 @@
|
|||||||
AF43A7401FC5FA6F008E9347 /* MVMCoreViewProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreViewProtocol.h; sourceTree = "<group>"; };
|
AF43A7401FC5FA6F008E9347 /* MVMCoreViewProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreViewProtocol.h; sourceTree = "<group>"; };
|
||||||
AF43A74A1FC6109F008E9347 /* MVMCoreSessionObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreSessionObject.h; sourceTree = "<group>"; };
|
AF43A74A1FC6109F008E9347 /* MVMCoreSessionObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreSessionObject.h; sourceTree = "<group>"; };
|
||||||
AF43A74B1FC6109F008E9347 /* MVMCoreSessionObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreSessionObject.m; sourceTree = "<group>"; };
|
AF43A74B1FC6109F008E9347 /* MVMCoreSessionObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreSessionObject.m; sourceTree = "<group>"; };
|
||||||
|
AF60A7F1289212CA00919EEB /* MVMError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMError.swift; sourceTree = "<group>"; };
|
||||||
|
AF60A7F3289212EB00919EEB /* MVMCoreError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreError.swift; sourceTree = "<group>"; };
|
||||||
|
AF69D4E8286E54D500BC6862 /* ActionCallHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionCallHandler.swift; sourceTree = "<group>"; };
|
||||||
|
AF69D4EA286E586200BC6862 /* ActionRestartHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionRestartHandler.swift; sourceTree = "<group>"; };
|
||||||
|
AF69D4EC286E5D8C00BC6862 /* ActionCancelHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionCancelHandler.swift; sourceTree = "<group>"; };
|
||||||
|
AF69D4EE286E612800BC6862 /* ActionOpenSMSHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionOpenSMSHandler.swift; sourceTree = "<group>"; };
|
||||||
|
AF69D4F0286E9D8000BC6862 /* ActionNoopHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionNoopHandler.swift; sourceTree = "<group>"; };
|
||||||
|
AF69D4F2286E9DCE00BC6862 /* ActionActionsHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionActionsHandler.swift; sourceTree = "<group>"; };
|
||||||
|
AF69D4F4286E9F5900BC6862 /* ActionSettingHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionSettingHandler.swift; sourceTree = "<group>"; };
|
||||||
|
AF69D4F6286EA0B800BC6862 /* ActionPreviousSubmitHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionPreviousSubmitHandler.swift; sourceTree = "<group>"; };
|
||||||
|
AF706999287DD02400077CF6 /* ActionContactHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionContactHandler.swift; sourceTree = "<group>"; };
|
||||||
|
AF70699D2880D01400077CF6 /* ActionShareHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionShareHandler.swift; sourceTree = "<group>"; };
|
||||||
|
AF70699F2880F0EB00077CF6 /* ActionOpenPageHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionOpenPageHandler.swift; sourceTree = "<group>"; };
|
||||||
|
AF787412286DEF8B00670588 /* ActionBackHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionBackHandler.swift; sourceTree = "<group>"; };
|
||||||
AF8D13382774EA1D008AF4A9 /* ActionOpenUrlHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionOpenUrlHandler.swift; sourceTree = "<group>"; };
|
AF8D13382774EA1D008AF4A9 /* ActionOpenUrlHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionOpenUrlHandler.swift; sourceTree = "<group>"; };
|
||||||
AFBB96321FBA34310008D868 /* MVMCoreErrorConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreErrorConstants.h; sourceTree = "<group>"; };
|
AFBB96321FBA34310008D868 /* MVMCoreErrorConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreErrorConstants.h; sourceTree = "<group>"; };
|
||||||
AFBB96331FBA34310008D868 /* MVMCoreErrorConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreErrorConstants.m; sourceTree = "<group>"; };
|
AFBB96331FBA34310008D868 /* MVMCoreErrorConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreErrorConstants.m; sourceTree = "<group>"; };
|
||||||
@ -274,8 +300,6 @@
|
|||||||
AFBB96AE1FBA3B590008D868 /* MVMCoreGetterUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreGetterUtility.h; sourceTree = "<group>"; };
|
AFBB96AE1FBA3B590008D868 /* MVMCoreGetterUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreGetterUtility.h; sourceTree = "<group>"; };
|
||||||
AFBB96AF1FBA3B590008D868 /* MVMCoreGetterUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreGetterUtility.m; sourceTree = "<group>"; };
|
AFBB96AF1FBA3B590008D868 /* MVMCoreGetterUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreGetterUtility.m; sourceTree = "<group>"; };
|
||||||
AFBB96B51FBA3CEC0008D868 /* MVMCoreActionDelegateProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreActionDelegateProtocol.h; sourceTree = "<group>"; };
|
AFBB96B51FBA3CEC0008D868 /* MVMCoreActionDelegateProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreActionDelegateProtocol.h; sourceTree = "<group>"; };
|
||||||
AFBB96B61FBA3CEC0008D868 /* MVMCoreActionHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreActionHandler.h; sourceTree = "<group>"; };
|
|
||||||
AFBB96B71FBA3CEC0008D868 /* MVMCoreActionHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreActionHandler.m; sourceTree = "<group>"; };
|
|
||||||
AFBB96D21FBA44420008D868 /* VZWAuthentication.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = VZWAuthentication.framework; path = ../../SharedFrameworks/VZWAuthentication.framework; sourceTree = "<group>"; };
|
AFBB96D21FBA44420008D868 /* VZWAuthentication.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = VZWAuthentication.framework; path = ../../SharedFrameworks/VZWAuthentication.framework; sourceTree = "<group>"; };
|
||||||
AFBB96E91FBA4A260008D868 /* MFHardCodedServerResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFHardCodedServerResponse.h; sourceTree = "<group>"; };
|
AFBB96E91FBA4A260008D868 /* MFHardCodedServerResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFHardCodedServerResponse.h; sourceTree = "<group>"; };
|
||||||
AFBB96EA1FBA4A260008D868 /* MFHardCodedServerResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFHardCodedServerResponse.m; sourceTree = "<group>"; };
|
AFBB96EA1FBA4A260008D868 /* MFHardCodedServerResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFHardCodedServerResponse.m; sourceTree = "<group>"; };
|
||||||
@ -300,8 +324,8 @@
|
|||||||
D268D82926700292008BD413 /* MVMCoreViewManagerViewControllerProtocolHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreViewManagerViewControllerProtocolHelper.h; sourceTree = "<group>"; };
|
D268D82926700292008BD413 /* MVMCoreViewManagerViewControllerProtocolHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreViewManagerViewControllerProtocolHelper.h; sourceTree = "<group>"; };
|
||||||
D268D82A26700292008BD413 /* MVMCoreViewManagerViewControllerProtocolHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreViewManagerViewControllerProtocolHelper.m; sourceTree = "<group>"; };
|
D268D82A26700292008BD413 /* MVMCoreViewManagerViewControllerProtocolHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreViewManagerViewControllerProtocolHelper.m; sourceTree = "<group>"; };
|
||||||
D27073B625BB45C4001C7246 /* ActionActionsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionActionsModel.swift; sourceTree = "<group>"; };
|
D27073B625BB45C4001C7246 /* ActionActionsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionActionsModel.swift; sourceTree = "<group>"; };
|
||||||
D27073CC25BB4CEF001C7246 /* MVMCoreActionHandler+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreActionHandler+Extension.swift"; sourceTree = "<group>"; };
|
D27073CC25BB4CEF001C7246 /* MVMCoreActionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreActionHandler.swift; sourceTree = "<group>"; };
|
||||||
D27073D025BB844B001C7246 /* MVMCoreActionDelegateProtocol+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreActionDelegateProtocol+Extension.swift"; sourceTree = "<group>"; };
|
D27073D025BB844B001C7246 /* ActionDelegateProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionDelegateProtocol.swift; sourceTree = "<group>"; };
|
||||||
D282AAB52240085300C46919 /* MVMCoreGetterUtility+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreGetterUtility+Extension.swift"; sourceTree = "<group>"; };
|
D282AAB52240085300C46919 /* MVMCoreGetterUtility+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreGetterUtility+Extension.swift"; sourceTree = "<group>"; };
|
||||||
D282AAB72240342D00C46919 /* NSNumber+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSNumber+Extension.swift"; sourceTree = "<group>"; };
|
D282AAB72240342D00C46919 /* NSNumber+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSNumber+Extension.swift"; sourceTree = "<group>"; };
|
||||||
D288D5F426C6EFE000A5C365 /* MVMCoreLoggingHandler+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreLoggingHandler+Extension.swift"; sourceTree = "<group>"; };
|
D288D5F426C6EFE000A5C365 /* MVMCoreLoggingHandler+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreLoggingHandler+Extension.swift"; sourceTree = "<group>"; };
|
||||||
@ -381,6 +405,8 @@
|
|||||||
8876D5D41FB50AAB00EB2E3D /* Utility */ = {
|
8876D5D41FB50AAB00EB2E3D /* Utility */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
AF60A7F1289212CA00919EEB /* MVMError.swift */,
|
||||||
|
AF60A7F3289212EB00919EEB /* MVMCoreError.swift */,
|
||||||
881D26911FCC9D180079C521 /* MVMCoreErrorObject.h */,
|
881D26911FCC9D180079C521 /* MVMCoreErrorObject.h */,
|
||||||
881D268F1FCC9D180079C521 /* MVMCoreErrorObject.m */,
|
881D268F1FCC9D180079C521 /* MVMCoreErrorObject.m */,
|
||||||
881D26921FCC9D180079C521 /* MVMCoreOperation.h */,
|
881D26921FCC9D180079C521 /* MVMCoreOperation.h */,
|
||||||
@ -462,19 +488,7 @@
|
|||||||
1DAD0FFD26AAB3FF00216E83 /* ActionRunJavaScriptModel.swift */,
|
1DAD0FFD26AAB3FF00216E83 /* ActionRunJavaScriptModel.swift */,
|
||||||
016FF6EC259A4E3E00F5E4AA /* Client Parameters */,
|
016FF6EC259A4E3E00F5E4AA /* Client Parameters */,
|
||||||
01F2A03523A80A7300D954D8 /* ActionModelProtocol.swift */,
|
01F2A03523A80A7300D954D8 /* ActionModelProtocol.swift */,
|
||||||
946EE1BB237B691A0036751F /* ActionOpenPageModel.swift */,
|
|
||||||
01DB1F2A26444F7F000F1AF4 /* ActionOpenPageProtocol.swift */,
|
01DB1F2A26444F7F000F1AF4 /* ActionOpenPageProtocol.swift */,
|
||||||
01F2A04B23A82B1B00D954D8 /* ActionCallModel.swift */,
|
|
||||||
01C851D023CF97FE0021F976 /* ActionBackModel.swift */,
|
|
||||||
0AFF597923FC6E60005C24E8 /* ActionShareModel.swift */,
|
|
||||||
94C014D024211869005811A9 /* ActionRestartModel.swift */,
|
|
||||||
94C014D2242119E6005811A9 /* ActionPreviousSubmitModel.swift */,
|
|
||||||
94C014D424211AF0005811A9 /* ActionCancelModel.swift */,
|
|
||||||
94C014D824212360005811A9 /* ActionSettingModel.swift */,
|
|
||||||
BB780ADE250F8C890030BD2F /* ActionNoopModel.swift */,
|
|
||||||
D27073B625BB45C4001C7246 /* ActionActionsModel.swift */,
|
|
||||||
0AEBB84525FA75C000EA80EE /* ActionOpenSMSModel.swift */,
|
|
||||||
0ACC81A12613C73800A9C886 /* ActionContactModel.swift */,
|
|
||||||
);
|
);
|
||||||
path = ActionType;
|
path = ActionType;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -619,13 +633,35 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
AFBB96B51FBA3CEC0008D868 /* MVMCoreActionDelegateProtocol.h */,
|
AFBB96B51FBA3CEC0008D868 /* MVMCoreActionDelegateProtocol.h */,
|
||||||
D27073D025BB844B001C7246 /* MVMCoreActionDelegateProtocol+Extension.swift */,
|
D27073D025BB844B001C7246 /* ActionDelegateProtocol.swift */,
|
||||||
AFBB96B61FBA3CEC0008D868 /* MVMCoreActionHandler.h */,
|
D27073CC25BB4CEF001C7246 /* MVMCoreActionHandler.swift */,
|
||||||
AFBB96B71FBA3CEC0008D868 /* MVMCoreActionHandler.m */,
|
946EE1BB237B691A0036751F /* ActionOpenPageModel.swift */,
|
||||||
D27073CC25BB4CEF001C7246 /* MVMCoreActionHandler+Extension.swift */,
|
AF70699F2880F0EB00077CF6 /* ActionOpenPageHandler.swift */,
|
||||||
AF130B8D2788DF6E00C6C03C /* OpenURLOptionsModel.swift */,
|
AF130B8D2788DF6E00C6C03C /* OpenURLOptionsModel.swift */,
|
||||||
01F2A03823A812DD00D954D8 /* ActionOpenUrlModel.swift */,
|
01F2A03823A812DD00D954D8 /* ActionOpenUrlModel.swift */,
|
||||||
AF8D13382774EA1D008AF4A9 /* ActionOpenUrlHandler.swift */,
|
AF8D13382774EA1D008AF4A9 /* ActionOpenUrlHandler.swift */,
|
||||||
|
01C851D023CF97FE0021F976 /* ActionBackModel.swift */,
|
||||||
|
AF787412286DEF8B00670588 /* ActionBackHandler.swift */,
|
||||||
|
01F2A04B23A82B1B00D954D8 /* ActionCallModel.swift */,
|
||||||
|
AF69D4E8286E54D500BC6862 /* ActionCallHandler.swift */,
|
||||||
|
94C014D024211869005811A9 /* ActionRestartModel.swift */,
|
||||||
|
AF69D4EA286E586200BC6862 /* ActionRestartHandler.swift */,
|
||||||
|
94C014D424211AF0005811A9 /* ActionCancelModel.swift */,
|
||||||
|
AF69D4EC286E5D8C00BC6862 /* ActionCancelHandler.swift */,
|
||||||
|
0AEBB84525FA75C000EA80EE /* ActionOpenSMSModel.swift */,
|
||||||
|
AF69D4EE286E612800BC6862 /* ActionOpenSMSHandler.swift */,
|
||||||
|
BB780ADE250F8C890030BD2F /* ActionNoopModel.swift */,
|
||||||
|
AF69D4F0286E9D8000BC6862 /* ActionNoopHandler.swift */,
|
||||||
|
D27073B625BB45C4001C7246 /* ActionActionsModel.swift */,
|
||||||
|
AF69D4F2286E9DCE00BC6862 /* ActionActionsHandler.swift */,
|
||||||
|
94C014D824212360005811A9 /* ActionSettingModel.swift */,
|
||||||
|
AF69D4F4286E9F5900BC6862 /* ActionSettingHandler.swift */,
|
||||||
|
94C014D2242119E6005811A9 /* ActionPreviousSubmitModel.swift */,
|
||||||
|
AF69D4F6286EA0B800BC6862 /* ActionPreviousSubmitHandler.swift */,
|
||||||
|
0ACC81A12613C73800A9C886 /* ActionContactModel.swift */,
|
||||||
|
AF706999287DD02400077CF6 /* ActionContactHandler.swift */,
|
||||||
|
0AFF597923FC6E60005C24E8 /* ActionShareModel.swift */,
|
||||||
|
AF70699D2880D01400077CF6 /* ActionShareHandler.swift */,
|
||||||
);
|
);
|
||||||
path = ActionHandling;
|
path = ActionHandling;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -749,7 +785,6 @@
|
|||||||
AF43A5831FBB66DE008E9347 /* MVMCoreConstants.h in Headers */,
|
AF43A5831FBB66DE008E9347 /* MVMCoreConstants.h in Headers */,
|
||||||
AFED77A81FCCA29400BAE689 /* MVMCoreViewControllerStoryBoardMappingObject.h in Headers */,
|
AFED77A81FCCA29400BAE689 /* MVMCoreViewControllerStoryBoardMappingObject.h in Headers */,
|
||||||
AFEEE8191FCDEB8D00B5EDD0 /* MVMCoreLoggingDelegateProtocol.h in Headers */,
|
AFEEE8191FCDEB8D00B5EDD0 /* MVMCoreLoggingDelegateProtocol.h in Headers */,
|
||||||
AFBB96B91FBA3CEC0008D868 /* MVMCoreActionHandler.h in Headers */,
|
|
||||||
AF43A74C1FC6109F008E9347 /* MVMCoreSessionObject.h in Headers */,
|
AF43A74C1FC6109F008E9347 /* MVMCoreSessionObject.h in Headers */,
|
||||||
8876D5F41FB50AB000EB2E3D /* UILabel+MFCustom.h in Headers */,
|
8876D5F41FB50AB000EB2E3D /* UILabel+MFCustom.h in Headers */,
|
||||||
AFFCFA681FCCC0D700FD0730 /* MVMCoreLoadingViewControllerProtocol.h in Headers */,
|
AFFCFA681FCCC0D700FD0730 /* MVMCoreLoadingViewControllerProtocol.h in Headers */,
|
||||||
@ -852,12 +887,14 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
AF69D4ED286E5D8C00BC6862 /* ActionCancelHandler.swift in Sources */,
|
||||||
AFED77A71FCCA29400BAE689 /* MVMCoreViewControllerProgrammaticMappingObject.m in Sources */,
|
AFED77A71FCCA29400BAE689 /* MVMCoreViewControllerProgrammaticMappingObject.m in Sources */,
|
||||||
946EE1A7237B5B1C0036751F /* ModelRegistry.swift in Sources */,
|
946EE1A7237B5B1C0036751F /* ModelRegistry.swift in Sources */,
|
||||||
AFBB96641FBA3A570008D868 /* MVMCoreLoadHandler.m in Sources */,
|
AFBB96641FBA3A570008D868 /* MVMCoreLoadHandler.m in Sources */,
|
||||||
AFFCFA671FCCC0D700FD0730 /* MVMCoreLoadingOverlayHandler.m in Sources */,
|
AFFCFA671FCCC0D700FD0730 /* MVMCoreLoadingOverlayHandler.m in Sources */,
|
||||||
AF8D13392774EA1D008AF4A9 /* ActionOpenUrlHandler.swift in Sources */,
|
AF8D13392774EA1D008AF4A9 /* ActionOpenUrlHandler.swift in Sources */,
|
||||||
AF130B8E2788DF6E00C6C03C /* OpenURLOptionsModel.swift in Sources */,
|
AF130B8E2788DF6E00C6C03C /* OpenURLOptionsModel.swift in Sources */,
|
||||||
|
AF69D4EB286E586200BC6862 /* ActionRestartHandler.swift in Sources */,
|
||||||
AFBB968E1FBA3A9A0008D868 /* MVMCoreNavigationHandler.m in Sources */,
|
AFBB968E1FBA3A9A0008D868 /* MVMCoreNavigationHandler.m in Sources */,
|
||||||
BB780ADF250F8C890030BD2F /* ActionNoopModel.swift in Sources */,
|
BB780ADF250F8C890030BD2F /* ActionNoopModel.swift in Sources */,
|
||||||
D2E1FAD92260C3E400AEFD8C /* DelegateObject.swift in Sources */,
|
D2E1FAD92260C3E400AEFD8C /* DelegateObject.swift in Sources */,
|
||||||
@ -869,13 +906,14 @@
|
|||||||
01F2A04C23A82B1B00D954D8 /* ActionCallModel.swift in Sources */,
|
01F2A04C23A82B1B00D954D8 /* ActionCallModel.swift in Sources */,
|
||||||
8876D5ED1FB50AB000EB2E3D /* NSDictionary+MFConvenience.m in Sources */,
|
8876D5ED1FB50AB000EB2E3D /* NSDictionary+MFConvenience.m in Sources */,
|
||||||
AFBB968C1FBA3A9A0008D868 /* MVMCoreDismissViewControllerOperation.m in Sources */,
|
AFBB968C1FBA3A9A0008D868 /* MVMCoreDismissViewControllerOperation.m in Sources */,
|
||||||
AFBB96BA1FBA3CEC0008D868 /* MVMCoreActionHandler.m in Sources */,
|
|
||||||
AFBB96ED1FBA4A260008D868 /* MFHardCodedServerResponse.m in Sources */,
|
AFBB96ED1FBA4A260008D868 /* MFHardCodedServerResponse.m in Sources */,
|
||||||
AF43A74D1FC6109F008E9347 /* MVMCoreSessionObject.m in Sources */,
|
AF43A74D1FC6109F008E9347 /* MVMCoreSessionObject.m in Sources */,
|
||||||
D282AAB62240085300C46919 /* MVMCoreGetterUtility+Extension.swift in Sources */,
|
D282AAB62240085300C46919 /* MVMCoreGetterUtility+Extension.swift in Sources */,
|
||||||
AFBB96901FBA3A9A0008D868 /* MVMCoreNavigationObject.m in Sources */,
|
AFBB96901FBA3A9A0008D868 /* MVMCoreNavigationObject.m in Sources */,
|
||||||
1DAD0FFE26AAB40000216E83 /* ActionRunJavaScriptModel.swift in Sources */,
|
1DAD0FFE26AAB40000216E83 /* ActionRunJavaScriptModel.swift in Sources */,
|
||||||
946EE1AB237B5C940036751F /* Decoder.swift in Sources */,
|
946EE1AB237B5C940036751F /* Decoder.swift in Sources */,
|
||||||
|
AF70699A287DD02400077CF6 /* ActionContactHandler.swift in Sources */,
|
||||||
|
AF69D4F3286E9DCE00BC6862 /* ActionActionsHandler.swift in Sources */,
|
||||||
946EE1BC237B691A0036751F /* ActionOpenPageModel.swift in Sources */,
|
946EE1BC237B691A0036751F /* ActionOpenPageModel.swift in Sources */,
|
||||||
0A42538F23F3414800554656 /* Codable+Helpers.swift in Sources */,
|
0A42538F23F3414800554656 /* Codable+Helpers.swift in Sources */,
|
||||||
881D26931FCC9D180079C521 /* MVMCoreErrorObject.m in Sources */,
|
881D26931FCC9D180079C521 /* MVMCoreErrorObject.m in Sources */,
|
||||||
@ -885,33 +923,40 @@
|
|||||||
30349BF21FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m in Sources */,
|
30349BF21FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m in Sources */,
|
||||||
D2DEDCB923C6400600C44CC4 /* UnitInterval.swift in Sources */,
|
D2DEDCB923C6400600C44CC4 /* UnitInterval.swift in Sources */,
|
||||||
94C014D3242119E6005811A9 /* ActionPreviousSubmitModel.swift in Sources */,
|
94C014D3242119E6005811A9 /* ActionPreviousSubmitModel.swift in Sources */,
|
||||||
|
AF60A7F2289212CA00919EEB /* MVMError.swift in Sources */,
|
||||||
8876D5E91FB50AB000EB2E3D /* NSArray+MFConvenience.m in Sources */,
|
8876D5E91FB50AB000EB2E3D /* NSArray+MFConvenience.m in Sources */,
|
||||||
D27073B725BB45C4001C7246 /* ActionActionsModel.swift in Sources */,
|
D27073B725BB45C4001C7246 /* ActionActionsModel.swift in Sources */,
|
||||||
946EE1B2237B5F260036751F /* JSONValue.swift in Sources */,
|
946EE1B2237B5F260036751F /* JSONValue.swift in Sources */,
|
||||||
0ACC81A22613C73800A9C886 /* ActionContactModel.swift in Sources */,
|
0ACC81A22613C73800A9C886 /* ActionContactModel.swift in Sources */,
|
||||||
AFBB96971FBA3A9A0008D868 /* MVMCorePresentViewControllerOperation.m in Sources */,
|
AFBB96971FBA3A9A0008D868 /* MVMCorePresentViewControllerOperation.m in Sources */,
|
||||||
|
AF69D4EF286E612800BC6862 /* ActionOpenSMSHandler.swift in Sources */,
|
||||||
AF43A5781FBA5B7C008E9347 /* MVMCoreJSONConstants.m in Sources */,
|
AF43A5781FBA5B7C008E9347 /* MVMCoreJSONConstants.m in Sources */,
|
||||||
AFBB96691FBA3A570008D868 /* MVMCoreRequestParameters.m in Sources */,
|
AFBB96691FBA3A570008D868 /* MVMCoreRequestParameters.m in Sources */,
|
||||||
AFED77A31FCCA29400BAE689 /* MVMCoreViewControllerNibMappingObject.m in Sources */,
|
AFED77A31FCCA29400BAE689 /* MVMCoreViewControllerNibMappingObject.m in Sources */,
|
||||||
8876D5EB1FB50AB000EB2E3D /* NSDecimalNumber+MFConvenience.m in Sources */,
|
8876D5EB1FB50AB000EB2E3D /* NSDecimalNumber+MFConvenience.m in Sources */,
|
||||||
01F2A03923A812DD00D954D8 /* ActionOpenUrlModel.swift in Sources */,
|
01F2A03923A812DD00D954D8 /* ActionOpenUrlModel.swift in Sources */,
|
||||||
01934FE725A4FFC2003DCD67 /* ClientParameterActionProtocol.swift in Sources */,
|
01934FE725A4FFC2003DCD67 /* ClientParameterActionProtocol.swift in Sources */,
|
||||||
|
AF69D4E9286E54D500BC6862 /* ActionCallHandler.swift in Sources */,
|
||||||
AFBB96351FBA34310008D868 /* MVMCoreErrorConstants.m in Sources */,
|
AFBB96351FBA34310008D868 /* MVMCoreErrorConstants.m in Sources */,
|
||||||
AF43A5881FBB67D6008E9347 /* MVMCoreActionUtility.m in Sources */,
|
AF43A5881FBB67D6008E9347 /* MVMCoreActionUtility.m in Sources */,
|
||||||
AFED77A61FCCA29400BAE689 /* MVMCoreViewControllerStoryBoardMappingObject.m in Sources */,
|
AFED77A61FCCA29400BAE689 /* MVMCoreViewControllerStoryBoardMappingObject.m in Sources */,
|
||||||
016CF36925FA6DD400B82A1F /* ClientParameterHandler.swift in Sources */,
|
016CF36925FA6DD400B82A1F /* ClientParameterHandler.swift in Sources */,
|
||||||
|
AF69D4F7286EA0B800BC6862 /* ActionPreviousSubmitHandler.swift in Sources */,
|
||||||
AF43A57C1FBA5E6A008E9347 /* MVMCoreHardcodedStringsConstants.m in Sources */,
|
AF43A57C1FBA5E6A008E9347 /* MVMCoreHardcodedStringsConstants.m in Sources */,
|
||||||
0AFF597A23FC6E60005C24E8 /* ActionShareModel.swift in Sources */,
|
0AFF597A23FC6E60005C24E8 /* ActionShareModel.swift in Sources */,
|
||||||
AFEEE81F1FCDF3CA00B5EDD0 /* MVMCoreLoggingHandler.m in Sources */,
|
AFEEE81F1FCDF3CA00B5EDD0 /* MVMCoreLoggingHandler.m in Sources */,
|
||||||
D27073CD25BB4CEF001C7246 /* MVMCoreActionHandler+Extension.swift in Sources */,
|
AF69D4F5286E9F5900BC6862 /* ActionSettingHandler.swift in Sources */,
|
||||||
|
D27073CD25BB4CEF001C7246 /* MVMCoreActionHandler.swift in Sources */,
|
||||||
01F2A05223A8325100D954D8 /* ModelMapping.swift in Sources */,
|
01F2A05223A8325100D954D8 /* ModelMapping.swift in Sources */,
|
||||||
8876D5F51FB50AB000EB2E3D /* UILabel+MFCustom.m in Sources */,
|
8876D5F51FB50AB000EB2E3D /* UILabel+MFCustom.m in Sources */,
|
||||||
AFBB96B31FBA3B590008D868 /* MVMCoreGetterUtility.m in Sources */,
|
AFBB96B31FBA3B590008D868 /* MVMCoreGetterUtility.m in Sources */,
|
||||||
AF43A7071FC4D7A2008E9347 /* MVMCoreObject.m in Sources */,
|
AF43A7071FC4D7A2008E9347 /* MVMCoreObject.m in Sources */,
|
||||||
94C014D924212360005811A9 /* ActionSettingModel.swift in Sources */,
|
94C014D924212360005811A9 /* ActionSettingModel.swift in Sources */,
|
||||||
D2DEDCB723C63F3B00C44CC4 /* Clamping.swift in Sources */,
|
D2DEDCB723C63F3B00C44CC4 /* Clamping.swift in Sources */,
|
||||||
|
AF70699E2880D01400077CF6 /* ActionShareHandler.swift in Sources */,
|
||||||
01DF561421F90ADC00CC099B /* Dictionary+MFConvenience.swift in Sources */,
|
01DF561421F90ADC00CC099B /* Dictionary+MFConvenience.swift in Sources */,
|
||||||
EA3B264C25FC0B7600008074 /* ModelHandlerProtocol.swift in Sources */,
|
EA3B264C25FC0B7600008074 /* ModelHandlerProtocol.swift in Sources */,
|
||||||
|
AF7069A02880F0EB00077CF6 /* ActionOpenPageHandler.swift in Sources */,
|
||||||
AFBB96B11FBA3B590008D868 /* MVMCoreDispatchUtility.m in Sources */,
|
AFBB96B11FBA3B590008D868 /* MVMCoreDispatchUtility.m in Sources */,
|
||||||
946EE1A3237B59C30036751F /* ModelProtocol.swift in Sources */,
|
946EE1A3237B59C30036751F /* ModelProtocol.swift in Sources */,
|
||||||
AFEA17A9209B6A1C00BC6740 /* MVMCoreBlockOperation.m in Sources */,
|
AFEA17A9209B6A1C00BC6740 /* MVMCoreBlockOperation.m in Sources */,
|
||||||
@ -920,13 +965,16 @@
|
|||||||
EA09CD62282ACDDB00A7835F /* Decoder+UserInfo.swift in Sources */,
|
EA09CD62282ACDDB00A7835F /* Decoder+UserInfo.swift in Sources */,
|
||||||
EA09CD99282BF83600A7835F /* DecodableDefault.swift in Sources */,
|
EA09CD99282BF83600A7835F /* DecodableDefault.swift in Sources */,
|
||||||
01C851D123CF97FE0021F976 /* ActionBackModel.swift in Sources */,
|
01C851D123CF97FE0021F976 /* ActionBackModel.swift in Sources */,
|
||||||
D27073D125BB844B001C7246 /* MVMCoreActionDelegateProtocol+Extension.swift in Sources */,
|
D27073D125BB844B001C7246 /* ActionDelegateProtocol.swift in Sources */,
|
||||||
AFBB96921FBA3A9A0008D868 /* MVMCoreNavigationOperation.m in Sources */,
|
AFBB96921FBA3A9A0008D868 /* MVMCoreNavigationOperation.m in Sources */,
|
||||||
AFBB96611FBA3A570008D868 /* MVMCoreLoadObject.m in Sources */,
|
AFBB96611FBA3A570008D868 /* MVMCoreLoadObject.m in Sources */,
|
||||||
|
AF787413286DEF8B00670588 /* ActionBackHandler.swift in Sources */,
|
||||||
946EE1B4237B619D0036751F /* Encoder.swift in Sources */,
|
946EE1B4237B619D0036751F /* Encoder.swift in Sources */,
|
||||||
|
AF60A7F4289212EB00919EEB /* MVMCoreError.swift in Sources */,
|
||||||
AFBB96941FBA3A9A0008D868 /* MVMCorePresentAnimationOperation.m in Sources */,
|
AFBB96941FBA3A9A0008D868 /* MVMCorePresentAnimationOperation.m in Sources */,
|
||||||
94C014D524211AF0005811A9 /* ActionCancelModel.swift in Sources */,
|
94C014D524211AF0005811A9 /* ActionCancelModel.swift in Sources */,
|
||||||
AF43A5841FBB66DE008E9347 /* MVMCoreConstants.m in Sources */,
|
AF43A5841FBB66DE008E9347 /* MVMCoreConstants.m in Sources */,
|
||||||
|
AF69D4F1286E9D8000BC6862 /* ActionNoopHandler.swift in Sources */,
|
||||||
016FF6F2259A4FCC00F5E4AA /* ClientParameterModel.swift in Sources */,
|
016FF6F2259A4FCC00F5E4AA /* ClientParameterModel.swift in Sources */,
|
||||||
D2DEDCBB23C65BC300C44CC4 /* Percent.swift in Sources */,
|
D2DEDCBB23C65BC300C44CC4 /* Percent.swift in Sources */,
|
||||||
AFBB966A1FBA3A570008D868 /* MVMCoreLoadRequestOperation.m in Sources */,
|
AFBB966A1FBA3A570008D868 /* MVMCoreLoadRequestOperation.m in Sources */,
|
||||||
@ -1098,7 +1146,7 @@
|
|||||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||||
MARKETING_VERSION = 3.0;
|
MARKETING_VERSION = 3.1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.vzw.MVMCore;
|
PRODUCT_BUNDLE_IDENTIFIER = com.vzw.MVMCore;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
@ -1126,7 +1174,7 @@
|
|||||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||||
MARKETING_VERSION = 3.0;
|
MARKETING_VERSION = 3.1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.vzw.MVMCore;
|
PRODUCT_BUNDLE_IDENTIFIER = com.vzw.MVMCore;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
|
|||||||
51
MVMCore/MVMCore/ActionHandling/ActionActionsHandler.swift
Normal file
51
MVMCore/MVMCore/ActionHandling/ActionActionsHandler.swift
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
//
|
||||||
|
// ActionActionsHandler.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 6/30/22.
|
||||||
|
// Copyright © 2022 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
open class ActionActionsHandler: MVMCoreJSONActionHandlerProtocol {
|
||||||
|
required public init() {}
|
||||||
|
|
||||||
|
open func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||||
|
guard let model = model as? ActionActionsModel else { return }
|
||||||
|
let actions = JSON.arrayForKey("actions")
|
||||||
|
if model.concurrent {
|
||||||
|
await withThrowingTaskGroup(of: Void.self) { group in
|
||||||
|
for case let (index, action as [AnyHashable: Any]) in actions.enumerated() {
|
||||||
|
group.addTask{
|
||||||
|
try await MVMCoreActionHandler.shared()?.handleAction(with: model.actions[index], json: action, additionalData: additionalData, delegateObject: delegateObject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for case let (index, action as [AnyHashable: Any]) in actions.enumerated() {
|
||||||
|
try Task.checkCancellation()
|
||||||
|
try await MVMCoreActionHandler.shared()?.handleAction(with: model.actions[index], json: action, additionalData: additionalData, delegateObject: delegateObject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open func execute(with model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||||
|
guard let model = model as? ActionActionsModel else { return }
|
||||||
|
if model.concurrent {
|
||||||
|
// TODO: inspect warning.
|
||||||
|
await withThrowingTaskGroup(of: Void.self) { group in
|
||||||
|
for action in model.actions {
|
||||||
|
group.addTask{
|
||||||
|
try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: action, additionalData: additionalData, delegateObject: delegateObject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for action in model.actions {
|
||||||
|
try Task.checkCancellation()
|
||||||
|
try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: action, additionalData: additionalData, delegateObject: delegateObject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers open class ActionActionsModel: ActionModelProtocol {
|
public struct ActionActionsModel: ActionModelProtocol {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -46,7 +46,7 @@ import Foundation
|
|||||||
// MARK: - Codec
|
// MARK: - Codec
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
actions = try typeContainer.decodeModels(codingKey: .actions)
|
actions = try typeContainer.decodeModels(codingKey: .actions)
|
||||||
if let concurrent = try typeContainer.decodeIfPresent(Bool.self, forKey: .concurrent) {
|
if let concurrent = try typeContainer.decodeIfPresent(Bool.self, forKey: .concurrent) {
|
||||||
32
MVMCore/MVMCore/ActionHandling/ActionBackHandler.swift
Normal file
32
MVMCore/MVMCore/ActionHandling/ActionBackHandler.swift
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
//
|
||||||
|
// ActionBackHandler.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 6/30/22.
|
||||||
|
// Copyright © 2022 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
open class ActionBackHandler: MVMCoreJSONActionHandlerProtocol {
|
||||||
|
required public init() {}
|
||||||
|
|
||||||
|
open func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||||
|
if let closure = delegateObject?.actionDelegate?.handleBackAction {
|
||||||
|
// Legacy code will use the old handler function and break the task chain here.
|
||||||
|
closure(JSON, additionalData)
|
||||||
|
} else {
|
||||||
|
try await execute(with: model, delegateObject: delegateObject, additionalData: additionalData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open func execute(with model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||||
|
await withCheckedContinuation { continuation in
|
||||||
|
Task(priority: .userInitiated) {
|
||||||
|
await MVMCoreNavigationHandler.shared()?.removeCurrentViewController(true, completionHandler: {
|
||||||
|
continuation.resume()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
@objcMembers public class ActionBackModel: ActionModelProtocol {
|
public struct ActionBackModel: ActionModelProtocol {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
19
MVMCore/MVMCore/ActionHandling/ActionCallHandler.swift
Normal file
19
MVMCore/MVMCore/ActionHandling/ActionCallHandler.swift
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// ActionCallHandler.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 6/30/22.
|
||||||
|
// Copyright © 2022 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
open class ActionCallHandler: MVMCoreActionHandlerProtocol {
|
||||||
|
required public init() {}
|
||||||
|
|
||||||
|
open func execute(with model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||||
|
guard let model = model as? ActionCallModel else { return }
|
||||||
|
// https://developer.apple.com/library/archive/featuredarticles/iPhoneURLScheme_Reference/PhoneLinks/PhoneLinks.html#//apple_ref/doc/uid/TP40007899-CH6-SW1
|
||||||
|
try await ActionOpenUrlHandler.openURL(with: "tel://\(model.callNumber)")
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
@objcMembers public class ActionCallModel: ActionModelProtocol {
|
public struct ActionCallModel: ActionModelProtocol {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
20
MVMCore/MVMCore/ActionHandling/ActionCancelHandler.swift
Normal file
20
MVMCore/MVMCore/ActionHandling/ActionCancelHandler.swift
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// ActionCancelHandler.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 6/30/22.
|
||||||
|
// Copyright © 2022 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
open class ActionCancelHandler: MVMCoreJSONActionHandlerProtocol {
|
||||||
|
required public init() {}
|
||||||
|
|
||||||
|
open func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||||
|
delegateObject?.actionDelegate?.handleCancel?(JSON, additionalData: additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
open func execute(with model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
@objcMembers public class ActionCancelModel: ActionModelProtocol {
|
public struct ActionCancelModel: ActionModelProtocol {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
116
MVMCore/MVMCore/ActionHandling/ActionContactHandler.swift
Normal file
116
MVMCore/MVMCore/ActionHandling/ActionContactHandler.swift
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
//
|
||||||
|
// ActionContactHandler.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 7/12/22.
|
||||||
|
// Copyright © 2022 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import ContactsUI
|
||||||
|
|
||||||
|
open class ActionContactHandler: NSObject, MVMCoreActionHandlerProtocol, CNContactPickerDelegate, CNContactViewControllerDelegate {
|
||||||
|
|
||||||
|
/// A continuation to keep the process running until we are finished.
|
||||||
|
private var continuation: CheckedContinuation<Bool, Never>?
|
||||||
|
|
||||||
|
required public override init() {}
|
||||||
|
|
||||||
|
/// Sets the continuation and runs the closure.
|
||||||
|
private func continueInTask(with closure: @escaping () async -> Void) async {
|
||||||
|
let _: Bool = await withCheckedContinuation { continuation in
|
||||||
|
self.continuation = continuation
|
||||||
|
Task(priority: .userInitiated) {
|
||||||
|
await closure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open func execute(with model: ActionModelProtocol, delegateObject: DelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) async throws {
|
||||||
|
guard let model = model as? ActionContactModel else { return }
|
||||||
|
|
||||||
|
switch model.approach {
|
||||||
|
case .add:
|
||||||
|
await continueInTask {
|
||||||
|
await MainActor.run {
|
||||||
|
let controller = CNContactPickerViewController()
|
||||||
|
|
||||||
|
// Setting to accessibilityValue as a workaround to pass data via the delegate function.
|
||||||
|
controller.view.accessibilityIdentifier = model.phoneNumber
|
||||||
|
controller.delegate = self
|
||||||
|
MVMCoreNavigationHandler.shared()?.present(controller, animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case .create:
|
||||||
|
let contact = CNMutableContact()
|
||||||
|
let phone = CNLabeledValue(label: CNLabelOther, value: CNPhoneNumber(stringValue: model.phoneNumber))
|
||||||
|
contact.phoneNumbers = [phone]
|
||||||
|
if let givenName = model.firstName {
|
||||||
|
contact.givenName = givenName
|
||||||
|
}
|
||||||
|
if let familyName = model.lastName {
|
||||||
|
contact.familyName = familyName
|
||||||
|
}
|
||||||
|
|
||||||
|
let store = CNContactStore()
|
||||||
|
await continueInTask {
|
||||||
|
await MainActor.run {
|
||||||
|
let controller = CNContactViewController(forNewContact: contact)
|
||||||
|
controller.contactStore = store
|
||||||
|
controller.delegate = self
|
||||||
|
MVMCoreNavigationHandler.shared()?.push(controller, animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case .view:
|
||||||
|
let symbols = CharacterSet(charactersIn: ".+()- ")
|
||||||
|
let contactPhoneNumber = model.phoneNumber.components(separatedBy: symbols).joined(separator: "")
|
||||||
|
let number = CNPhoneNumber(stringValue: contactPhoneNumber)
|
||||||
|
let contactPredicate = CNContact.predicateForContacts(matching: number)
|
||||||
|
let displayedKeys = [await CNContactViewController.descriptorForRequiredKeys()]
|
||||||
|
let store = CNContactStore()
|
||||||
|
let viewContact = try store.unifiedContacts(matching: contactPredicate, keysToFetch: displayedKeys).first
|
||||||
|
await continueInTask {
|
||||||
|
await MainActor.run {
|
||||||
|
let controller = CNContactViewController(forNewContact: viewContact)
|
||||||
|
controller.contactStore = store
|
||||||
|
controller.delegate = self
|
||||||
|
MVMCoreNavigationHandler.shared()?.push(controller, animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func contactViewController(_ viewController: CNContactViewController, didCompleteWith contact: CNContact?) {
|
||||||
|
MVMCoreNavigationHandler.shared()?.popTopViewController(animated: true, navigationController: nil, delegate: nil, completionHandler: {
|
||||||
|
self.continuation?.resume(returning: true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
public func contactViewController(_ viewController: CNContactViewController, shouldPerformDefaultActionFor property: CNContactProperty) -> Bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
public func contactPickerDidCancel(_ picker: CNContactPickerViewController) {
|
||||||
|
MVMCoreNavigationHandler.shared()?.dismissTopViewController(animated: true, delegate: nil, completionHandler: {
|
||||||
|
self.continuation?.resume(returning: true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
public func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) {
|
||||||
|
// This is a means to pass the data to this delegate function.
|
||||||
|
guard let phoneNumber = picker.view.accessibilityIdentifier else { return }
|
||||||
|
let store = CNContactStore()
|
||||||
|
let existingContact = contact.mutableCopy() as! CNMutableContact
|
||||||
|
let number = CNPhoneNumber(stringValue: phoneNumber)
|
||||||
|
let labelValue = CNLabeledValue(label: CNLabelOther, value: number)
|
||||||
|
var phoneNumbers = [labelValue]
|
||||||
|
phoneNumbers.append(contentsOf: existingContact.phoneNumbers)
|
||||||
|
existingContact.phoneNumbers = phoneNumbers
|
||||||
|
Task { @MainActor in
|
||||||
|
let controller = CNContactViewController(forNewContact: existingContact)
|
||||||
|
controller.contactStore = store
|
||||||
|
controller.delegate = self
|
||||||
|
MVMCoreNavigationHandler.shared()?.push(controller, animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,18 +9,24 @@
|
|||||||
import ContactsUI
|
import ContactsUI
|
||||||
|
|
||||||
|
|
||||||
@objcMembers public class ActionContactModel: ActionModelProtocol {
|
public struct ActionContactModel: ActionModelProtocol {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public enum Approach: String, Codable {
|
||||||
|
case add
|
||||||
|
case create
|
||||||
|
case view
|
||||||
|
}
|
||||||
|
|
||||||
public static var identifier: String = "contact"
|
public static var identifier: String = "contact"
|
||||||
public var actionType: String = ActionContactModel.identifier
|
public var actionType: String = ActionContactModel.identifier
|
||||||
|
|
||||||
public var phoneNumber: String
|
public var phoneNumber: String
|
||||||
public var firstName: String?
|
public var firstName: String?
|
||||||
public var lastName: String?
|
public var lastName: String?
|
||||||
public var approach: String = KeyCreate
|
public var approach: Approach = .create
|
||||||
public var extraParameters: JSONValueDictionary?
|
public var extraParameters: JSONValueDictionary?
|
||||||
public var analyticsData: JSONValueDictionary?
|
public var analyticsData: JSONValueDictionary?
|
||||||
|
|
||||||
@ -28,7 +34,7 @@ import ContactsUI
|
|||||||
// MARK: - Initializer
|
// MARK: - Initializer
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public init(phoneNumber: String, firstName: String? = nil, lastName: String? = nil, approach: String = KeyCreate, _ extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) {
|
public init(phoneNumber: String, firstName: String? = nil, lastName: String? = nil, approach: Approach = .create, _ extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) {
|
||||||
self.phoneNumber = phoneNumber
|
self.phoneNumber = phoneNumber
|
||||||
self.firstName = firstName
|
self.firstName = firstName
|
||||||
self.lastName = lastName
|
self.lastName = lastName
|
||||||
21
MVMCore/MVMCore/ActionHandling/ActionDelegateProtocol.swift
Normal file
21
MVMCore/MVMCore/ActionHandling/ActionDelegateProtocol.swift
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// MVMCoreActionDelegateProtocolExtension.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 1/22/21.
|
||||||
|
// Copyright © 2021 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol ActionDelegateProtocol: MVMCoreActionDelegateProtocol {
|
||||||
|
/// Asks the delegate to perform the action.
|
||||||
|
func performAction(with model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) async throws
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension ActionDelegateProtocol {
|
||||||
|
|
||||||
|
func performAction(with model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) async throws {
|
||||||
|
try await MVMCoreActionHandler.shared()?.handleAction(with: model, additionalData: additionalData, delegateObject: delegateObject)
|
||||||
|
}
|
||||||
|
}
|
||||||
15
MVMCore/MVMCore/ActionHandling/ActionNoopHandler.swift
Normal file
15
MVMCore/MVMCore/ActionHandling/ActionNoopHandler.swift
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// ActionNoopHandler.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 6/30/22.
|
||||||
|
// Copyright © 2022 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
open class ActionNoopHandler: MVMCoreActionHandlerProtocol {
|
||||||
|
required public init() {}
|
||||||
|
|
||||||
|
open func execute(with model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {}
|
||||||
|
}
|
||||||
@ -6,7 +6,7 @@
|
|||||||
// Copyright © 2020 myverizon. All rights reserved.
|
// Copyright © 2020 myverizon. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
@objcMembers public class ActionNoopModel: ActionModelProtocol {
|
public struct ActionNoopModel: ActionModelProtocol {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
90
MVMCore/MVMCore/ActionHandling/ActionOpenPageHandler.swift
Normal file
90
MVMCore/MVMCore/ActionHandling/ActionOpenPageHandler.swift
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
//
|
||||||
|
// OpenPageHandler.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 7/14/22.
|
||||||
|
// Copyright © 2022 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
open class ActionOpenPageHandler: MVMCoreJSONActionHandlerProtocol {
|
||||||
|
required public init() {}
|
||||||
|
|
||||||
|
open func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||||
|
guard let model = model as? ActionOpenPageModel else { return }
|
||||||
|
do {
|
||||||
|
if let closure = delegateObject?.actionDelegate?.handleOpenPage {
|
||||||
|
// Legacy code will use the old handler function and break the task chain here.
|
||||||
|
closure(model.requestParameters, JSON, additionalData)
|
||||||
|
} else if let operation = try await performRequestAddingClientParameters(with: model.requestParameters, model: model, delegateObject: delegateObject, additionalData: additionalData) {
|
||||||
|
await withCheckedContinuation { continuation in
|
||||||
|
operation.completionBlock = {
|
||||||
|
continuation.resume()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
try handle(error: error, model: model, delegateObject: delegateObject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open func execute(with model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||||
|
guard let model = model as? ActionOpenPageModel else { return }
|
||||||
|
do {
|
||||||
|
// Pass through the old function for legacy open page.
|
||||||
|
let json = try MVMCoreActionHandler.convertActionToJSON(model)
|
||||||
|
try await performAction(with: json, model: model, delegateObject: delegateObject, additionalData: additionalData)
|
||||||
|
} catch {
|
||||||
|
try handle(error: error, model: model, delegateObject: delegateObject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds client parameters and makes calls performRequest()
|
||||||
|
open func performRequestAddingClientParameters(with requestParameters: MVMCoreRequestParameters, model: ActionOpenPageModel, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws -> MVMCoreLoadRequestOperation? {
|
||||||
|
// Adds any client parameters to the request parameters.
|
||||||
|
if let parametersToFetch = model.clientParameters,
|
||||||
|
let fetchedParameters = try await ClientParameterHandler().getClientParameters(with: parametersToFetch, requestParameters: requestParameters.parameters as? [String : Any] ?? [:], showLoadingOverlay: !requestParameters.backgroundRequest) {
|
||||||
|
requestParameters.add(fetchedParameters)
|
||||||
|
}
|
||||||
|
try Task.checkCancellation()
|
||||||
|
return MVMCoreLoadHandler.sharedGlobal()?.loadRequest(requestParameters, dataForPage: additionalData, delegateObject: delegateObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ensures background requests do not have showing errors.
|
||||||
|
private func handle(error: Error, model: ActionOpenPageModel, delegateObject: DelegateObject?) throws {
|
||||||
|
switch error {
|
||||||
|
case MVMCoreError.errorObject(let errorObject):
|
||||||
|
errorObject.silentError = model.background == true
|
||||||
|
throw MVMCoreError.errorObject(errorObject)
|
||||||
|
default:
|
||||||
|
let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: model.actionType))!
|
||||||
|
errorObject.silentError = model.background == true
|
||||||
|
throw MVMCoreError.errorObject(errorObject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public extension ClientParameterHandler {
|
||||||
|
|
||||||
|
/// Iterates through the clientParameters list. Gets values from the individual handlers and attaches the parameters to extraParameters.
|
||||||
|
func getClientParameters(with model: ClientParameterModel, requestParameters: [String: Any], showLoadingOverlay: Bool) async throws -> [String: Any]? {
|
||||||
|
if showLoadingOverlay {
|
||||||
|
MVMCoreLoadingOverlayHandler.sharedLoadingOverlay()?.startLoading()
|
||||||
|
}
|
||||||
|
defer {
|
||||||
|
if showLoadingOverlay {
|
||||||
|
MVMCoreLoadingOverlayHandler.sharedLoadingOverlay()?.stopLoading(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return try await withCheckedThrowingContinuation({ continuation in
|
||||||
|
do {
|
||||||
|
try getParameters(with: model, requestParameters: requestParameters) { parameters in
|
||||||
|
continuation.resume(returning: parameters)
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
continuation.resume(throwing: error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
113
MVMCore/MVMCore/ActionHandling/ActionOpenPageModel.swift
Normal file
113
MVMCore/MVMCore/ActionHandling/ActionOpenPageModel.swift
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
//
|
||||||
|
// ActionModel.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Suresh, Kamlesh on 10/3/19.
|
||||||
|
// Copyright © 2019 Suresh, Kamlesh. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public struct ActionOpenPageModel: ActionModelProtocol, ActionOpenPageProtocol, ClientParameterActionProtocol {
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public static var identifier: String = "openPage"
|
||||||
|
public var actionType: String = identifier
|
||||||
|
public var pageType: String
|
||||||
|
public var modules: [String]?
|
||||||
|
public var baseURL: URL?
|
||||||
|
public var appContext: String?
|
||||||
|
public var requestURL: URL?
|
||||||
|
public var extraParameters: JSONValueDictionary?
|
||||||
|
public var analyticsData: JSONValueDictionary?
|
||||||
|
public var presentationStyle: String?
|
||||||
|
public var tabBarIndex: Int?
|
||||||
|
public var background: Bool?
|
||||||
|
public var clientParameters: ClientParameterModel?
|
||||||
|
public var customTimeoutTime: TimeInterval?
|
||||||
|
|
||||||
|
public var requestParameters: MVMCoreRequestParameters
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Initialzier
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public init(pageType: String, presentationStyle: String? = nil, extraParameters: JSONValueDictionary? = nil, analyticsData: JSONValueDictionary? = nil, tabBarIndex: Int? = nil, background: Bool? = nil) {
|
||||||
|
self.pageType = pageType
|
||||||
|
self.presentationStyle = presentationStyle
|
||||||
|
self.extraParameters = extraParameters
|
||||||
|
self.analyticsData = analyticsData
|
||||||
|
self.tabBarIndex = tabBarIndex
|
||||||
|
self.background = background
|
||||||
|
|
||||||
|
requestParameters = MVMCoreRequestParameters(pageType: pageType, extraParameters: extraParameters.toJSON())!
|
||||||
|
if let background = background {
|
||||||
|
requestParameters.backgroundRequest = background
|
||||||
|
}
|
||||||
|
requestParameters.actionMap = toJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Codable
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case actionType
|
||||||
|
case pageType
|
||||||
|
case modules
|
||||||
|
case baseURL
|
||||||
|
case appContext
|
||||||
|
case requestURL
|
||||||
|
case extraParameters
|
||||||
|
case analyticsData
|
||||||
|
case presentationStyle
|
||||||
|
case tabBarIndex
|
||||||
|
case background
|
||||||
|
case clientParameters
|
||||||
|
case customTimeoutTime
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
pageType = try typeContainer.decode(String.self, forKey: .pageType)
|
||||||
|
baseURL = try typeContainer.decodeIfPresent(URL.self, forKey: .baseURL)
|
||||||
|
appContext = try typeContainer.decodeIfPresent(String.self, forKey: .appContext)
|
||||||
|
requestURL = try typeContainer.decodeIfPresent(URL.self, forKey: .requestURL)
|
||||||
|
modules = try typeContainer.decodeIfPresent([String].self, forKey: .modules)
|
||||||
|
presentationStyle = try typeContainer.decodeIfPresent(String.self, forKey: .presentationStyle)
|
||||||
|
tabBarIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .tabBarIndex)
|
||||||
|
background = try typeContainer.decodeIfPresent(Bool.self, forKey: .background)
|
||||||
|
clientParameters = try typeContainer.decodeIfPresent(ClientParameterModel.self, forKey: .clientParameters)
|
||||||
|
customTimeoutTime = try typeContainer.decodeIfPresent(TimeInterval.self, forKey: .customTimeoutTime)
|
||||||
|
extraParameters = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .extraParameters)
|
||||||
|
analyticsData = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .analyticsData)
|
||||||
|
|
||||||
|
requestParameters = MVMCoreRequestParameters(pageType: pageType, additionalModules: modules ?? [], extraParameters: extraParameters.toJSON())!
|
||||||
|
requestParameters.contextRoot = appContext
|
||||||
|
requestParameters.alternateBaseURL = baseURL
|
||||||
|
requestParameters.url = requestURL
|
||||||
|
requestParameters.customTimeoutTime = customTimeoutTime as NSNumber?
|
||||||
|
if let background = background {
|
||||||
|
requestParameters.backgroundRequest = background
|
||||||
|
}
|
||||||
|
requestParameters.actionMap = toJSON()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encode(pageType, forKey: .pageType)
|
||||||
|
try container.encodeIfPresent(baseURL, forKey: .baseURL)
|
||||||
|
try container.encodeIfPresent(appContext, forKey: .appContext)
|
||||||
|
try container.encodeIfPresent(requestURL, forKey: .requestURL)
|
||||||
|
try container.encodeIfPresent(modules, forKey: .modules)
|
||||||
|
try container.encodeIfPresent(presentationStyle, forKey: .presentationStyle)
|
||||||
|
try container.encodeIfPresent(tabBarIndex, forKey: .tabBarIndex)
|
||||||
|
try container.encodeIfPresent(background, forKey: .background)
|
||||||
|
try container.encodeIfPresent(clientParameters, forKey: .clientParameters)
|
||||||
|
try container.encodeIfPresent(customTimeoutTime, forKey: .customTimeoutTime)
|
||||||
|
try container.encodeIfPresent(extraParameters, forKey: .extraParameters)
|
||||||
|
try container.encodeIfPresent(analyticsData, forKey: .analyticsData)
|
||||||
|
}
|
||||||
|
}
|
||||||
33
MVMCore/MVMCore/ActionHandling/ActionOpenSMSHandler.swift
Normal file
33
MVMCore/MVMCore/ActionHandling/ActionOpenSMSHandler.swift
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// ActionOpenSMSHandler.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 6/30/22.
|
||||||
|
// Copyright © 2022 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension String {
|
||||||
|
public enum StringError: Error {
|
||||||
|
case addingPercentEncoding(string: String)
|
||||||
|
}
|
||||||
|
|
||||||
|
func addingPercentEncodingThrowable(withAllowedCharacters characterSet: CharacterSet) throws -> String {
|
||||||
|
guard let string = addingPercentEncoding(withAllowedCharacters: characterSet) else {
|
||||||
|
throw StringError.addingPercentEncoding(string: self)
|
||||||
|
}
|
||||||
|
return string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class ActionOpenSMSHandler: MVMCoreActionHandlerProtocol {
|
||||||
|
required public init() {}
|
||||||
|
|
||||||
|
open func execute(with model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||||
|
guard let model = model as? ActionOpenSMSModel else { return }
|
||||||
|
// https://developer.apple.com/library/archive/featuredarticles/iPhoneURLScheme_Reference/SMSLinks/SMSLinks.html#:~:text=Note%3A%20SMS%20text%20links%20are,number%20of%20the%20SMS%20message.
|
||||||
|
let string = try "sms:\(model.phoneNumber)&body=\(model.message ?? "")".addingPercentEncodingThrowable(withAllowedCharacters: CharacterSet.urlQueryAllowed)
|
||||||
|
try await ActionOpenUrlHandler.openURL(with: string)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
@objcMembers public class ActionOpenSMSModel: ActionModelProtocol {
|
public struct ActionOpenSMSModel: ActionModelProtocol {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -8,43 +8,84 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
open class ActionOpenUrlHandler: MVMCoreActionHandlerProtocol {
|
public extension URL {
|
||||||
required public init() {}
|
enum URLError: MVMError, CustomStringConvertible {
|
||||||
|
case invalid(string: String)
|
||||||
open func handleAction(_ model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) {
|
|
||||||
guard let model = model as? ActionOpenUrlModel else { return }
|
public var description: String {
|
||||||
MVMCoreDispatchUtility.performBlock(onMainThread: { [self] in
|
switch self {
|
||||||
// Try loading the app url first, otherwise fall back to browser url.
|
case URLError.invalid(let string):
|
||||||
guard let appURL = model.appURL else {
|
return "Failed to create url with string: \(string)"
|
||||||
openURL(model: model, additionalData: additionalData, delegateObject: delegateObject)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
UIApplication.shared.open(appURL, options: model.appURLOptions?.options ?? [:]) { loaded in
|
|
||||||
guard !loaded else { return }
|
|
||||||
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Failed to open app url: \(appURL)")
|
|
||||||
openURL(model: model, additionalData: additionalData, delegateObject: delegateObject)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Opens the url.
|
|
||||||
open func openURL(model: ActionOpenUrlModel, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) {
|
|
||||||
UIApplication.shared.open(model.browserUrl, options: [:]) { [self] loaded in
|
|
||||||
guard !loaded else { return }
|
|
||||||
handleError(model: model, additionalData: additionalData, delegateObject: delegateObject)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles any url loading errors.
|
static func createURL(with string: String) throws -> URL {
|
||||||
open func handleError(model: ActionOpenUrlModel, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) {
|
guard let url = URL(string: string) else {
|
||||||
if let error = MVMCoreErrorObject(title: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorTitle),
|
throw URL.URLError.invalid(string: string)
|
||||||
message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess),
|
|
||||||
messageToLog: "Unable to load URL: \(String(describing: model.browserUrl))", code: ErrorCode.linkawayFailed.rawValue,
|
|
||||||
domain: ErrorDomainNative,
|
|
||||||
location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: ActionOpenUrlModel.identifier)) {
|
|
||||||
MVMCoreDispatchUtility.performBlock(inBackground: {
|
|
||||||
MVMCoreActionHandler.shared()?.handleActionError(error, actionInformation: model.toJSON(), additionalData: additionalData, delegateObject: delegateObject)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class ActionOpenUrlHandler: MVMCoreJSONActionHandlerProtocol {
|
||||||
|
required public init() {}
|
||||||
|
|
||||||
|
public enum URLError: MVMError, CustomStringConvertible {
|
||||||
|
case failedToOpen(url: URL)
|
||||||
|
|
||||||
|
public var description: String {
|
||||||
|
switch self {
|
||||||
|
case ActionOpenUrlHandler.URLError.failedToOpen(let url):
|
||||||
|
return "Failed to open url: \(url.absoluteString)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a url and calls open(url: URL)
|
||||||
|
public static func openURL(with string: String) async throws {
|
||||||
|
let url = try URL.createURL(with: string)
|
||||||
|
try await ActionOpenUrlHandler.open(url: url)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Opens the url using UIApplication open(url:). Throws URLError.failedToOpen if it fails.
|
||||||
|
@MainActor
|
||||||
|
public static func open(url: URL) async throws {
|
||||||
|
try await withCheckedThrowingContinuation { continuation in
|
||||||
|
UIApplication.shared.open(url, options: [:]) { successful in
|
||||||
|
if successful {
|
||||||
|
continuation.resume()
|
||||||
|
} else {
|
||||||
|
continuation.resume(throwing: ActionOpenUrlHandler.URLError.failedToOpen(url: url))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} as Void
|
||||||
|
}
|
||||||
|
|
||||||
|
open func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||||
|
try await execute(with: model, delegateObject: delegateObject, additionalData: additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
open func execute(with model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||||
|
guard let model = model as? ActionOpenUrlModel else { return }
|
||||||
|
|
||||||
|
// Try loading the app url first, otherwise fall back to browser url.
|
||||||
|
if let appURL = model.appURL {
|
||||||
|
do {
|
||||||
|
try await ActionOpenUrlHandler.open(url: appURL)
|
||||||
|
return
|
||||||
|
} catch {
|
||||||
|
// Log error and continue
|
||||||
|
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Failed to open app url: \(appURL)")
|
||||||
|
if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: model.actionType)) {
|
||||||
|
MVMCoreLoggingHandler.addError(toLog: errorObject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try await openURL(model: model, additionalData: additionalData, delegateObject: delegateObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
open func openURL(model: ActionOpenUrlModel, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) async throws {
|
||||||
|
try await ActionOpenUrlHandler.open(url: model.browserUrl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,18 +8,18 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers open class ActionOpenUrlModel: ActionModelProtocol {
|
open class ActionOpenUrlModel: ActionModelProtocol {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public static var identifier: String = "openURL"
|
open class var identifier: String { "openURL" }
|
||||||
public var actionType: String = ActionOpenUrlModel.identifier
|
open var actionType: String = ActionOpenUrlModel.identifier
|
||||||
public var browserUrl: URL
|
open var browserUrl: URL
|
||||||
public var appURL: URL?
|
open var appURL: URL?
|
||||||
public var appURLOptions: OpenUrlOptionsModel?
|
open var appURLOptions: OpenUrlOptionsModel?
|
||||||
public var extraParameters: JSONValueDictionary?
|
open var extraParameters: JSONValueDictionary?
|
||||||
public var analyticsData: JSONValueDictionary?
|
open var analyticsData: JSONValueDictionary?
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initialzier
|
// MARK: - Initialzier
|
||||||
|
|||||||
@ -0,0 +1,47 @@
|
|||||||
|
//
|
||||||
|
// ActionPreviousSubmitHandler.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 6/30/22.
|
||||||
|
// Copyright © 2022 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// Makes the previous request, needs the delegate for this
|
||||||
|
open class ActionPreviousSubmitHandler: MVMCoreJSONActionHandlerProtocol {
|
||||||
|
required public init() {}
|
||||||
|
|
||||||
|
private var json: [AnyHashable: Any]?
|
||||||
|
|
||||||
|
// Conform to MVMCoreJSONActionHandlerProtocol To allow for legacy handleOpenPage delegate
|
||||||
|
open func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||||
|
json = JSON
|
||||||
|
try await execute(with: model, delegateObject: delegateObject, additionalData: additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
open func execute(with model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||||
|
guard let loadObject = (delegateObject?.actionDelegate as? MVMCoreViewControllerProtocol)?.loadObject,
|
||||||
|
let previousRequest = loadObject?.requestParameters else { return }
|
||||||
|
|
||||||
|
// Combines data
|
||||||
|
var data = loadObject?.dataForPage
|
||||||
|
if let previousData = data,
|
||||||
|
let additionalData = additionalData {
|
||||||
|
data = previousData.merging(additionalData) {(new,_) in new}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let _ = delegateObject?.actionDelegate?.handleOpenPage {
|
||||||
|
// Legacy handling. Will lose the task.
|
||||||
|
let json = try json ?? MVMCoreActionHandler.convertActionToJSON(model)
|
||||||
|
delegateObject?.actionDelegate?.handleOpenPage?(for: previousRequest, actionInformation: json, additionalData: additionalData)
|
||||||
|
} else {
|
||||||
|
guard let operation = MVMCoreLoadHandler.sharedGlobal()?.loadRequest(previousRequest, dataForPage: additionalData, delegateObject: delegateObject) else { return }
|
||||||
|
await withCheckedContinuation { continuation in
|
||||||
|
operation.completionBlock = {
|
||||||
|
continuation.resume()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
@objcMembers public class ActionPreviousSubmitModel: ActionModelProtocol {
|
public struct ActionPreviousSubmitModel: ActionModelProtocol {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
35
MVMCore/MVMCore/ActionHandling/ActionRestartHandler.swift
Normal file
35
MVMCore/MVMCore/ActionHandling/ActionRestartHandler.swift
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
//
|
||||||
|
// ActionRestartHandler.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 6/30/22.
|
||||||
|
// Copyright © 2022 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
open class ActionRestartHandler: MVMCoreActionHandlerProtocol {
|
||||||
|
required public init() {}
|
||||||
|
|
||||||
|
open func execute(with model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||||
|
guard let model = model as? ActionRestartModel else { return }
|
||||||
|
|
||||||
|
let _: Void = try await withCheckedThrowingContinuation { continuation in
|
||||||
|
|
||||||
|
// Invalidates the session before restarting.
|
||||||
|
MVMCoreSessionTimeHandler.sharedSession()?.invalidateSession({ error in
|
||||||
|
if let error = error {
|
||||||
|
guard error.code != NSURLErrorCancelled else {
|
||||||
|
continuation.resume()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
continuation.resume(throwing: MVMCoreError.errorObject(error))
|
||||||
|
} else {
|
||||||
|
// Restarts the app (forcing any passed in page types).
|
||||||
|
MVMCoreSessionObject.sharedGlobal()?.restartSession(withPageType: model.pageType, parameters: model.extraParameters.toJSON(), clearAllVariables: true)
|
||||||
|
continuation.resume()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
@objcMembers public class ActionRestartModel: ActionModelProtocol {
|
public struct ActionRestartModel: ActionModelProtocol {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
17
MVMCore/MVMCore/ActionHandling/ActionSettingHandler.swift
Normal file
17
MVMCore/MVMCore/ActionHandling/ActionSettingHandler.swift
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// ActionSettingHandler.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 6/30/22.
|
||||||
|
// Copyright © 2022 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
open class ActionSettingHandler: MVMCoreActionHandlerProtocol {
|
||||||
|
required public init() {}
|
||||||
|
|
||||||
|
open func execute(with model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||||
|
try await ActionOpenUrlHandler.openURL(with: await UIApplication.openSettingsURLString)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,7 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
@objcMembers public class ActionSettingModel: ActionModelProtocol {
|
public struct ActionSettingModel: ActionModelProtocol {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
55
MVMCore/MVMCore/ActionHandling/ActionShareHandler.swift
Normal file
55
MVMCore/MVMCore/ActionHandling/ActionShareHandler.swift
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
//
|
||||||
|
// ActionShareHandler.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 7/14/22.
|
||||||
|
// Copyright © 2022 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
open class ActionShareHandler: MVMCoreActionHandlerProtocol {
|
||||||
|
|
||||||
|
required public init() {}
|
||||||
|
|
||||||
|
open func execute(with model: ActionModelProtocol, delegateObject: DelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) async throws {
|
||||||
|
guard let model = model as? ActionShareModel else { return }
|
||||||
|
var shareData: [Any]
|
||||||
|
switch model.sharedType {
|
||||||
|
case .text:
|
||||||
|
shareData = [model.sharedText]
|
||||||
|
case .url:
|
||||||
|
let url = try URL.createURL(with: model.sharedText)
|
||||||
|
shareData = [model.sharedText, url]
|
||||||
|
}
|
||||||
|
try await shareWith(activityItems: shareData, model: model)
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
open func shareWith(activityItems: [Any], model: ActionShareModel, delegateObject: DelegateObject? = nil) async throws {
|
||||||
|
try await withCheckedThrowingContinuation { continuation in
|
||||||
|
let controller = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
|
||||||
|
controller.popoverPresentationController?.sourceView = MVMCoreNavigationHandler.shared()?.viewControllerToPresentOn?.view
|
||||||
|
controller.completionWithItemsHandler = {(activityType: UIActivity.ActivityType?, completed: Bool, returnedItems: [Any]?, error: Error?) in
|
||||||
|
if completed {
|
||||||
|
// Activity was completed, considered finished.
|
||||||
|
if activityType == .copyToPasteboard {
|
||||||
|
// Allow copy
|
||||||
|
MVMCoreSessionObject.sharedGlobal()?.copyString(toClipboard: model.sharedText)
|
||||||
|
}
|
||||||
|
continuation.resume()
|
||||||
|
} else if let _ = activityType {
|
||||||
|
// If a specific type of activity failed, the activity controller is still presented, cannot continue yet.
|
||||||
|
if let error = error,
|
||||||
|
let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: model.actionType)) {
|
||||||
|
MVMCoreLoggingHandler.addError(toLog: errorObject)
|
||||||
|
}
|
||||||
|
} else if let error = error {
|
||||||
|
continuation.resume(throwing: error)
|
||||||
|
} else {
|
||||||
|
continuation.resume()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MVMCoreNavigationHandler.shared()?.present(controller, animated: true)
|
||||||
|
} as Void
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,7 +7,13 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
@objcMembers public class ActionShareModel: ActionModelProtocol {
|
public struct ActionShareModel: ActionModelProtocol {
|
||||||
|
|
||||||
|
public enum SharedType: String, Codable {
|
||||||
|
case text
|
||||||
|
case url
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -15,7 +21,7 @@
|
|||||||
public static var identifier: String = "share"
|
public static var identifier: String = "share"
|
||||||
|
|
||||||
public var actionType: String = ActionShareModel.identifier
|
public var actionType: String = ActionShareModel.identifier
|
||||||
public var sharedType: String
|
public var sharedType: SharedType
|
||||||
public var sharedText: String
|
public var sharedText: String
|
||||||
public var extraParameters: JSONValueDictionary?
|
public var extraParameters: JSONValueDictionary?
|
||||||
public var analyticsData: JSONValueDictionary?
|
public var analyticsData: JSONValueDictionary?
|
||||||
@ -24,7 +30,7 @@
|
|||||||
// MARK: - Initializer
|
// MARK: - Initializer
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public init(sharedText: String, sharedType: String, _ extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) {
|
public init(sharedText: String, sharedType: SharedType, _ extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) {
|
||||||
self.sharedType = sharedType
|
self.sharedType = sharedType
|
||||||
self.sharedText = sharedText
|
self.sharedText = sharedText
|
||||||
self.extraParameters = extraParameters
|
self.extraParameters = extraParameters
|
||||||
@ -1,16 +0,0 @@
|
|||||||
//
|
|
||||||
// MVMCoreActionDelegateProtocolExtension.swift
|
|
||||||
// MVMCore
|
|
||||||
//
|
|
||||||
// Created by Scott Pfeil on 1/22/21.
|
|
||||||
// Copyright © 2021 myverizon. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
public extension MVMCoreActionDelegateProtocol {
|
|
||||||
/// Handles any action errors.
|
|
||||||
func handleAction(error: MVMCoreErrorObject, action: ActionModelProtocol, additionalData: [AnyHashable: Any]?) {
|
|
||||||
MVMCoreActionHandler.shared()?.defaultHandleActionError(error, additionalData: additionalData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -24,9 +24,6 @@
|
|||||||
// Handles the back actions. Can overwrite for special loading.
|
// Handles the back actions. Can overwrite for special loading.
|
||||||
- (void)handleBackAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData;
|
- (void)handleBackAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData;
|
||||||
|
|
||||||
// Prepares to call the previous submit request again. Can overwrite for special loading. Be sure to call submit() block to perform the actual load.
|
|
||||||
- (void)prepareRequestForPreviousSubmission:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData submit:(nonnull void (^)(MVMCoreRequestParameters * _Nonnull requestParameters, NSDictionary * _Nullable dataForPage))submit;
|
|
||||||
|
|
||||||
// Handles the linkaway action. Call the block to continue to linkaway.
|
// Handles the linkaway action. Call the block to continue to linkaway.
|
||||||
- (void)shouldLinkAwayWithURL:(nullable NSURL *)URL appURL:(nullable NSURL *)appURL actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData linkAwayBlock:(nonnull void (^)(NSURL * _Nullable appURL, NSURL * _Nullable URL, NSDictionary * _Nullable actionInformation, NSDictionary * _Nullable additionalData))linkAwayBlock;
|
- (void)shouldLinkAwayWithURL:(nullable NSURL *)URL appURL:(nullable NSURL *)appURL actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData linkAwayBlock:(nonnull void (^)(NSURL * _Nullable appURL, NSURL * _Nullable URL, NSDictionary * _Nullable actionInformation, NSDictionary * _Nullable additionalData))linkAwayBlock;
|
||||||
|
|
||||||
@ -36,9 +33,6 @@
|
|||||||
// Handles any unknown action types. Can overwrite for more specific handling.
|
// Handles any unknown action types. Can overwrite for more specific handling.
|
||||||
- (void)handleUnknownActionType:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData;
|
- (void)handleUnknownActionType:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData;
|
||||||
|
|
||||||
// Handles any action errors. Can overwrite for more specific handling.
|
|
||||||
- (void)handleActionError:(nonnull MVMCoreErrorObject *)error additionalData:(nullable NSDictionary *)additionalData;
|
|
||||||
|
|
||||||
// Lets the delegate know that another internal module app is about to be launched
|
// Lets the delegate know that another internal module app is about to be launched
|
||||||
- (void)prepareForOpenOtherAppModule:(nullable NSString *)module;
|
- (void)prepareForOpenOtherAppModule:(nullable NSString *)module;
|
||||||
|
|
||||||
|
|||||||
@ -1,84 +0,0 @@
|
|||||||
//
|
|
||||||
// MVMCoreActionHandler+Extension.swift
|
|
||||||
// MVMCore
|
|
||||||
//
|
|
||||||
// Created by Scott Pfeil on 1/22/21.
|
|
||||||
// Copyright © 2021 myverizon. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
public protocol MVMCoreActionHandlerProtocol: ModelHandlerProtocol {
|
|
||||||
init()
|
|
||||||
func handleAction(_ model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?)
|
|
||||||
}
|
|
||||||
|
|
||||||
public extension MVMCoreActionHandler {
|
|
||||||
|
|
||||||
/// Converts the action to json for old action handler to handle.
|
|
||||||
func convertActionToJSON(_ model: ActionModelProtocol, delegateObject: DelegateObject?) -> [AnyHashable: Any]? {
|
|
||||||
do {
|
|
||||||
let data = try model.encode()
|
|
||||||
guard let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [AnyHashable: Any] else {
|
|
||||||
throw ModelRegistry.Error.decoderError
|
|
||||||
}
|
|
||||||
return json
|
|
||||||
} catch {
|
|
||||||
if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: "") {
|
|
||||||
delegateObject?.actionDelegate?.handleAction(error: errorObject, action: model, additionalData: model.extraParameters) ?? MVMCoreActionHandler.shared()?.defaultHandleActionError(errorObject, additionalData: model.extraParameters)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc func hasActionHandler(actionType: String?, actionInformation: [String: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) -> Bool {
|
|
||||||
|
|
||||||
guard //ensure there is a actinType
|
|
||||||
let actionType = actionType,
|
|
||||||
//ensure there is a serialized version of the Action
|
|
||||||
let actionInformation = actionInformation,
|
|
||||||
//esnure the actionModelType
|
|
||||||
let actionModelType = ModelRegistry.getType(for: actionType, with: ActionModelProtocol.self),
|
|
||||||
//ensure there is handlerType for the action of MVMCoreActionHandlerProtocol
|
|
||||||
let actionHandlerType = try? ModelRegistry.getHandlerType(for: actionModelType) as? MVMCoreActionHandlerProtocol.Type
|
|
||||||
else { return false }
|
|
||||||
|
|
||||||
do {
|
|
||||||
//ensure the decoded actionModel is of ActionModelProtocol
|
|
||||||
guard let actionModel = try actionModelType.decode(jsonDict: actionInformation) as? ActionModelProtocol else {
|
|
||||||
throw ModelRegistry.Error.decoderOther(message: "Could not decode to ActionModelProtocol")
|
|
||||||
}
|
|
||||||
|
|
||||||
//create the handler since we know it can initialize
|
|
||||||
let actionHandler = actionHandlerType.init()
|
|
||||||
|
|
||||||
//call the handleAction of the handler
|
|
||||||
actionHandler.handleAction(actionModel, additionalData: additionalData, delegateObject: delegateObject)
|
|
||||||
|
|
||||||
} catch {
|
|
||||||
//log the error
|
|
||||||
if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: "") {
|
|
||||||
MVMCoreActionHandler.shared()?.defaultHandleActionError(errorObject, additionalData: additionalData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//found the handler, returning true no matter if there was a failure in the do...catch
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Start action on current thread.
|
|
||||||
func syncHandleAction(with model: ActionModelProtocol, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
|
|
||||||
guard let json = convertActionToJSON(model, delegateObject: delegateObject) else { return }
|
|
||||||
synchronouslyHandleAction(model.actionType, actionInformation: json, additionalData: additionalData, delegateObject: delegateObject)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Start action on dispatched background thread.
|
|
||||||
func asyncHandleAction(with model: ActionModelProtocol, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
|
|
||||||
guard let json = convertActionToJSON(model, delegateObject: delegateObject) else { return }
|
|
||||||
handleAction(model.actionType, actionInformation: json, additionalData: additionalData, delegateObject: delegateObject)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc static func getErrorLocation(with delegate: MVMCoreActionDelegateProtocol?, actionType: String) -> String {
|
|
||||||
return "\(String(describing: delegate))_\(actionType)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,97 +0,0 @@
|
|||||||
//
|
|
||||||
// MVMCoreActionHandler.h
|
|
||||||
// myverizon
|
|
||||||
//
|
|
||||||
// Created by Scott Pfeil on 11/20/15.
|
|
||||||
// Copyright © 2015 Verizon Wireless. All rights reserved.
|
|
||||||
//
|
|
||||||
// Can be subclassed to handle app specific actions as well.
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import <MVMCore/MVMCoreActionDelegateProtocol.h>
|
|
||||||
#import <MVMCore/MVMCoreLoadDelegateProtocol.h>
|
|
||||||
#import <MVMCore/MVMCorePresentationDelegateProtocol.h>
|
|
||||||
@class DelegateObject;
|
|
||||||
|
|
||||||
extern NSString * _Nonnull const KeyActionType;
|
|
||||||
extern NSString * _Nonnull const KeyActionTypeLinkAway;
|
|
||||||
extern NSString * _Nonnull const KeyActionTypeOpen;
|
|
||||||
|
|
||||||
@interface MVMCoreActionHandler : NSObject
|
|
||||||
|
|
||||||
/// Returns the shared action handler
|
|
||||||
+ (nullable instancetype)sharedActionHandler;
|
|
||||||
|
|
||||||
/// Convenience function for handling actions. This will pull action and pageInfo out of the dictionary and call handleAction: actionInformation: with those values
|
|
||||||
- (void)handleActionWithDictionary:(nullable NSDictionary *)dictionary additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// Asynchronously handles action (dispatches and calls below function). Used by server driven user actions..
|
|
||||||
- (void)handleAction:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// Synchronously handles action. Used by server driven user actions..
|
|
||||||
- (void)synchronouslyHandleAction:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// Iterates through the clientParameters list. Gets values from the individual handlers and attaches the parameters to extraParameters.
|
|
||||||
- (void)getClientParameter:(nullable NSDictionary *)clientParametersMap requestParameters:(nullable NSDictionary *)requestParameters showLoadingOverlay:(BOOL)showLoadingOverlay completionHandler:(nonnull void (^)(NSDictionary * _Nullable jsonDictionary))completionHandler;
|
|
||||||
|
|
||||||
#pragma mark - Actions
|
|
||||||
/// by default, returns the original RequestParameter that passed in. Can be overriden for some generic updates to the RequestParameter before handle open page action gets called.
|
|
||||||
- (void)updateRequestParametersBeforeHandleOpenPageAction:(nonnull MVMCoreRequestParameters *)requestParameters callBack:(void (^_Nonnull)(MVMCoreRequestParameters * _Nonnull requestParameters))callback;
|
|
||||||
|
|
||||||
/// Logs the action. Currently is not action information driven... depends on delegate.
|
|
||||||
- (void)logAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// Tries to open a page
|
|
||||||
- (void)openPageAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// restarts the app
|
|
||||||
- (void)restartAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// Goes back
|
|
||||||
- (void)backAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// Opens Text Message
|
|
||||||
- (void)smsAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// Makes a phone call
|
|
||||||
- (void)callAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// Makes the previous request, needs the delegate for this
|
|
||||||
- (void)previousSubmitAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// Redirects to another experience
|
|
||||||
- (void)redirectAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// Cancels (like in a popup)
|
|
||||||
- (void)cancelAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// Goes to settings app
|
|
||||||
- (void)settingsAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// Performs multiple actions
|
|
||||||
- (void)actions:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// Subclass this to handle other custom actions. Return YES if handled, and NO if not.
|
|
||||||
- (BOOL)handleOtherActions:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// Last chance to handle unknown actions before throwing an error
|
|
||||||
- (void)unknownAction:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// Handles action errors.
|
|
||||||
- (void)handleActionError:(nullable MVMCoreErrorObject *)error actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
#pragma mark - Default Action Protocol Functions
|
|
||||||
|
|
||||||
/// Currently no default log action but this will eventually be server driven.
|
|
||||||
+ (void)defaultLogAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// Sends the request to the load handler.
|
|
||||||
+ (void)defaultHandleOpenPageForRequestParameters:(nonnull MVMCoreRequestParameters *)requestParameters actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// By default, throws an error, calling defaultHandleActionError.
|
|
||||||
+ (void)defaultHandleUnknownActionType:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// Logs the error.
|
|
||||||
- (void)defaultHandleActionError:(nonnull MVMCoreErrorObject *)error additionalData:(nullable NSDictionary *)additionalData;
|
|
||||||
|
|
||||||
@end
|
|
||||||
@ -1,486 +0,0 @@
|
|||||||
//
|
|
||||||
// MVMCoreActionHandler.m
|
|
||||||
// myverizon
|
|
||||||
//
|
|
||||||
// Created by Scott Pfeil on 11/20/15.
|
|
||||||
// Copyright © 2015 Verizon Wireless. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#import <MVMCore/MVMCoreActionHandler.h>
|
|
||||||
#import "MVMCoreLoggingHandler.h"
|
|
||||||
#import "MVMCoreCache.h"
|
|
||||||
#import "MVMCoreSessionTimeHandler.h"
|
|
||||||
#import "MVMCoreLoadHandler.h"
|
|
||||||
#import "MVMCoreNavigationHandler.h"
|
|
||||||
#import "MVMCoreDispatchUtility.h"
|
|
||||||
#import "NSDictionary+MFConvenience.h"
|
|
||||||
#import "MVMCoreGetterUtility.h"
|
|
||||||
#import "MVMCoreRequestParameters.h"
|
|
||||||
#import "MVMCoreErrorObject.h"
|
|
||||||
#import "MVMCoreJSONConstants.h"
|
|
||||||
#import "MVMCoreHardcodedStringsConstants.h"
|
|
||||||
#import "MVMCoreErrorConstants.h"
|
|
||||||
#import "MVMCoreActionUtility.h"
|
|
||||||
#import "MVMCoreSessionObject.h"
|
|
||||||
#import "MVMCoreObject.h"
|
|
||||||
#import "MVMCorePresentationDelegateProtocol.h"
|
|
||||||
#import <SafariServices/SafariServices.h>
|
|
||||||
#import <MVMCore/MVMCore-Swift.h>
|
|
||||||
#import "MVMCoreLoadingOverlayHandler.h"
|
|
||||||
#import <ContactsUI/ContactsUI.h>
|
|
||||||
|
|
||||||
NSString * const KeyActionType = @"actionType";
|
|
||||||
NSString * const KeyActionTypeLinkAway = @"openURL";
|
|
||||||
NSString * const KeyActionTypeOpen = @"openPage";
|
|
||||||
|
|
||||||
@interface MVMCoreActionHandler() <CNContactViewControllerDelegate, CNContactPickerDelegate>
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation MVMCoreActionHandler
|
|
||||||
+ (nullable instancetype)sharedActionHandler {
|
|
||||||
return [MVMCoreActionUtility initializerClassCheck:[MVMCoreObject sharedInstance].actionHandler classToVerify:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)handleActionWithDictionary:(nullable NSDictionary *)dictionary additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
|
|
||||||
NSString *action = [dictionary stringForKey:KeyActionType];
|
|
||||||
[self handleAction:action actionInformation:dictionary additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)handleAction:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
||||||
[self synchronouslyHandleAction:actionType actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)synchronouslyHandleAction:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
// Logs the action.
|
|
||||||
[self logAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
|
|
||||||
if ([actionType isEqualToString:KeyActionTypeOpen]) {
|
|
||||||
[self openPageAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
|
|
||||||
} else if ([actionType isEqualToString:KeyActionTypeRestart]) {
|
|
||||||
[self restartAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
|
|
||||||
} else if ([actionType isEqualToString:KeyActionTypeBack]) {
|
|
||||||
[self backAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
|
|
||||||
} else if ([actionType isEqualToString:KeyActionTypeCall]) {
|
|
||||||
[self callAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
|
|
||||||
} else if ([actionType isEqualToString:KeyActionTypeSMS]) {
|
|
||||||
[self smsAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
|
|
||||||
} else if ([actionType isEqualToString:KeyActionTypeContact]) {
|
|
||||||
[self contactAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
|
|
||||||
} else if ([actionType isEqualToString:KeyActionTypeShare]) {
|
|
||||||
[self shareAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
|
|
||||||
} else if ([actionType isEqualToString:KeyActionTypePreviousSubmit]) {
|
|
||||||
[self previousSubmitAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
|
|
||||||
} else if ([actionType isEqualToString:KeyActionTypeRedirect]) {
|
|
||||||
[self redirectAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
|
|
||||||
} else if ([actionType isEqualToString:KeyActionTypeCancel]) {
|
|
||||||
[self cancelAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
|
|
||||||
} else if ([actionType isEqualToString:KeyActionTypeSettings]) {
|
|
||||||
[self settingsAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
|
|
||||||
} else if ([actionType isEqualToString:KeyActionTypeNoop]) {
|
|
||||||
} else if ([actionType isEqualToString:KeyActionTypeActions]) {
|
|
||||||
[self actions:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
} else if (![self handleOtherActions:actionType actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject]) {
|
|
||||||
// not a known action type.
|
|
||||||
[self unknownAction:actionType actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)getClientParameter:(nullable NSDictionary *)clientParametersMap requestParameters:(nullable NSDictionary *)requestParameters showLoadingOverlay:(BOOL)showLoadingOverlay completionHandler:(nonnull void (^)(NSDictionary * _Nullable parameters))completionHandler {
|
|
||||||
|
|
||||||
if (!clientParametersMap) {
|
|
||||||
completionHandler(nil);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (showLoadingOverlay) {
|
|
||||||
[[MVMCoreLoadingOverlayHandler sharedLoadingOverlay] startLoading];
|
|
||||||
}
|
|
||||||
|
|
||||||
void (^stopLoadingOverlay)(void) = ^(void) {
|
|
||||||
if (showLoadingOverlay) {
|
|
||||||
[[MVMCoreLoadingOverlayHandler sharedLoadingOverlay] stopLoading:true];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
NSError *error = nil;
|
|
||||||
[MVMCoreLoggingHandler logDebugMessageWithDelegate:@"Fetching client parameters"];
|
|
||||||
|
|
||||||
ClientParameterHandler *clientParameterHandler = [[ClientParameterHandler alloc] init];
|
|
||||||
[clientParameterHandler getParametersWith:clientParametersMap
|
|
||||||
requestParameters:requestParameters
|
|
||||||
error:&error
|
|
||||||
completionHandler:^(NSDictionary<NSString *,id> * _Nullable clientParameters) {
|
|
||||||
[MVMCoreLoggingHandler logDebugMessageWithDelegate:@"Finshed fetching client parameters"];
|
|
||||||
if (clientParameters) {
|
|
||||||
stopLoadingOverlay();
|
|
||||||
completionHandler(clientParameters);
|
|
||||||
} else {
|
|
||||||
[MVMCoreLoggingHandler logDebugMessageWithDelegate:@"No client parameters"];
|
|
||||||
stopLoadingOverlay();
|
|
||||||
completionHandler(nil);
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
stopLoadingOverlay();
|
|
||||||
completionHandler(nil);
|
|
||||||
[MVMCoreLoggingHandler addErrorToLog:[MVMCoreErrorObject createErrorObjectForNSError:error location:@"MVMCoreActionHandler->setClientParameter"]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Actions
|
|
||||||
|
|
||||||
- (void)updateRequestParametersBeforeHandleOpenPageAction:(nonnull MVMCoreRequestParameters *)requestParameters callBack:(void (^_Nonnull)(MVMCoreRequestParameters * _Nonnull requestParameters))callback {
|
|
||||||
//does not do anything by default, can be override
|
|
||||||
callback(requestParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)logAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
if ([delegateObject.actionDelegate respondsToSelector:@selector(logActionWithActionInformation:additionalData:)]) {
|
|
||||||
[delegateObject.actionDelegate logActionWithActionInformation:actionInformation additionalData:additionalData];
|
|
||||||
} else {
|
|
||||||
[[self class] defaultLogAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)openPageAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
|
|
||||||
// Loads the given page type.
|
|
||||||
NSString *pageType = [actionInformation stringForKey:KeyPageType];
|
|
||||||
|
|
||||||
if (pageType.length == 0) {
|
|
||||||
// No page type to load, show error.
|
|
||||||
MVMCoreErrorObject *error = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorUnableToProcess] code:ErrorCodeNoPageType domain:ErrorDomainNative location:[NSString stringWithFormat:@"%@_%@",NSStringFromClass([delegateObject.actionDelegate class]),KeyActionTypeOpen]];
|
|
||||||
[self handleActionError:error actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MVMCoreRequestParameters *requestParameters = [[MVMCoreRequestParameters alloc] initWithActionMap:actionInformation];
|
|
||||||
[self updateRequestParametersBeforeHandleOpenPageAction:requestParameters callBack:^(MVMCoreRequestParameters * _Nonnull requestParameters) {
|
|
||||||
if ([delegateObject.actionDelegate respondsToSelector:@selector(handleOpenPageForRequestParameters:actionInformation:additionalData:)]) {
|
|
||||||
[delegateObject.actionDelegate handleOpenPageForRequestParameters:requestParameters actionInformation:actionInformation additionalData:additionalData];
|
|
||||||
} else {
|
|
||||||
[MVMCoreActionHandler defaultHandleOpenPageForRequestParameters:requestParameters
|
|
||||||
actionInformation:actionInformation
|
|
||||||
additionalData:additionalData
|
|
||||||
delegateObject:delegateObject];
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)shareAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
|
|
||||||
NSString *shareType = [actionInformation string:KeyShareType];
|
|
||||||
NSString *shareText = [actionInformation string:KeyShareText];
|
|
||||||
|
|
||||||
if (!shareText || !shareType) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSArray *shareData = nil;
|
|
||||||
|
|
||||||
if ([shareType isEqualToString:@"text"]) {
|
|
||||||
shareData = @[shareText];
|
|
||||||
|
|
||||||
} else if ([shareType isEqualToString:@"url"]) {
|
|
||||||
NSURL *url = [NSURL URLWithString:shareText];
|
|
||||||
if (url) {
|
|
||||||
shareData = @[shareText, url];
|
|
||||||
} else {
|
|
||||||
shareData = @[shareText];
|
|
||||||
}
|
|
||||||
} else if ([shareType isEqualToString:@"image"]) {
|
|
||||||
// TODO: Implement image parsing. 🏂
|
|
||||||
|
|
||||||
} else if ([shareType isEqualToString:@"file"]) {
|
|
||||||
// TODO: Implement file parsing. 🌋
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shareData.count > 0) {
|
|
||||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
|
||||||
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:shareData applicationActivities:nil];
|
|
||||||
|
|
||||||
void(^activityCompletion)(UIActivityType, BOOL, NSArray*, NSError*) = ^(UIActivityType activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
|
|
||||||
if (activityType == UIActivityTypeCopyToPasteboard) {
|
|
||||||
[[MVMCoreSessionObject sharedGlobal] copyStringToClipboard:shareText];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
activityViewController.completionWithItemsHandler = activityCompletion;
|
|
||||||
activityViewController.popoverPresentationController.sourceView = [MVMCoreNavigationHandler sharedNavigationHandler].viewControllerToPresentOn.view;
|
|
||||||
[[MVMCoreNavigationHandler sharedNavigationHandler] presentViewController:activityViewController animated:YES];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)restartAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
|
|
||||||
// Invalidates the session before restarting.
|
|
||||||
[[MVMCoreSessionTimeHandler sharedSessionHandler] invalidateSession:^(MVMCoreErrorObject * _Nullable error) {
|
|
||||||
|
|
||||||
// Restarts the app (forcing any passed in page types).
|
|
||||||
if (error.code != NSURLErrorCancelled) {
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
|
|
||||||
// Error invalidating.
|
|
||||||
[self handleActionError:error actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// Restart the application with the page type.
|
|
||||||
NSString *pageType = [actionInformation string:KeyPageType];
|
|
||||||
NSDictionary *parameters = [actionInformation dict:KeyExtraParameters];
|
|
||||||
[[MVMCoreSessionObject sharedGlobal] restartSessionWithPageType:pageType parameters:parameters clearAllVariables:YES];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)backAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
// Go back.
|
|
||||||
if ([delegateObject.actionDelegate respondsToSelector:@selector(handleBackAction:additionalData:)]) {
|
|
||||||
[delegateObject.actionDelegate handleBackAction:actionInformation additionalData:additionalData];
|
|
||||||
} else {
|
|
||||||
[[MVMCoreNavigationHandler sharedNavigationHandler] removeCurrentViewController];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)smsAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
|
|
||||||
NSString *phoneNumber = [actionInformation stringForKey:@"phoneNumber"];
|
|
||||||
NSString *message = [actionInformation stringForKey:KeyMessage];
|
|
||||||
NSString *smsQuery = [NSString stringWithFormat:@"sms:%@&body=%@", phoneNumber, message];
|
|
||||||
[MVMCoreActionUtility linkAway:[smsQuery stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] appURLString:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)contactAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
|
|
||||||
__weak typeof(self) weakSelf = self;
|
|
||||||
|
|
||||||
NSString *phoneNumber = [actionInformation string:@"phoneNumber"];
|
|
||||||
|
|
||||||
if (!phoneNumber) { return; }
|
|
||||||
CNMutableContact *contact = [[CNMutableContact alloc] init];
|
|
||||||
NSString *approach = [actionInformation stringForKey:@"approach"];
|
|
||||||
|
|
||||||
CNLabeledValue *phone = [[CNLabeledValue alloc] initWithLabel:CNLabelOther value:[[CNPhoneNumber alloc] initWithStringValue:phoneNumber]];
|
|
||||||
contact.phoneNumbers = @[phone];
|
|
||||||
|
|
||||||
if ([approach isEqualToString:KeyAdd]) {
|
|
||||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
|
||||||
CNContactPickerViewController *controller = [[CNContactPickerViewController alloc] init];
|
|
||||||
// Setting to accessibilityValue as a workaround to pass data via the delegate function.
|
|
||||||
[controller.view setAccessibilityIdentifier:phoneNumber];
|
|
||||||
controller.delegate = weakSelf;
|
|
||||||
|
|
||||||
[[MVMCoreNavigationHandler sharedNavigationHandler] presentViewController:controller animated:YES];
|
|
||||||
}];
|
|
||||||
} else if ([approach isEqualToString:KeyCreate]) {
|
|
||||||
contact.givenName = [actionInformation string:@"firstName"];
|
|
||||||
contact.familyName = [actionInformation string:@"lastName"];
|
|
||||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
|
||||||
CNContactStore *store = [[CNContactStore alloc] init];
|
|
||||||
CNContactViewController *controller = [CNContactViewController viewControllerForNewContact:contact];
|
|
||||||
controller.contactStore = store;
|
|
||||||
controller.delegate = weakSelf;
|
|
||||||
|
|
||||||
[[MVMCoreNavigationHandler sharedNavigationHandler] pushViewController:controller animated:YES];
|
|
||||||
}];
|
|
||||||
} else if ([approach isEqualToString:KeyView]) {
|
|
||||||
NSCharacterSet *symbols = [NSCharacterSet characterSetWithCharactersInString:@".+()- "];
|
|
||||||
NSString *contactPhoneNumber = [actionInformation string:@"phoneNumber"];
|
|
||||||
contactPhoneNumber = [[contactPhoneNumber componentsSeparatedByCharactersInSet:symbols] componentsJoinedByString:@""];
|
|
||||||
CNPhoneNumber *number = [[CNPhoneNumber alloc] initWithStringValue:contactPhoneNumber];
|
|
||||||
NSPredicate *contactPredicate = [CNContact predicateForContactsMatchingPhoneNumber:number];
|
|
||||||
NSArray *displayedKeys = @[[CNContactViewController descriptorForRequiredKeys]];
|
|
||||||
CNContactStore *store = [[CNContactStore alloc] init];
|
|
||||||
NSError *error;
|
|
||||||
CNContact *viewContact = [[store unifiedContactsMatchingPredicate:contactPredicate keysToFetch:displayedKeys error:&error] firstObject];
|
|
||||||
|
|
||||||
if (viewContact) {
|
|
||||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
|
||||||
CNContactViewController *controller = [CNContactViewController viewControllerForNewContact:viewContact];
|
|
||||||
controller.contactStore = store;
|
|
||||||
controller.delegate = weakSelf;
|
|
||||||
|
|
||||||
[[MVMCoreNavigationHandler sharedNavigationHandler] pushViewController:controller animated:YES];
|
|
||||||
}];
|
|
||||||
} else {
|
|
||||||
// No contacts found, show an alert
|
|
||||||
MVMCoreErrorObject *error = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorContactUnAvailable] code:ErrorCodeDefault domain:ErrorDomainNative location:[NSString stringWithFormat:@"%@_%@",NSStringFromClass([delegateObject.actionDelegate class]),KeyActionTypeContact]];
|
|
||||||
error.silentError = NO;
|
|
||||||
[self handleActionError:error actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)callAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
// Call
|
|
||||||
NSString *callNumber = [actionInformation stringForKey:KeyCallNumber];
|
|
||||||
[MVMCoreActionUtility linkAway:[@"tel://" stringByAppendingString:callNumber] appURLString:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)previousSubmitAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
// Perform the previous submission.
|
|
||||||
__weak typeof(self) weakSelf = self;
|
|
||||||
if ([delegateObject.actionDelegate respondsToSelector:@selector(prepareRequestForPreviousSubmission:additionalData:submit:)]) {
|
|
||||||
[delegateObject.actionDelegate prepareRequestForPreviousSubmission:actionInformation additionalData:additionalData submit:^(MVMCoreRequestParameters * _Nonnull requestParameters, NSDictionary * _Nullable dataForPage) {
|
|
||||||
|
|
||||||
[weakSelf updateRequestParametersBeforeHandleOpenPageAction:requestParameters callBack:^(MVMCoreRequestParameters * _Nonnull requestParameters) {
|
|
||||||
// Give the delegate a chance to alter the request parameters
|
|
||||||
if ([delegateObject.actionDelegate respondsToSelector:@selector(handleOpenPageForRequestParameters:actionInformation:additionalData:)]) {
|
|
||||||
[delegateObject.actionDelegate handleOpenPageForRequestParameters:requestParameters actionInformation:actionInformation additionalData:dataForPage];
|
|
||||||
} else {
|
|
||||||
[MVMCoreActionHandler defaultHandleOpenPageForRequestParameters:requestParameters
|
|
||||||
actionInformation:actionInformation
|
|
||||||
additionalData:additionalData
|
|
||||||
delegateObject:delegateObject];
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)redirectAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
// Have delegate redirect.
|
|
||||||
[[MVMCoreSessionObject sharedGlobal] redirectWithInfo:actionInformation];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)cancelAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
if ([delegateObject.actionDelegate respondsToSelector:@selector(handleCancel:additionalData:)]) {
|
|
||||||
[delegateObject.actionDelegate handleCancel:actionInformation additionalData:additionalData];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)settingsAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
[MVMCoreActionUtility linkAway:UIApplicationOpenSettingsURLString appURLString:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)actions:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
NSArray *actions = [actionInformation array:@"actions"];
|
|
||||||
BOOL concurrent = [actionInformation boolForKey:@"concurrent"];
|
|
||||||
for (NSDictionary *action in actions) {
|
|
||||||
NSString *actionType = [action string:KeyActionType];
|
|
||||||
if (concurrent) {
|
|
||||||
[self handleAction:actionType actionInformation:action additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
} else {
|
|
||||||
[self synchronouslyHandleAction:actionType actionInformation:action additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)handleOtherActions:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
return [self hasActionHandlerWithActionType:actionType actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)unknownAction:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
if ([delegateObject.actionDelegate respondsToSelector:@selector(handleUnknownActionType:actionInformation:additionalData:)]) {
|
|
||||||
[delegateObject.actionDelegate handleUnknownActionType:actionType actionInformation:actionInformation additionalData:additionalData];
|
|
||||||
} else {
|
|
||||||
[MVMCoreActionHandler defaultHandleUnknownActionType:actionType actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)handleActionError:(nullable MVMCoreErrorObject *)error actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
if (error) {
|
|
||||||
if ([delegateObject.actionDelegate respondsToSelector:@selector(handleActionError:additionalData:)]) {
|
|
||||||
[delegateObject.actionDelegate handleActionError:error additionalData:additionalData];
|
|
||||||
} else {
|
|
||||||
[self defaultHandleActionError:error additionalData:additionalData];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - CNContactViewControllerDelegate
|
|
||||||
|
|
||||||
- (void)contactViewController:(CNContactViewController *)viewController didCompleteWithContact:(CNContact *)contact {
|
|
||||||
[[MVMCoreNavigationHandler sharedNavigationHandler] removeCurrentViewController];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)contactViewController:(CNContactViewController *)viewController shouldPerformDefaultActionForContactProperty:(CNContactProperty *)property {
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - CNContactPickerDelegate
|
|
||||||
|
|
||||||
- (void)contactPickerDidCancel:(CNContactPickerViewController *)picker {
|
|
||||||
[[MVMCoreNavigationHandler sharedNavigationHandler] removeCurrentViewController];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact {
|
|
||||||
|
|
||||||
// This is a means to pass the data to this delegate function.
|
|
||||||
NSString *phoneNumber = picker.view.accessibilityIdentifier;
|
|
||||||
|
|
||||||
if (!phoneNumber) { return; }
|
|
||||||
CNContactStore *store = [[CNContactStore alloc] init];
|
|
||||||
CNMutableContact *existingContact = [(CNMutableContact *)contact mutableCopy];
|
|
||||||
CNPhoneNumber *number = [[CNPhoneNumber alloc] initWithStringValue:phoneNumber];
|
|
||||||
CNLabeledValue *labelValue = [[CNLabeledValue alloc] initWithLabel:CNLabelOther value:number];
|
|
||||||
NSMutableArray<CNLabeledValue *> *phoneNumbers = [NSMutableArray new];
|
|
||||||
[phoneNumbers addObject:labelValue];
|
|
||||||
[phoneNumbers addObjectsFromArray:existingContact.phoneNumbers];
|
|
||||||
existingContact.phoneNumbers = phoneNumbers;
|
|
||||||
|
|
||||||
__weak typeof(self) weakSelf = self;
|
|
||||||
|
|
||||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
|
||||||
CNContactViewController *controller = [CNContactViewController viewControllerForNewContact:existingContact];
|
|
||||||
controller.contactStore = store;
|
|
||||||
controller.delegate = weakSelf;
|
|
||||||
|
|
||||||
[[MVMCoreNavigationHandler sharedNavigationHandler] pushViewController:controller animated:YES];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Default Action Protocol
|
|
||||||
|
|
||||||
+ (void)defaultLogAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject{
|
|
||||||
// Currently no default log action but this will eventually be server driven.
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)defaultHandleOpenPageForRequestParameters:(nonnull MVMCoreRequestParameters *)requestParameters actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
|
|
||||||
NSDictionary *clientParamters = [actionInformation dict:KeyClientParameters];
|
|
||||||
if (clientParamters) {
|
|
||||||
[[MVMCoreActionHandler sharedActionHandler] getClientParameter:clientParamters
|
|
||||||
requestParameters: requestParameters.parameters
|
|
||||||
showLoadingOverlay: !requestParameters.backgroundRequest
|
|
||||||
completionHandler: ^(NSDictionary * _Nullable jsonDictionary) {
|
|
||||||
[requestParameters addRequestParameters:jsonDictionary];
|
|
||||||
[[MVMCoreLoadHandler sharedGlobal] loadRequest:requestParameters dataForPage:additionalData delegateObject:delegateObject];
|
|
||||||
}];
|
|
||||||
} else {
|
|
||||||
[[MVMCoreLoadHandler sharedGlobal] loadRequest:requestParameters dataForPage:additionalData delegateObject:delegateObject];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)defaultHandleUnknownActionType:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
|
|
||||||
MVMCoreErrorObject *error = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorUnableToProcess] code:ErrorCodeUnknownActionType domain:ErrorDomainNative location:[NSString stringWithFormat:@"%@Requests_%@",NSStringFromClass([delegateObject.actionDelegate class]),actionType]];
|
|
||||||
[[self sharedActionHandler] defaultHandleActionError:error additionalData:additionalData];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)defaultHandleActionError:(nonnull MVMCoreErrorObject *)error additionalData:(nullable NSDictionary *)additionalData {
|
|
||||||
|
|
||||||
// Logs the error.
|
|
||||||
if (error.logError) {
|
|
||||||
[MVMCoreLoggingHandler addErrorToLog:error];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
204
MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.swift
Normal file
204
MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.swift
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
//
|
||||||
|
// MVMCoreActionHandler.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 1/22/21.
|
||||||
|
// Copyright © 2021 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// Handlers that can be registered and used by the MVMCoreActionHandler to handle actions.
|
||||||
|
public protocol MVMCoreActionHandlerProtocol: ModelHandlerProtocol {
|
||||||
|
init()
|
||||||
|
|
||||||
|
func execute(with model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Protocol used to bridge legacy, non model based code. Allows us to keep the original json intact and not lose key values during decode/encode. Should not be used for new actions.
|
||||||
|
public protocol MVMCoreJSONActionHandlerProtocol: MVMCoreActionHandlerProtocol {
|
||||||
|
/// Perform the function using the original json and model.
|
||||||
|
func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc open class MVMCoreActionHandler: NSObject {
|
||||||
|
|
||||||
|
enum ActionError: MVMError, CustomStringConvertible {
|
||||||
|
case unknownAction(type: String)
|
||||||
|
|
||||||
|
public var description: String {
|
||||||
|
switch self {
|
||||||
|
case MVMCoreActionHandler.ActionError.unknownAction(let type):
|
||||||
|
return "Couldn't perform action: \(type)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var errorCode: Int {
|
||||||
|
ErrorCode.unknownActionType.rawValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Used to temporarily store the json in additionalData.
|
||||||
|
private let jsonKey = "MVMCore.JSON"
|
||||||
|
|
||||||
|
/// Returns the action handler stored in the MVMCoreObject
|
||||||
|
@objc(sharedActionHandler)
|
||||||
|
public static func shared() -> Self? {
|
||||||
|
return MVMCoreActionUtility.initializerClassCheck(MVMCoreObject.sharedInstance()?.actionHandler, classToVerify: self) as? Self
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Conversions
|
||||||
|
|
||||||
|
/// Converts the action to json for legacy functions.
|
||||||
|
static public func convertActionToJSON(_ model: ActionModelProtocol) throws -> [AnyHashable: Any] {
|
||||||
|
let data = try model.encode()
|
||||||
|
guard let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [AnyHashable: Any] else {
|
||||||
|
throw ModelRegistry.Error.decoderError
|
||||||
|
}
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a model from the action json.
|
||||||
|
static public func createModel(with json: [AnyHashable: Any], delegateObject: DelegateObject? = nil) throws -> ActionModelProtocol {
|
||||||
|
guard let castedSelf = json as? [String: Any] else {
|
||||||
|
throw ModelRegistry.Error.decoderOther(message: "Dictionary is not of type [String: Any]")
|
||||||
|
}
|
||||||
|
guard let actionType = ModelRegistry.getType(for: castedSelf.stringForkey(KeyActionType), with: ActionModelProtocol.self) else {
|
||||||
|
throw ModelRegistry.Error.decoderErrorModelNotMapped()
|
||||||
|
}
|
||||||
|
guard let actionModel = try actionType.decode(jsonDict: castedSelf, delegateObject: delegateObject) as? ActionModelProtocol else {
|
||||||
|
throw ModelRegistry.Error.decoderOther(message: "Could not decode to ActionModelProtocol")
|
||||||
|
}
|
||||||
|
return actionModel
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Error Handling
|
||||||
|
|
||||||
|
/// Returns a common description for the error location.
|
||||||
|
@objc public static func getErrorLocation(with delegate: MVMCoreActionDelegateProtocol?, actionType: String) -> String {
|
||||||
|
return "\(String(describing: delegate))_\(actionType)"
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Action Handling
|
||||||
|
|
||||||
|
/// Handle an action with the given model.
|
||||||
|
open func handleAction(with model: ActionModelProtocol, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) async throws {
|
||||||
|
try Task.checkCancellation()
|
||||||
|
var additionalData = MVMCoreActionHandler.setUUID(additionalData: additionalData)
|
||||||
|
MVMCoreActionHandler.log(string: "Begin Action: \(model.actionType)", additionalData: additionalData)
|
||||||
|
defer {
|
||||||
|
MVMCoreActionHandler.log(string: "End Action: \(model.actionType)", additionalData: additionalData)
|
||||||
|
}
|
||||||
|
let json = try additionalData.removeValue(forKey: jsonKey) as? [AnyHashable : Any] ?? MVMCoreActionHandler.convertActionToJSON(model)
|
||||||
|
|
||||||
|
// Log the action
|
||||||
|
logAction(with: json, additionalData: additionalData, delegateObject: delegateObject)
|
||||||
|
|
||||||
|
do {
|
||||||
|
let handlerType = try ModelRegistry.getHandler(model) as! MVMCoreActionHandlerProtocol.Type
|
||||||
|
let handler = handlerType.init()
|
||||||
|
if let handler = handler as? MVMCoreJSONActionHandlerProtocol {
|
||||||
|
// Needed until we can remove legacy delegate functions.
|
||||||
|
try await handler.performAction(with: json, model: model, delegateObject: delegateObject, additionalData: additionalData)
|
||||||
|
} else {
|
||||||
|
try await handler.execute(with: model, delegateObject: delegateObject, additionalData: additionalData)
|
||||||
|
}
|
||||||
|
} catch ModelRegistry.Error.handlerNotMapped {
|
||||||
|
try Task.checkCancellation()
|
||||||
|
// Allows custom handling if there no handler for the action.
|
||||||
|
guard try await handleUnregisteredAction(with: model, json: json, additionalData: additionalData, delegateObject: delegateObject) else {
|
||||||
|
MVMCoreActionHandler.log(string: "Failed Action Unknown", additionalData: additionalData)
|
||||||
|
throw ActionError.unknownAction(type: model.actionType)
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
MVMCoreActionHandler.log(string: "Failed Action \(error)", additionalData: additionalData)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Subclassables
|
||||||
|
|
||||||
|
/// Subclass to log the action was fired.
|
||||||
|
open func logAction(with JSON: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
|
||||||
|
// Calls legacy log action function.
|
||||||
|
delegateObject?.actionDelegate?.logAction?(withActionInformation: JSON, additionalData: additionalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Logs the error.
|
||||||
|
@objc open func defaultHandleActionError(_ error: MVMCoreErrorObject, additionalData: [AnyHashable: Any]?) {
|
||||||
|
guard error.logError else { return }
|
||||||
|
MVMCoreLoggingHandler.addError(toLog: error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Legacy Holdovers
|
||||||
|
|
||||||
|
static public func setUUID(additionalData: [AnyHashable: Any]?, force: Bool = false) -> [AnyHashable: Any] {
|
||||||
|
if !force && getUUID(additionalData: additionalData) != nil { return additionalData! }
|
||||||
|
return additionalData.dictionaryAdding(key: "Action-UUID", value: UUID().uuidString)
|
||||||
|
}
|
||||||
|
|
||||||
|
static public func getUUID(additionalData: [AnyHashable: Any]?) -> String? {
|
||||||
|
return additionalData?.optionalStringForKey("Action-UUID")
|
||||||
|
}
|
||||||
|
|
||||||
|
static public func log(string: String, additionalData: [AnyHashable: Any]?) {
|
||||||
|
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ActionHandler: UUID: \(String(describing: getUUID(additionalData: additionalData))), \(string)")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Legacy handle action with json.
|
||||||
|
@objc(handleActionWithDictionary:additionalData:delegateObject:)
|
||||||
|
open func handleAction(with json: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
|
||||||
|
_ = Task(priority: .userInitiated) {
|
||||||
|
try Task.checkCancellation()
|
||||||
|
do {
|
||||||
|
guard let json = json else {
|
||||||
|
throw ModelRegistry.Error.keyNotFound
|
||||||
|
}
|
||||||
|
let model = try MVMCoreActionHandler.createModel(with: json, delegateObject: delegateObject)
|
||||||
|
try await handleAction(with: model, json: json, additionalData: additionalData, delegateObject: delegateObject)
|
||||||
|
} catch {
|
||||||
|
let actionType = json?.optionalStringForKey(KeyActionType)
|
||||||
|
switch error {
|
||||||
|
case ModelRegistry.Error.decoderErrorModelNotMapped:
|
||||||
|
// If the model is not mapped, give the legacy classes a chance to handle it.
|
||||||
|
if try await handleUnregisteredAction(with: nil, json: json!, additionalData: additionalData, delegateObject: delegateObject) == false {
|
||||||
|
fallthrough
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
MVMCoreActionHandler.log(string: "Failed Action: Error \(error)", additionalData: additionalData)
|
||||||
|
if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: actionType ?? "noAction")) {
|
||||||
|
defaultHandleActionError(errorObject, additionalData: additionalData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Bridges the legacy json using functions and the new model using functions.
|
||||||
|
open func handleAction(with model: ActionModelProtocol, json: [AnyHashable: Any], additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) async throws {
|
||||||
|
try Task.checkCancellation()
|
||||||
|
var additionalData = additionalData.dictionaryAdding(key: jsonKey, value: json)
|
||||||
|
additionalData = MVMCoreActionHandler.setUUID(additionalData: additionalData, force: true)
|
||||||
|
MVMCoreActionHandler.log(string: "JSON \(json)", additionalData: additionalData)
|
||||||
|
if let closure = (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction {
|
||||||
|
// Allow newer delegates to handle calls from legacy functions
|
||||||
|
try await closure(model, additionalData, delegateObject)
|
||||||
|
} else {
|
||||||
|
try await handleAction(with: model, additionalData: additionalData, delegateObject: delegateObject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Subclass to handle and any actions where a handler was not registered. Checks with the delegate handlesUnknownAction function
|
||||||
|
open func handleUnregisteredAction(with model: ActionModelProtocol?, json: [AnyHashable: Any], additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) async throws -> Bool {
|
||||||
|
// Check if the delegate handles the action.
|
||||||
|
let actionType = json.optionalStringForKey(KeyActionType)
|
||||||
|
if let closure = delegateObject?.actionDelegate?.handleUnknownActionType {
|
||||||
|
MVMCoreActionHandler.log(string: "Unknown handled (Handler not registered): \(String(describing: actionType)) \(String(describing: delegateObject?.actionDelegate))", additionalData: additionalData)
|
||||||
|
// Check if the legacy delegate handles the action.
|
||||||
|
closure(actionType, json, additionalData)
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -33,6 +33,10 @@ extern NSString * const KeyView;
|
|||||||
extern NSString * const KeyLinks;
|
extern NSString * const KeyLinks;
|
||||||
extern NSString * const KeyTitle;
|
extern NSString * const KeyTitle;
|
||||||
extern NSString * const KeyMessage;
|
extern NSString * const KeyMessage;
|
||||||
|
|
||||||
|
extern NSString * const KeyActionType;
|
||||||
|
extern NSString * const KeyActionTypeLinkAway;
|
||||||
|
extern NSString * const KeyActionTypeOpen;
|
||||||
extern NSString * const KeyActionTypeRestart;
|
extern NSString * const KeyActionTypeRestart;
|
||||||
extern NSString * const KeyActionTypeBack;
|
extern NSString * const KeyActionTypeBack;
|
||||||
extern NSString * const KeyActionTypeShare;
|
extern NSString * const KeyActionTypeShare;
|
||||||
|
|||||||
@ -35,6 +35,10 @@ NSString * const KeyView = @"view";
|
|||||||
NSString * const KeyLinks = @"Links";
|
NSString * const KeyLinks = @"Links";
|
||||||
NSString * const KeyTitle = @"title";
|
NSString * const KeyTitle = @"title";
|
||||||
NSString * const KeyMessage = @"message";
|
NSString * const KeyMessage = @"message";
|
||||||
|
|
||||||
|
NSString * const KeyActionType = @"actionType";
|
||||||
|
NSString * const KeyActionTypeLinkAway = @"openURL";
|
||||||
|
NSString * const KeyActionTypeOpen = @"openPage";
|
||||||
NSString * const KeyActionTypeRestart = @"restart";
|
NSString * const KeyActionTypeRestart = @"restart";
|
||||||
NSString * const KeyActionTypeBack = @"back";
|
NSString * const KeyActionTypeBack = @"back";
|
||||||
NSString * const KeyActionTypeShare = @"share";
|
NSString * const KeyActionTypeShare = @"share";
|
||||||
|
|||||||
@ -24,7 +24,6 @@
|
|||||||
#import "MVMCoreHardcodedStringsConstants.h"
|
#import "MVMCoreHardcodedStringsConstants.h"
|
||||||
#import "MVMCoreErrorConstants.h"
|
#import "MVMCoreErrorConstants.h"
|
||||||
#import "MVMCoreActionUtility.h"
|
#import "MVMCoreActionUtility.h"
|
||||||
#import <MVMCore/MVMCoreActionHandler.h>
|
|
||||||
#import "MVMCoreObject.h"
|
#import "MVMCoreObject.h"
|
||||||
#import "MVMCoreConstants.h"
|
#import "MVMCoreConstants.h"
|
||||||
#import <MVMCore/MVMCore-Swift.h>
|
#import <MVMCore/MVMCore-Swift.h>
|
||||||
|
|||||||
@ -66,7 +66,6 @@ FOUNDATION_EXPORT const unsigned char MVMCoreVersionString[];
|
|||||||
#import <MVMCore/MVMCoreAlertController.h>
|
#import <MVMCore/MVMCoreAlertController.h>
|
||||||
|
|
||||||
// Action Handling
|
// Action Handling
|
||||||
#import <MVMCore/MVMCoreActionHandler.h>
|
|
||||||
#import <MVMCore/MVMCoreActionDelegateProtocol.h>
|
#import <MVMCore/MVMCoreActionDelegateProtocol.h>
|
||||||
#import <MVMCore/MVMCoreActionUtility.h>
|
#import <MVMCore/MVMCoreActionUtility.h>
|
||||||
|
|
||||||
|
|||||||
@ -1,41 +0,0 @@
|
|||||||
//
|
|
||||||
// ActionModel.swift
|
|
||||||
// MVMCore
|
|
||||||
//
|
|
||||||
// Created by Suresh, Kamlesh on 10/3/19.
|
|
||||||
// Copyright © 2019 Suresh, Kamlesh. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
@objcMembers open class ActionOpenPageModel: ActionModelProtocol, ActionOpenPageProtocol, ClientParameterActionProtocol {
|
|
||||||
//--------------------------------------------------
|
|
||||||
// MARK: - Properties
|
|
||||||
//--------------------------------------------------
|
|
||||||
|
|
||||||
public static var identifier: String = "openPage"
|
|
||||||
public var actionType: String = ActionOpenPageModel.identifier
|
|
||||||
public var pageType: String
|
|
||||||
public var modules: [String]?
|
|
||||||
public var baseURL: String?
|
|
||||||
public var appContext: String?
|
|
||||||
public var requestURL: String?
|
|
||||||
public var extraParameters: JSONValueDictionary?
|
|
||||||
public var analyticsData: JSONValueDictionary?
|
|
||||||
public var presentationStyle: String?
|
|
||||||
public var tabBarIndex: Int?
|
|
||||||
public var background: Bool?
|
|
||||||
public var clientParameters: ClientParameterModel?
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
|
||||||
// MARK: - Initialzier
|
|
||||||
//--------------------------------------------------
|
|
||||||
|
|
||||||
public init(pageType: String, presentationStyle: String? = nil, extraParameters: JSONValueDictionary? = nil, analyticsData: JSONValueDictionary? = nil, tabBarIndex: Int? = nil, background: Bool? = nil) {
|
|
||||||
self.pageType = pageType
|
|
||||||
self.presentationStyle = presentationStyle
|
|
||||||
self.extraParameters = extraParameters
|
|
||||||
self.analyticsData = analyticsData
|
|
||||||
self.tabBarIndex = tabBarIndex
|
|
||||||
self.background = background
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -44,21 +44,23 @@
|
|||||||
///}
|
///}
|
||||||
/// completionHandler can return flat dictinary or a map. It depends on the paramters handler
|
/// completionHandler can return flat dictinary or a map. It depends on the paramters handler
|
||||||
open func getParameters(with clientParameters: [String: Any], requestParameters: [String: Any], completionHandler:@escaping ([String: Any]?) -> ()) throws {
|
open func getParameters(with clientParameters: [String: Any], requestParameters: [String: Any], completionHandler:@escaping ([String: Any]?) -> ()) throws {
|
||||||
|
|
||||||
guard let clientParameterModel = try getClientParameterModel(clientParameters) else {
|
guard let clientParameterModel = try getClientParameterModel(clientParameters) else {
|
||||||
completionHandler(nil)
|
completionHandler(nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
try getParameters(with: clientParameterModel, requestParameters: requestParameters, completionHandler: completionHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
open func getParameters(with model: ClientParameterModel, requestParameters: [String: Any], completionHandler:@escaping ([String: Any]?) -> ()) throws {
|
||||||
|
|
||||||
let timeout = clientParameterModel.timeout ?? 30.0
|
let timeout = model.timeout ?? 30.0
|
||||||
|
|
||||||
|
|
||||||
// Dispatch setup on queue to ensure setup is complete before completion callbacks.
|
// Dispatch setup on queue to ensure setup is complete before completion callbacks.
|
||||||
|
|
||||||
// Don't use [weak self]. Object is deallocated in the dispatch queue.
|
// Don't use [weak self]. Object is deallocated in the dispatch queue.
|
||||||
parametersWorkQueue.async(group: group, qos: .userInitiated) {
|
parametersWorkQueue.async(group: group, qos: .userInitiated) {
|
||||||
// Create the handler list so that same object can be used when merging. Merging needs default value in case of timeout
|
// Create the handler list so that same object can be used when merging. Merging needs default value in case of timeout
|
||||||
for parameterModel in clientParameterModel.list {
|
for parameterModel in model.list {
|
||||||
if let parameterHandler = self.createParametersHandler(parameterModel) {
|
if let parameterHandler = self.createParametersHandler(parameterModel) {
|
||||||
self.parameterHandlerList.append(parameterHandler)
|
self.parameterHandlerList.append(parameterHandler)
|
||||||
}
|
}
|
||||||
@ -101,7 +103,7 @@
|
|||||||
// Queue the results for merge.
|
// Queue the results for merge.
|
||||||
self.parametersWorkQueue.async {
|
self.parametersWorkQueue.async {
|
||||||
if (returnedList[index] != nil) {
|
if (returnedList[index] != nil) {
|
||||||
MVMCoreLoggingHandler.shared()?.addError(toLog: MVMCoreErrorObject(title: nil, message: "Client parameter \(parameterType) has already executed. The completion handler should only be called once!", code: ErrorCode.default.rawValue, domain: ErrorDomainNative, location: String(describing: ClientParameterHandler.self))!)
|
MVMCoreLoggingHandler.addError(toLog: MVMCoreErrorObject(title: nil, message: "Client parameter \(parameterType) has already executed. The completion handler should only be called once!", code: ErrorCode.default.rawValue, domain: ErrorDomainNative, location: String(describing: ClientParameterHandler.self))!)
|
||||||
} else {
|
} else {
|
||||||
returnedList[index] = receivedParameter
|
returnedList[index] = receivedParameter
|
||||||
self.group.leave() // Leaving is only done after setup (barriered).
|
self.group.leave() // Leaving is only done after setup (barriered).
|
||||||
|
|||||||
@ -12,18 +12,18 @@
|
|||||||
|
|
||||||
open class func registerActions() {
|
open class func registerActions() {
|
||||||
ModelRegistry.register(ActionRunJavaScriptModel.self)
|
ModelRegistry.register(ActionRunJavaScriptModel.self)
|
||||||
ModelRegistry.register(ActionOpenPageModel.self)
|
ModelRegistry.register(handler: ActionOpenPageHandler.self, for: ActionOpenPageModel.self)
|
||||||
ModelRegistry.register(handler: ActionOpenUrlHandler.self, for: ActionOpenUrlModel.self)
|
ModelRegistry.register(handler: ActionOpenUrlHandler.self, for: ActionOpenUrlModel.self)
|
||||||
ModelRegistry.register(ActionCallModel.self)
|
ModelRegistry.register(handler: ActionCallHandler.self, for: ActionCallModel.self)
|
||||||
ModelRegistry.register(ActionBackModel.self)
|
ModelRegistry.register(handler: ActionBackHandler.self, for: ActionBackModel.self)
|
||||||
ModelRegistry.register(ActionShareModel.self)
|
ModelRegistry.register(handler: ActionShareHandler.self, for: ActionShareModel.self)
|
||||||
ModelRegistry.register(ActionRestartModel.self)
|
ModelRegistry.register(handler: ActionRestartHandler.self, for: ActionRestartModel.self)
|
||||||
ModelRegistry.register(ActionPreviousSubmitModel.self)
|
ModelRegistry.register(handler: ActionPreviousSubmitHandler.self, for: ActionPreviousSubmitModel.self)
|
||||||
ModelRegistry.register(ActionCancelModel.self)
|
ModelRegistry.register(handler: ActionCancelHandler.self, for: ActionCancelModel.self)
|
||||||
ModelRegistry.register(ActionSettingModel.self)
|
ModelRegistry.register(handler: ActionSettingHandler.self, for: ActionSettingModel.self)
|
||||||
ModelRegistry.register(ActionNoopModel.self)
|
ModelRegistry.register(handler: ActionNoopHandler.self, for: ActionNoopModel.self)
|
||||||
ModelRegistry.register(ActionActionsModel.self)
|
ModelRegistry.register(handler: ActionActionsHandler.self, for: ActionActionsModel.self)
|
||||||
ModelRegistry.register(ActionOpenSMSModel.self)
|
ModelRegistry.register(handler: ActionOpenSMSHandler.self, for: ActionOpenSMSModel.self)
|
||||||
ModelRegistry.register(ActionContactModel.self)
|
ModelRegistry.register(handler: ActionContactHandler.self, for: ActionContactModel.self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,6 +37,9 @@
|
|||||||
// pops or dimisses as needed
|
// pops or dimisses as needed
|
||||||
- (void)removeCurrentViewController;
|
- (void)removeCurrentViewController;
|
||||||
|
|
||||||
|
/// Dismisses or pops the current view controller.
|
||||||
|
- (void)removeCurrentViewController:(BOOL)animated completionHandler:(nullable void (^)(void))completionBlock;
|
||||||
|
|
||||||
#pragma mark - Delegate Handling
|
#pragma mark - Delegate Handling
|
||||||
|
|
||||||
/// Adds a listener for navigation delegate functions
|
/// Adds a listener for navigation delegate functions
|
||||||
|
|||||||
@ -118,12 +118,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)removeCurrentViewController {
|
- (void)removeCurrentViewController {
|
||||||
|
[self removeCurrentViewController:YES completionHandler:NULL];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)removeCurrentViewController:(BOOL)animated completionHandler:(nullable void (^)(void))completionBlock {
|
||||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
||||||
// presentedViewController must be used on main thread
|
// presentedViewController must be used on main thread
|
||||||
if (self.viewControllerToPresentOn.presentedViewController) {
|
if (self.viewControllerToPresentOn.presentedViewController) {
|
||||||
[[MVMCoreNavigationHandler sharedNavigationHandler] dismissTopViewControllerAnimated:YES];
|
[[MVMCoreNavigationHandler sharedNavigationHandler] dismissTopViewControllerAnimated:animated delegate:nil completionHandler:completionBlock];
|
||||||
} else {
|
} else {
|
||||||
[[MVMCoreNavigationHandler sharedNavigationHandler] popTopViewControllerAnimated:YES];
|
[[MVMCoreNavigationHandler sharedNavigationHandler] popTopViewControllerAnimated:animated navigationController:nil delegate:nil completionHandler:completionBlock];
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,13 +10,13 @@
|
|||||||
#import <MVMCore/MVMCoreSessionObject.h>
|
#import <MVMCore/MVMCoreSessionObject.h>
|
||||||
#import <MVMCore/MVMCoreCache.h>
|
#import <MVMCore/MVMCoreCache.h>
|
||||||
#import <MVMCore/MVMCoreViewControllerMappingObject.h>
|
#import <MVMCore/MVMCoreViewControllerMappingObject.h>
|
||||||
#import <MVMCore/MVMCoreActionHandler.h>
|
|
||||||
#import <MVMCore/MVMCoreSessionTimeHandler.h>
|
#import <MVMCore/MVMCoreSessionTimeHandler.h>
|
||||||
#import <MVMCore/MVMCoreGlobalLoadProtocol.h>
|
#import <MVMCore/MVMCoreGlobalLoadProtocol.h>
|
||||||
#import <MVMCore/MVMCoreLoadingOverlayDelegateProtocol.h>
|
#import <MVMCore/MVMCoreLoadingOverlayDelegateProtocol.h>
|
||||||
#import <MVMCore/MVMCoreLoggingDelegateProtocol.h>
|
#import <MVMCore/MVMCoreLoggingDelegateProtocol.h>
|
||||||
#import <MVMCore/MVMCoreLoggingHandler.h>
|
#import <MVMCore/MVMCoreLoggingHandler.h>
|
||||||
#import <MVMCore/MVMCoreLoadHandler.h>
|
#import <MVMCore/MVMCoreLoadHandler.h>
|
||||||
|
@class MVMCoreActionHandler;
|
||||||
|
|
||||||
@interface MVMCoreObject : NSObject
|
@interface MVMCoreObject : NSObject
|
||||||
|
|
||||||
|
|||||||
52
MVMCore/MVMCore/Utility/MVMCoreError.swift
Normal file
52
MVMCore/MVMCore/Utility/MVMCoreError.swift
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
//
|
||||||
|
// MVMCoreError.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 7/27/22.
|
||||||
|
// Copyright © 2022 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public enum MVMCoreError: MVMError, CustomStringConvertible {
|
||||||
|
case error(code: Int, messageToDisplay: String? = nil, messageToLog: String)
|
||||||
|
case errorObject(_ object: MVMCoreErrorObject)
|
||||||
|
|
||||||
|
public var errorCode: Int {
|
||||||
|
switch self {
|
||||||
|
case MVMCoreError.error(let code, _, _):
|
||||||
|
return code
|
||||||
|
case MVMCoreError.errorObject(let object):
|
||||||
|
return object.code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var description: String {
|
||||||
|
switch self {
|
||||||
|
case MVMCoreError.error(_, _, let messageToLog):
|
||||||
|
return messageToLog
|
||||||
|
case MVMCoreError.errorObject(let object):
|
||||||
|
return object.messageToLog ?? "Error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var errorDescription: String? {
|
||||||
|
switch self {
|
||||||
|
case MVMCoreError.error(_, let message, _):
|
||||||
|
return message ?? MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess)
|
||||||
|
case MVMCoreError.errorObject(let object):
|
||||||
|
return object.messageToDisplay ?? MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc public extension NSError {
|
||||||
|
@objc func checkForMVMCoreError() -> MVMCoreErrorObject? {
|
||||||
|
switch self as Error {
|
||||||
|
case MVMCoreError.errorObject(let object):
|
||||||
|
return object
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -14,6 +14,7 @@
|
|||||||
#import "MVMCoreJSONConstants.h"
|
#import "MVMCoreJSONConstants.h"
|
||||||
#import "MVMCoreHardcodedStringsConstants.h"
|
#import "MVMCoreHardcodedStringsConstants.h"
|
||||||
#import "MVMCoreDispatchUtility.h"
|
#import "MVMCoreDispatchUtility.h"
|
||||||
|
#import <MVMCore/MVMCore-Swift.h>
|
||||||
|
|
||||||
@implementation MVMCoreErrorObject
|
@implementation MVMCoreErrorObject
|
||||||
|
|
||||||
@ -106,8 +107,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
+ (nullable instancetype)createErrorObjectForNSError:(nonnull NSError *)error location:(nullable NSString *)location {
|
+ (nullable instancetype)createErrorObjectForNSError:(nonnull NSError *)error location:(nullable NSString *)location {
|
||||||
|
MVMCoreErrorObject *errorObject = [error checkForMVMCoreError];
|
||||||
MVMCoreErrorObject *errorObject = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[error localizedDescription] messageToLog:[error description] code:[error code] domain:ErrorDomainSystem location:location];
|
if (errorObject) {
|
||||||
|
return errorObject;
|
||||||
|
}
|
||||||
|
errorObject = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[error localizedDescription] messageToLog:[error description] code:[error code] domain:ErrorDomainSystem location:location];
|
||||||
if ([error.domain isEqualToString:NSURLErrorDomain]) {
|
if ([error.domain isEqualToString:NSURLErrorDomain]) {
|
||||||
errorObject.systemDomain = error.domain;
|
errorObject.systemDomain = error.domain;
|
||||||
if ([[MVMCoreObject sharedInstance].globalLoadDelegate respondsToSelector:@selector(getNativeScreenForRequestError:requestObject:)]) {
|
if ([[MVMCoreObject sharedInstance].globalLoadDelegate respondsToSelector:@selector(getNativeScreenForRequestError:requestObject:)]) {
|
||||||
|
|||||||
18
MVMCore/MVMCore/Utility/MVMError.swift
Normal file
18
MVMCore/MVMCore/Utility/MVMError.swift
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// MVMError.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 7/27/22.
|
||||||
|
// Copyright © 2022 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol MVMError: LocalizedError, CustomNSError {}
|
||||||
|
extension MVMError {
|
||||||
|
public var errorDescription: String? { return MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess) }
|
||||||
|
|
||||||
|
public static var errorDomain: String {
|
||||||
|
return ErrorDomainNative
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user