diff --git a/.gitignore b/.gitignore index 3bc7441..73454f7 100644 --- a/.gitignore +++ b/.gitignore @@ -11,8 +11,8 @@ mvm_core mfprepayshop_ios mvm_core_ui mvmreactnative -vds -VDSSample +vds_ios +vds_ios_sample # frameworks contentTransferFramework.framework diff --git a/JSONCreator.xcworkspace/contents.xcworkspacedata b/JSONCreator.xcworkspace/contents.xcworkspacedata index a714f9d..40a48cc 100644 --- a/JSONCreator.xcworkspace/contents.xcworkspacedata +++ b/JSONCreator.xcworkspace/contents.xcworkspacedata @@ -2,10 +2,7 @@ - - + location = "group:vds_ios/VDS.xcodeproj"> diff --git a/JSONCreator_iOS/JSONCreator.xcodeproj/project.pbxproj b/JSONCreator_iOS/JSONCreator.xcodeproj/project.pbxproj index c6ffea1..b704ce5 100644 --- a/JSONCreator_iOS/JSONCreator.xcodeproj/project.pbxproj +++ b/JSONCreator_iOS/JSONCreator.xcodeproj/project.pbxproj @@ -73,8 +73,6 @@ EA33618B288B1B630071C351 /* VDS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA33618A288B1B630071C351 /* VDS.framework */; }; EA33618C288B1B630071C351 /* VDS.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EA33618A288B1B630071C351 /* VDS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; EA3361C1288B37FB0071C351 /* TestToggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3361C0288B37FB0071C351 /* TestToggle.swift */; }; - EA3361FB2891D54A0071C351 /* VDSTypographyTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA3361FA2891D54A0071C351 /* VDSTypographyTokens.xcframework */; }; - EA3361FC2891D54A0071C351 /* VDSTypographyTokens.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EA3361FA2891D54A0071C351 /* VDSTypographyTokens.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; EA3362342891F5AB0071C351 /* TestToggleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3362332891F5AB0071C351 /* TestToggleModel.swift */; }; EA3E48A62860BB4D00B524AB /* WifiWidgetModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3E48A52860BB4D00B524AB /* WifiWidgetModel.swift */; }; EA3E48A82860BB9800B524AB /* WifiWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3E48A72860BB9800B524AB /* WifiWidget.swift */; }; @@ -82,12 +80,30 @@ EA5B696F2866BC1000B17D2E /* MVMCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EA5B696C2866BC1000B17D2E /* MVMCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; EA5B69702866BC1000B17D2E /* MVMCoreUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA5B696D2866BC1000B17D2E /* MVMCoreUI.framework */; }; EA5B69712866BC1000B17D2E /* MVMCoreUI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EA5B696D2866BC1000B17D2E /* MVMCoreUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + EA84F75128BD558F00D67ABC /* TransientCoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA84F73F28BD558F00D67ABC /* TransientCoding.swift */; }; + EA84F75228BD558F00D67ABC /* ImmutableWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA84F74028BD558F00D67ABC /* ImmutableWrapper.swift */; }; + EA84F75328BD558F00D67ABC /* OptionalWrappers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA84F74128BD558F00D67ABC /* OptionalWrappers.swift */; }; + EA84F75428BD558F00D67ABC /* FallbackCoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA84F74228BD558F00D67ABC /* FallbackCoding.swift */; }; + EA84F75528BD558F00D67ABC /* OmitCodingWrappers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA84F74328BD558F00D67ABC /* OmitCodingWrappers.swift */; }; + EA84F75628BD558F00D67ABC /* StaticCodingWrappers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA84F74428BD558F00D67ABC /* StaticCodingWrappers.swift */; }; + EA84F75728BD558F00D67ABC /* NilFiltering.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA84F74628BD558F00D67ABC /* NilFiltering.swift */; }; + EA84F75828BD558F00D67ABC /* DateCoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA84F74728BD558F00D67ABC /* DateCoding.swift */; }; + EA84F75928BD558F00D67ABC /* FloatingPointCoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA84F74828BD558F00D67ABC /* FloatingPointCoding.swift */; }; + EA84F75A28BD558F00D67ABC /* BoolCoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA84F74928BD558F00D67ABC /* BoolCoding.swift */; }; + EA84F75B28BD558F00D67ABC /* DataCoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA84F74A28BD558F00D67ABC /* DataCoding.swift */; }; + EA84F75C28BD558F00D67ABC /* NullEncoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA84F74B28BD558F00D67ABC /* NullEncoding.swift */; }; + EA84F75D28BD558F00D67ABC /* StaticCoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA84F74C28BD558F00D67ABC /* StaticCoding.swift */; }; + EA84F75E28BD558F00D67ABC /* EmptyDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA84F74E28BD558F00D67ABC /* EmptyDefaults.swift */; }; + EA84F75F28BD558F00D67ABC /* CustomWrappers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA84F74F28BD558F00D67ABC /* CustomWrappers.swift */; }; + EA84F76028BD558F00D67ABC /* ConveienceAdherence.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA84F75028BD558F00D67ABC /* ConveienceAdherence.swift */; }; EAA54A92286A47ED00B9136B /* WifiViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA54A91286A47ED00B9136B /* WifiViewController.swift */; }; - EAA658152875FA5E00484A7D /* VDSFormControlsTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EAA658142875FA5E00484A7D /* VDSFormControlsTokens.xcframework */; }; - EAA658162875FA5E00484A7D /* VDSFormControlsTokens.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EAA658142875FA5E00484A7D /* VDSFormControlsTokens.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - EACA5E5E2853DBC900CBA65B /* VDSColorTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EACA5E5D2853DBC900CBA65B /* VDSColorTokens.xcframework */; }; - EACA5E5F2853DBC900CBA65B /* VDSColorTokens.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EACA5E5D2853DBC900CBA65B /* VDSColorTokens.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; EAF7F0912899825D00B287F5 /* TestLabelToggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0902899825D00B287F5 /* TestLabelToggle.swift */; }; + EAF7F12528A15E2300B287F5 /* VDSTypographyTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA3361FA2891D54A0071C351 /* VDSTypographyTokens.xcframework */; }; + EAF7F12628A15E2300B287F5 /* VDSTypographyTokens.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EA3361FA2891D54A0071C351 /* VDSTypographyTokens.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + EAF7F12728A15E2300B287F5 /* VDSFormControlsTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EAA658142875FA5E00484A7D /* VDSFormControlsTokens.xcframework */; }; + EAF7F12828A15E2300B287F5 /* VDSFormControlsTokens.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EAA658142875FA5E00484A7D /* VDSFormControlsTokens.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + EAF7F12928A15E2300B287F5 /* VDSColorTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EACA5E5D2853DBC900CBA65B /* VDSColorTokens.xcframework */; }; + EAF7F12A28A15E2300B287F5 /* VDSColorTokens.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EACA5E5D2853DBC900CBA65B /* VDSColorTokens.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -97,11 +113,11 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( + EAF7F12828A15E2300B287F5 /* VDSFormControlsTokens.xcframework in Embed Frameworks */, + EAF7F12A28A15E2300B287F5 /* VDSColorTokens.xcframework in Embed Frameworks */, EA33618C288B1B630071C351 /* VDS.framework in Embed Frameworks */, - EAA658162875FA5E00484A7D /* VDSFormControlsTokens.xcframework in Embed Frameworks */, EA5B696F2866BC1000B17D2E /* MVMCore.framework in Embed Frameworks */, - EACA5E5F2853DBC900CBA65B /* VDSColorTokens.xcframework in Embed Frameworks */, - EA3361FC2891D54A0071C351 /* VDSTypographyTokens.xcframework in Embed Frameworks */, + EAF7F12628A15E2300B287F5 /* VDSTypographyTokens.xcframework in Embed Frameworks */, EA5B69712866BC1000B17D2E /* MVMCoreUI.framework in Embed Frameworks */, ); name = "Embed Frameworks"; @@ -178,6 +194,22 @@ EA5B696D2866BC1000B17D2E /* MVMCoreUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = MVMCoreUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; EA7E676927582F2200ABF773 /* MVMCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = MVMCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; EA7E676A27582F2200ABF773 /* MVMCoreUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = MVMCoreUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + EA84F73F28BD558F00D67ABC /* TransientCoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransientCoding.swift; sourceTree = ""; }; + EA84F74028BD558F00D67ABC /* ImmutableWrapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImmutableWrapper.swift; sourceTree = ""; }; + EA84F74128BD558F00D67ABC /* OptionalWrappers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionalWrappers.swift; sourceTree = ""; }; + EA84F74228BD558F00D67ABC /* FallbackCoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FallbackCoding.swift; sourceTree = ""; }; + EA84F74328BD558F00D67ABC /* OmitCodingWrappers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OmitCodingWrappers.swift; sourceTree = ""; }; + EA84F74428BD558F00D67ABC /* StaticCodingWrappers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StaticCodingWrappers.swift; sourceTree = ""; }; + EA84F74628BD558F00D67ABC /* NilFiltering.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NilFiltering.swift; sourceTree = ""; }; + EA84F74728BD558F00D67ABC /* DateCoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateCoding.swift; sourceTree = ""; }; + EA84F74828BD558F00D67ABC /* FloatingPointCoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatingPointCoding.swift; sourceTree = ""; }; + EA84F74928BD558F00D67ABC /* BoolCoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoolCoding.swift; sourceTree = ""; }; + EA84F74A28BD558F00D67ABC /* DataCoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataCoding.swift; sourceTree = ""; }; + EA84F74B28BD558F00D67ABC /* NullEncoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NullEncoding.swift; sourceTree = ""; }; + EA84F74C28BD558F00D67ABC /* StaticCoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StaticCoding.swift; sourceTree = ""; }; + EA84F74E28BD558F00D67ABC /* EmptyDefaults.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmptyDefaults.swift; sourceTree = ""; }; + EA84F74F28BD558F00D67ABC /* CustomWrappers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomWrappers.swift; sourceTree = ""; }; + EA84F75028BD558F00D67ABC /* ConveienceAdherence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConveienceAdherence.swift; sourceTree = ""; }; EAA54A91286A47ED00B9136B /* WifiViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WifiViewController.swift; sourceTree = ""; }; EAA658142875FA5E00484A7D /* VDSFormControlsTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSFormControlsTokens.xcframework; path = ../SharedFrameworks/VDSFormControlsTokens.xcframework; sourceTree = ""; }; EACA5E5D2853DBC900CBA65B /* VDSColorTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSColorTokens.xcframework; path = ../SharedFrameworks/VDSColorTokens.xcframework; sourceTree = ""; }; @@ -189,13 +221,13 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - EACA5E5E2853DBC900CBA65B /* VDSColorTokens.xcframework in Frameworks */, EA09CDBD282C3FD800A7835F /* CoreBluetooth.framework in Frameworks */, EA33618B288B1B630071C351 /* VDS.framework in Frameworks */, - EA3361FB2891D54A0071C351 /* VDSTypographyTokens.xcframework in Frameworks */, EA5B696E2866BC1000B17D2E /* MVMCore.framework in Frameworks */, - EAA658152875FA5E00484A7D /* VDSFormControlsTokens.xcframework in Frameworks */, + EAF7F12728A15E2300B287F5 /* VDSFormControlsTokens.xcframework in Frameworks */, EA5B69702866BC1000B17D2E /* MVMCoreUI.framework in Frameworks */, + EAF7F12528A15E2300B287F5 /* VDSTypographyTokens.xcframework in Frameworks */, + EAF7F12928A15E2300B287F5 /* VDSColorTokens.xcframework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -232,6 +264,7 @@ D2B1E3F122F4A68F0065F95C /* JSONCreator */ = { isa = PBXGroup; children = ( + EA84F73D28BD558F00D67ABC /* CodableWrappers */, EA09CD9A282C3F6B00A7835F /* 5G */, D288D69B26CAE26900A5C365 /* MF */, D2B1E40922F4C9F00065F95C /* JSON */, @@ -376,6 +409,53 @@ path = Models; sourceTree = ""; }; + EA84F73D28BD558F00D67ABC /* CodableWrappers */ = { + isa = PBXGroup; + children = ( + EA84F73E28BD558F00D67ABC /* Core */, + EA84F74528BD558F00D67ABC /* StaticCoders */, + EA84F74D28BD558F00D67ABC /* Convenience */, + ); + path = CodableWrappers; + sourceTree = ""; + }; + EA84F73E28BD558F00D67ABC /* Core */ = { + isa = PBXGroup; + children = ( + EA84F73F28BD558F00D67ABC /* TransientCoding.swift */, + EA84F74028BD558F00D67ABC /* ImmutableWrapper.swift */, + EA84F74128BD558F00D67ABC /* OptionalWrappers.swift */, + EA84F74228BD558F00D67ABC /* FallbackCoding.swift */, + EA84F74328BD558F00D67ABC /* OmitCodingWrappers.swift */, + EA84F74428BD558F00D67ABC /* StaticCodingWrappers.swift */, + ); + path = Core; + sourceTree = ""; + }; + EA84F74528BD558F00D67ABC /* StaticCoders */ = { + isa = PBXGroup; + children = ( + EA84F74628BD558F00D67ABC /* NilFiltering.swift */, + EA84F74728BD558F00D67ABC /* DateCoding.swift */, + EA84F74828BD558F00D67ABC /* FloatingPointCoding.swift */, + EA84F74928BD558F00D67ABC /* BoolCoding.swift */, + EA84F74A28BD558F00D67ABC /* DataCoding.swift */, + EA84F74B28BD558F00D67ABC /* NullEncoding.swift */, + EA84F74C28BD558F00D67ABC /* StaticCoding.swift */, + ); + path = StaticCoders; + sourceTree = ""; + }; + EA84F74D28BD558F00D67ABC /* Convenience */ = { + isa = PBXGroup; + children = ( + EA84F74E28BD558F00D67ABC /* EmptyDefaults.swift */, + EA84F74F28BD558F00D67ABC /* CustomWrappers.swift */, + EA84F75028BD558F00D67ABC /* ConveienceAdherence.swift */, + ); + path = Convenience; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -476,11 +556,14 @@ buildActionMask = 2147483647; files = ( EA09CDFC282C430400A7835F /* CharacteristicModel.swift in Sources */, + EA84F75328BD558F00D67ABC /* OptionalWrappers.swift in Sources */, EA3E48A82860BB9800B524AB /* WifiWidget.swift in Sources */, D2B1E3F722F4A68F0065F95C /* DetailViewController.swift in Sources */, + EA84F76028BD558F00D67ABC /* ConveienceAdherence.swift in Sources */, EA09CDDD282C40CC00A7835F /* GMFGSpeedTestHandler.swift in Sources */, EA09CDDF282C40CC00A7835F /* GMFGRouterWifiHandler.swift in Sources */, EA09CDFD282C430400A7835F /* ServiceModel.swift in Sources */, + EA84F75F28BD558F00D67ABC /* CustomWrappers.swift in Sources */, EA09CE01282C43E800A7835F /* KeyedDecodingContainer+Decode.swift in Sources */, EA09CDDE282C40CC00A7835F /* GMFG5GSignalHandler.swift in Sources */, EAF7F0912899825D00B287F5 /* TestLabelToggle.swift in Sources */, @@ -488,7 +571,9 @@ EA09CDEB282C422900A7835F /* GMFGStorageManager.swift in Sources */, EA1B7BBD2893459E006AF0BC /* DecodableDefaults+VDS.swift in Sources */, EA09CE05282C45C200A7835F /* BluetoothPairBehavior.swift in Sources */, + EA84F75B28BD558F00D67ABC /* DataCoding.swift in Sources */, EAA54A92286A47ED00B9136B /* WifiViewController.swift in Sources */, + EA84F75228BD558F00D67ABC /* ImmutableWrapper.swift in Sources */, EA09CDFA282C430400A7835F /* BluetoothConfigModel.swift in Sources */, D27564CA25939E91003CA713 /* LinksModel.swift in Sources */, D2B1E3F522F4A68F0065F95C /* MasterViewController.swift in Sources */, @@ -496,6 +581,7 @@ EA09CDEF282C429800A7835F /* GMFGTestScreenData.swift in Sources */, EA09CDED282C423F00A7835F /* GMFGLocationManager.swift in Sources */, EA09CE03282C44A100A7835F /* MFFGHSUtility.swift in Sources */, + EA84F75528BD558F00D67ABC /* OmitCodingWrappers.swift in Sources */, EA09CDF9282C430400A7835F /* BluetoothPairableProtocol.swift in Sources */, D27564B72590FADB003CA713 /* ListDeviceRightVariableCaret.swift in Sources */, D2431DEB25E93A4F001C7AAC /* buttimag.swift in Sources */, @@ -509,22 +595,32 @@ D27564C925939E91003CA713 /* Links.swift in Sources */, EA09CDE6282C416C00A7835F /* BluetoothDebuggableProtocol.swift in Sources */, EA3E48A62860BB4D00B524AB /* WifiWidgetModel.swift in Sources */, + EA84F75628BD558F00D67ABC /* StaticCodingWrappers.swift in Sources */, EA09CDD2282C40CC00A7835F /* GMFGBluetoothPair.swift in Sources */, EA09CDE9282C416C00A7835F /* BluetoothDebuggerView.swift in Sources */, D2FC4FAE25897ACB00061EA4 /* OrderTrackerModel.swift in Sources */, EA3362342891F5AB0071C351 /* TestToggleModel.swift in Sources */, D21B3A27259B93ED001483DC /* SelfSizingCollectionView.swift in Sources */, + EA84F75A28BD558F00D67ABC /* BoolCoding.swift in Sources */, EA09CDD9282C40CC00A7835F /* GMFG5GCBandSignalHandler.swift in Sources */, EA09CDF8282C430400A7835F /* BluetoothPairingProtocol.swift in Sources */, + EA84F75128BD558F00D67ABC /* TransientCoding.swift in Sources */, D2B1E3F322F4A68F0065F95C /* AppDelegate.swift in Sources */, EA09CDDA282C40CC00A7835F /* GMFGOperationHandler.swift in Sources */, + EA84F75D28BD558F00D67ABC /* StaticCoding.swift in Sources */, EA09CDE7282C416C00A7835F /* MulticastDelegate.swift in Sources */, + EA84F75828BD558F00D67ABC /* DateCoding.swift in Sources */, + EA84F75E28BD558F00D67ABC /* EmptyDefaults.swift in Sources */, + EA84F75728BD558F00D67ABC /* NilFiltering.swift in Sources */, D29C557825BF1F340082E7D6 /* JSONCreatorActionHandler.swift in Sources */, EA09CDDB282C40CC00A7835F /* GMFGPublicInternetAccessHandler.swift in Sources */, + EA84F75C28BD558F00D67ABC /* NullEncoding.swift in Sources */, D2FC4FAD25897ACB00061EA4 /* StepModel.swift in Sources */, EA09CDFF282C437C00A7835F /* MFFGHSAnalyticsProtocol.swift in Sources */, EA09CDE8282C416C00A7835F /* BluetoothDebugger.swift in Sources */, D2FC4FAF25897ACB00061EA4 /* Step.swift in Sources */, + EA84F75928BD558F00D67ABC /* FloatingPointCoding.swift in Sources */, + EA84F75428BD558F00D67ABC /* FallbackCoding.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/JSONCreator_iOS/JSONCreator.xcodeproj/xcshareddata/xcschemes/JSONCreator.xcscheme b/JSONCreator_iOS/JSONCreator.xcodeproj/xcshareddata/xcschemes/JSONCreator.xcscheme new file mode 100644 index 0000000..a178879 --- /dev/null +++ b/JSONCreator_iOS/JSONCreator.xcodeproj/xcshareddata/xcschemes/JSONCreator.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/JSONCreator_iOS/JSONCreator/AppDelegate.swift b/JSONCreator_iOS/JSONCreator/AppDelegate.swift index 084c6cc..3947db5 100644 --- a/JSONCreator_iOS/JSONCreator/AppDelegate.swift +++ b/JSONCreator_iOS/JSONCreator/AppDelegate.swift @@ -129,12 +129,22 @@ extension AppDelegate: MVMCoreGlobalTopAlertDelegateProtocol { extension AppDelegate { func register(){ + ModelRegistry.register(TestModel.self) ModelRegistry.register(handler: TestLabelToggle.self, for: TestLabelToggleModel.self) ModelRegistry.register(handler: TestToggle.self, for: TestToggleModel.self) ModelRegistry.register(handler: TextEntryField.self, for: TextEntryField64Model.self) ModelRegistry.register(handler: EmailVerifyField.self, for: EmailVerifyModel.self) ModelRegistry.register(handler: WifiWidget.self, for: WifiWidgetModel.self) ModelRegistry.register(handler: ToggleWifiActionHandler.self, for: ToggleWifiActionModel.self) + + guard let model = try? TestModel.decode(fileName: "/JSON/Samples/Wifi/TestModel") else { return } + + print(model.action.actionType) + + if let jsonstring = model.toJSONString() { + print(jsonstring) + } + } } @@ -289,3 +299,235 @@ extension String { return String(data: data, encoding: .utf8) } } + + +struct TestModel: MoleculeModelProtocol { + var backgroundColor: MVMCoreUI.Color? + static var identifier: String = "testModel" + var text: String = "This is a test" + @Model> var action: ActionModelProtocol + @OptionalModels> var actions: [ActionModelProtocol]? +} + +//4 class +//2 optional (single/array) +//2 non-optional (single/array) + +@propertyWrapper +public struct ModelCodable { + public var wrappedValue: ModelType + public init(wrappedValue: ModelType) { + self.wrappedValue = wrappedValue + } +} + +extension ModelCodable: Codable { + public init(from decoder: Decoder) throws { + wrappedValue = try decoder.decodeModel() + } + + public func encode(to encoder: Encoder) throws { + if let model = wrappedValue as? ModelProtocol { + try model.encode(to: encoder) + } + } +} + +@propertyWrapper +public struct ModelsCodable { + public var wrappedValue: [ModelType] + public init(wrappedValue: [ModelType]) { + self.wrappedValue = wrappedValue + } +} + +extension ModelsCodable: Codable { + public init(from decoder: Decoder) throws { + wrappedValue = try decoder.decodeModels() + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.unkeyedContainer() + for value in wrappedValue { + if let model = value as? ModelProtocol { + try container.encode(model) + } + } + } +} + +@propertyWrapper +public struct OptionalModelCodable { + public var wrappedValue: ModelType? + public init(wrappedValue: ModelType?) { + self.wrappedValue = wrappedValue + } +} + +extension OptionalModelCodable: Codable { + public init(from decoder: Decoder) throws { + wrappedValue = try? decoder.decodeModel() + } + + public func encode(to encoder: Encoder) throws { + if let model = wrappedValue as? ModelProtocol { + try model.encode(to: encoder) + } + } +} + +@propertyWrapper +public struct OptionalModelsCodable { + public var wrappedValue: [ModelType]? + public init(wrappedValue: [ModelType]?) { + self.wrappedValue = wrappedValue + } +} + +extension OptionalModelsCodable: Codable { + public init(from decoder: Decoder) throws { + wrappedValue = try? decoder.decodeModels() + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.unkeyedContainer() + guard let wrappedValue else { return } + for value in wrappedValue { + if let model = value as? ModelProtocol { + try container.encode(model) + } + } + } +} + +///crap + +public protocol WrappedModel: Codable { + associatedtype ModelType + var wrappedModel: ModelType { get set } +} + +public protocol WrappedModels: Codable { + associatedtype ModelType + var wrappedModels: [ModelType] { get set } +} + +public struct AnyModel: WrappedModel { + public var wrappedModel: ModelType + + public init(from decoder: Decoder) throws { + wrappedModel = try decoder.decodeModel() + } + + public func encode(to encoder: Encoder) throws { + if let model = wrappedModel as? ModelProtocol { + try model.encode(to: encoder) + } + } +} + +public struct AnyModels: WrappedModels { + public var wrappedModels: [ModelType] + + public init(from decoder: Decoder) throws { + var container = try decoder.unkeyedContainer() + wrappedModels = try container.decodeModelsIfPresent() ?? [] + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.unkeyedContainer() + for value in wrappedModels { + if let model = value as? ModelProtocol { + try container.encode(model) + } + } + } +} + +@propertyWrapper +public struct OptionalModel { + public var wrappedValue: ModelType.ModelType? { modelType?.wrappedModel} + private var modelType: ModelType? + public init() {} +} + +extension OptionalModel: Codable { + public init(from decoder: Decoder) throws { + modelType = try? ModelType.init(from: decoder) + } + + public func encode(to encoder: Encoder) throws { + try modelType?.encode(to: encoder) + } +} + + +@propertyWrapper +public struct OptionalModels { + public var wrappedValue: [ModelType.ModelType]? { modelType?.wrappedModels} + private var modelType: ModelType? + public init() {} +} + +extension OptionalModels: Codable { + public init(from decoder: Decoder) throws { + modelType = try? ModelType.init(from: decoder) + } + + public func encode(to encoder: Encoder) throws { + try modelType?.encode(to: encoder) + } +} + +@propertyWrapper +public struct Model { + public var wrappedValue: ModelType.ModelType { modelType.wrappedModel } + private var modelType: ModelType! + public init() { } +} + +extension Model: Codable { + public init(from decoder: Decoder) throws { + modelType = try ModelType.init(from: decoder) + } + + public func encode(to encoder: Encoder) throws { + try modelType.encode(to: encoder) + } +} + +@propertyWrapper +public struct Models { + public var wrappedValue: [ModelType.ModelType] { modelType.wrappedModels } + private var modelType: ModelType! + public init() { } +} + +extension Models: Codable { + public init(from decoder: Decoder) throws { + modelType = try ModelType.init(from: decoder) + } + + public func encode(to encoder: Encoder) throws { + try modelType.encode(to: encoder) + } +} + +extension Decoder { + public func decodeModel() throws -> T { + let container = try container(keyedBy: AnyCodingKey.self) + let typeCodingKey = try ModelRegistry.getCodingKey(for: T.self) + let identifier = try container.decode(String.self, forKey: typeCodingKey) + guard let type = ModelRegistry.getType(for: identifier, with: T.self), + let model = try type.init(from: self) as? T else { + throw ModelRegistry.Error.decoderError + } + return model + } + + public func decodeModels() throws -> [T] { + var container = try unkeyedContainer() + return try container.decodeModelsIfPresent() ?? [] + } +} + diff --git a/JSONCreator_iOS/JSONCreator/CodableWrappers/Convenience/ConveienceAdherence.swift b/JSONCreator_iOS/JSONCreator/CodableWrappers/Convenience/ConveienceAdherence.swift new file mode 100644 index 0000000..2d80f49 --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/CodableWrappers/Convenience/ConveienceAdherence.swift @@ -0,0 +1,20 @@ +// +// ConveienceAdherence.swift +// +// +// Created by PJ Fechner on 7/7/20. +// + +import Foundation + +//MARK: ExpressibleByNilLiteral Extensions + +// This make propertyWrappers adhere to OptionalCodingWrapper when wrapped value is Optional + +extension TransientEncoding: OptionalEncodingWrapper where T: ExpressibleByNilLiteral { } +extension TransientDecoding: OptionalDecodingWrapper where T: ExpressibleByNilLiteral { } +extension TransientCoding: OptionalCodingWrapper where T: ExpressibleByNilLiteral { } + +extension DecodingUses: OptionalDecodingWrapper where CustomDecoder.DecodedType: ExpressibleByNilLiteral { } +extension EncodingUses: OptionalEncodingWrapper where CustomEncoder.OriginalType: ExpressibleByNilLiteral { } +extension CodingUses: OptionalCodingWrapper where CustomEncoder.OriginalType: ExpressibleByNilLiteral { } diff --git a/JSONCreator_iOS/JSONCreator/CodableWrappers/Convenience/CustomWrappers.swift b/JSONCreator_iOS/JSONCreator/CodableWrappers/Convenience/CustomWrappers.swift new file mode 100644 index 0000000..2f1d21c --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/CodableWrappers/Convenience/CustomWrappers.swift @@ -0,0 +1,164 @@ +// +// CustomWrappers.swift +// +// +// Created by PJ Fechner on 10/13/19. +// Copyright © 2019 PJ Fechner. All rights reserved. + +import Foundation + +//MARK: - Non-Conforming Floating Point + +//MARK: Float + +/// Use the values in `ValueProvider` when encoding this immutable Property with non-conforming numbers, also known as IEEE 754 exceptional values. +public typealias NonConformingFloatEncoding = EncodingUses> +/// Use the values in `ValueProvider` when decoding this immutable Property with non-conforming numbers, also known as IEEE 754 exceptional values. +public typealias NonConformingFloatDecoding = DecodingUses> +/// Use the values in `ValueProvider` when (en/de)coding this immutable Property with non-conforming numbers, also known as IEEE 754 exceptional values. +public typealias NonConformingFloatCoding = CodingUses> +/// Use the values in `ValueProvider` when (en/de)coding this immutable Optional Property with non-conforming numbers, also known as IEEE 754 exceptional values. + + +//MARK: Double + +/// Use the values in `ValueProvider` when encoding this immutable Property with non-conforming numbers, also known as IEEE 754 exceptional values. +public typealias NonConformingDoubleEncoding = EncodingUses> +/// Use the values in `ValueProvider` when decoding this immutable Property with non-conforming numbers, also known as IEEE 754 exceptional values. +public typealias NonConformingDoubleDecoding = DecodingUses> +/// Use the values in `ValueProvider` when (en/de)coding this immutable Property with non-conforming numbers, also known as IEEE 754 exceptional values. +public typealias NonConformingDoubleCoding = CodingUses> + + +//MARK: - Data + +//MARK: Base64 + +/// Encode this immutable `Data` Property as a Base64 encoded String +public typealias Base64Encoding = EncodingUses +/// Decode this immutable `Data` Property as a Base64 encoded String +public typealias Base64Decoding = DecodingUses +/// (En/De)code this immutable `Data` Property as a Base64 encoded String +public typealias Base64Coding = CodingUses + + +//MARK: - Date + +//MARK: millisecondsSince1970 + +/// Encode this immutable `Date` Property using millisecondsSince1970 +public typealias MillisecondsSince1970DateEncoding = EncodingUses +/// Decode this immutable `Date` Property using millisecondsSince1970 +public typealias MillisecondsSince1970DateDecoding = DecodingUses +/// (En/De)code this immutable `Date` Property using millisecondsSince1970 +public typealias MillisecondsSince1970DateCoding = CodingUses + + +//MARK: secondsSince1970 + +/// Encode this immutable `Date` Property using secondsSince1970 +public typealias SecondsSince1970DateEncoding = EncodingUses +/// Decode this immutable `Date` Property using secondsSince1970 +public typealias SecondsSince1970DateDecoding = DecodingUses +/// (En/De)code this immutable `Date` Property using secondsSince1970 +public typealias SecondsSince1970DateCoding = CodingUses + +//MARK: ISO8601Date + +/// Encode this immutable `Date` Property using a ISO8601DateFormatter with `formatOptions` set to `.withInternetDateTime` +@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) +public typealias ISO8601DateEncoding = EncodingUses +/// Decode this immutable `Date` Property using a ISO8601DateFormatter with `formatOptions` set to `.withInternetDateTime` +@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) +public typealias ISO8601DateDecoding = DecodingUses +/// (En/De) this immutable `Date` Property using a ISO8601DateFormatter with `formatOptions` set to `.withInternetDateTime` +@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) +public typealias ISO8601DateCoding = CodingUses + + +//MARK: CustomISO8601Date + +/// Encode this immutable `Date` Property using the passed formatter +@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) +public typealias ISO8601DateFormatterEncoding = EncodingUses +@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) +/// Decode this immutable `Date` Property using the passed formatter +@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) +public typealias ISO8601DateFormatterDecoding = DecodingUses +/// (En/De)code this immutable `Date` Property using the passed formatter +@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) +public typealias ISO8601DateFormatterCoding = CodingUses + + +//MARK: DateFormatter + +/// Encode this immutable `Date` Property using the passed formatter +public typealias DateFormatterEncoding = EncodingUses +/// Decode this immutable `Date` Property using the passed formatter +public typealias DateFormatterDecoding = DecodingUses +/// (En/De)code this immutable `Date` Property using the passed formatter +public typealias DateFormatterCoding = CodingUses + + +//MARK: - Bool + +//MARK: NonConformingBool + +/// Encode this immutable `Bool` Property using the passed NonConformingBoolValueProvider +public typealias NonConformingBoolEncoding = EncodingUses> +/// Decode this immutable `Bool` Property using the passed NonConformingBoolValueProvider +public typealias NonConformingBoolDecoding = DecodingUses> +/// (En/De)code this immutable `Bool` Property using the passed NonConformingBoolValueProvider +public typealias NonConformingBoolCoding = CodingUses> + + +//MARK: BoolAsInteger + +/// Convenience typealias +public typealias BoolAsIntegerStaticCoder = NonConformingBoolStaticCoder> + +/// Encode this immutable `Bool` Property as the passed Integer Type using 1 as true and 0 as false +public typealias BoolAsIntegerEncoding = EncodingUses> +/// Decode this immutable `Bool` Property as passed Integer Type using 1 as true and 0 as false +public typealias BoolFromIntegerDecoding = DecodingUses> +/// (En/De)code this immutable `Bool` Property as passed Integer Type using 1 as true and 0 as false +public typealias BoolAsIntegerCoding = CodingUses> + + +//MARK: BoolAsInt + +/// Encode this immutable `Bool` Property as an Int using 1 as true and 0 as false +public typealias BoolAsIntEncoding = BoolAsIntegerEncoding +/// Decode this immutable `Bool` Property as an Int using 1 as true and 0 as false +public typealias BoolFromIntDecoding = BoolFromIntegerDecoding +/// (En/De)code this immutable `Bool` Property as an Int using 1 as true and 0 as false +public typealias BoolAsIntCoding = BoolAsIntegerCoding + + +/// Convenience typealias +public typealias BoolAsStringStaticCoder = NonConformingBoolStaticCoder + +/// Encode this immutable `Bool` Property as a String using "true" for true and "false" for false +public typealias BoolAsStringEncoding = EncodingUses +/// Decode this immutable `Bool` Property as a String using "true" for true and "false" for false +public typealias BoolFromStringDecoding = DecodingUses +/// (En/De)code this immutable `Bool` Property a String using "true" for true and "false" for false +public typealias BoolAsStringCoding = CodingUses + + +//MARK: NilFiltering + +/// Filters any nil values when decoding +public typealias LossyArrayDecoding = DecodingUses> + +/// Filters any nil values when decoding +public typealias LossySetDecoding = DecodingUses> + +/// Filters any nil values when decoding +public typealias LossyDictionaryDecoding = DecodingUses> + + +//MARK: NullEncoding + +/// Encodes a nil value in a singleValueContainer using `encodeNil` rather than it being omitted. +public typealias EncodeNulls = EncodingUses> diff --git a/JSONCreator_iOS/JSONCreator/CodableWrappers/Convenience/EmptyDefaults.swift b/JSONCreator_iOS/JSONCreator/CodableWrappers/Convenience/EmptyDefaults.swift new file mode 100644 index 0000000..f92ab9d --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/CodableWrappers/Convenience/EmptyDefaults.swift @@ -0,0 +1,106 @@ +// +// EmptyDefaults.swift +// +// +// Created by PJ Fechner on 7/10/20. +// + +import Foundation +#if canImport(UIKit) +import UIKit +#endif + +// MARK: - Convenience Defaults + +/// Empty FallbackValueProvider for Bool: false +public struct EmptyBool: FallbackValueProvider { + public static var defaultValue: Bool { false } +} + +/// Empty FallbackValueProvider for String: "" +public struct EmptyString: FallbackValueProvider { + public static var defaultValue: String { "" } +} + +/// Empty FallbackValueProvider for Int: 0 +public struct EmptyInt: FallbackValueProvider { + public static var defaultValue: Int { 0 } +} +/// Empty FallbackValueProvider for Int16: 0 +public struct EmptyInt16: FallbackValueProvider { + public static var defaultValue: Int16 { 0 } +} +/// Empty FallbackValueProvider for Int32: 0 +public struct EmptyInt32: FallbackValueProvider { + public static var defaultValue: Int32 { 0 } +} +/// Empty FallbackValueProvider for Int64: 0 +public struct EmptyInt64: FallbackValueProvider { + public static var defaultValue: Int64 { 0 } +} +/// Empty FallbackValueProvider for Int8: 0 +public struct EmptyInt8: FallbackValueProvider { + public static var defaultValue: Int8 { 0 } +} +/// Empty FallbackValueProvider for UInt: 0 +public struct EmptyUInt: FallbackValueProvider { + public static var defaultValue: UInt { 0 } +} +/// Empty FallbackValueProvider for UInt16: 0 +public struct EmptyUInt16: FallbackValueProvider { + public static var defaultValue: UInt16 { 0 } +} +/// Empty FallbackValueProvider for UInt32: 0 +public struct EmptyUInt32: FallbackValueProvider { + public static var defaultValue: UInt32 { 0 } +} +/// Empty FallbackValueProvider for UInt64: 0 +public struct EmptyUInt64: FallbackValueProvider { + public static var defaultValue: UInt64 { 0 } +} +/// Empty FallbackValueProvider for UInt8: 0 +public struct EmptyUInt8: FallbackValueProvider { + public static var defaultValue: UInt8 { 0 } +} + +#if canImport(UIKit) + +/// Empty FallbackValueProvider for CGFloat: 0 +public struct EmptyCGFloat: FallbackValueProvider { + public static var defaultValue: CGFloat { 0 } +} +#endif + +/// Empty FallbackValueProvider for Double: 0 +public struct EmptyDouble: FallbackValueProvider { + public static var defaultValue: Double { 0 } +} +/// Empty FallbackValueProvider for Float: 0 +public struct EmptyFloat: FallbackValueProvider { + public static var defaultValue: Float { 0 } +} + +// Float16 is only available on ARM Macs. +#if swift(>=5.4) && !((os(macOS) || targetEnvironment(macCatalyst)) && arch(x86_64)) +/// Empty FallbackValueProvider for Float16: 0 +@available(iOS 14, macOS 11, tvOS 14.0, watchOS 7.0, macCatalyst 14.5, *) +public struct EmptyFloat16: FallbackValueProvider { + @available(iOS 14, macOS 11, tvOS 14.0, watchOS 7.0, macCatalyst 14.5, *) + public static var defaultValue: Float16 { 0 } +} +#endif + +/// Empty FallbackValueProvider for Array: [] +public struct EmptyArray: FallbackValueProvider { + public static var defaultValue: Array { [] } +} +/// Empty FallbackValueProvider for Dictionary: [:] +public struct EmptyDictionary: FallbackValueProvider { + public static var defaultValue: Dictionary { [:] } +} +/// Empty FallbackValueProvider for Set: [] +public struct EmptySet: FallbackValueProvider { + public static var defaultValue: Set { [] } +} + + diff --git a/JSONCreator_iOS/JSONCreator/CodableWrappers/Core/FallbackCoding.swift b/JSONCreator_iOS/JSONCreator/CodableWrappers/Core/FallbackCoding.swift new file mode 100644 index 0000000..acab8fe --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/CodableWrappers/Core/FallbackCoding.swift @@ -0,0 +1,124 @@ +// +// FallbackCoding.swift +// +// +// Created by PJ Fechner on 7/7/20. +// + +import Foundation + +//MARK: - FallbackWrappers + +//MARK: Protocols + +/// Contract for providing a default value of a Type +public protocol FallbackValueProvider { + associatedtype ValueType + static var defaultValue: ValueType { get } +} + +/// Contract for an Encoding Fallback Wrapper. Used to unify logic for Encodable/Codable version +public protocol FallbackEncodingWrapper: Encodable { + associatedtype ValueProvider: FallbackValueProvider where ValueProvider.ValueType: Encodable + var wrappedValue: ValueProvider.ValueType? { get } +} + +extension FallbackEncodingWrapper { + public func encode(to encoder: Encoder) throws { + + guard let wrappedValue = wrappedValue else { + try ValueProvider.defaultValue.encode(to: encoder) + return + } + try wrappedValue.encode(to: encoder) + } +} + +/// Contract for an Decoding Fallback Wrapper. Used to unify logic for Decodable/Codable version +public protocol FallbackDecodingWrapper: Decodable { + associatedtype ValueProvider: FallbackValueProvider where ValueProvider.ValueType: Decodable + init(wrappedValue: ValueProvider.ValueType) +} + +extension FallbackDecodingWrapper { + public init(from decoder: Decoder) throws { + let foundValue = try? ValueProvider.ValueType(from: decoder) + // The second half of this should never run due to the KeyedDecodingContainer.decode extension, but just in case, possible when a value is "null" + self.init(wrappedValue: foundValue ?? ValueProvider.defaultValue) + } +} + +public typealias FallbackCodingWrapper = FallbackEncodingWrapper & FallbackDecodingWrapper + +//MARK: Wrappers + + +/// If `wrappedValue` is nil encodes the `ValueProvider.defaultValue` value. +/// - Note: WrappedType must be Optional or encoding is irrelevant. Use`FallbackDecoding` for decoding-only cases +@propertyWrapper +public struct FallbackEncoding: FallbackEncodingWrapper where ValueProvider.ValueType: Encodable { + + public var wrappedValue: ValueProvider.ValueType? + + public init(wrappedValue: ValueProvider.ValueType?) { + self.wrappedValue = wrappedValue + } +} + +/// If a value is not found while decoding, will be initialized with the `ValueProvider.defaultValue` value. +@propertyWrapper +public struct FallbackDecoding: FallbackDecodingWrapper where ValueProvider.ValueType: Decodable { + + public var wrappedValue: ValueProvider.ValueType + + public init(wrappedValue: ValueProvider.ValueType) { + self.wrappedValue = wrappedValue + } +} + +/// Encoding: If `wrappedValue` is nil encodes the `ValueProvider.defaultValue` value. +/// Decoding: If a value is not found, will be initialized with the `ValueProvider.defaultValue` value. +/// - Note: WrappedType must be Optional or encoding is irrelevant. `FallbackDecoding` is available for decoding-only cases +@propertyWrapper +public struct FallbackCoding: FallbackCodingWrapper, Codable where ValueProvider.ValueType: Codable { + + public var wrappedValue: ValueProvider.ValueType? + + public init(wrappedValue: ValueProvider.ValueType?) { + self.wrappedValue = wrappedValue + } + + // Need this in order to work with `EmptyFallbackDecodableWrapper` + public init(wrappedValue: ValueProvider.ValueType) { + self.wrappedValue = wrappedValue + } +} + +extension KeyedDecodingContainer { + // This is used to override the default decoding behavior for `EmptyFallbackDecodableWrapper` to allow a value to avoid a missing key Error + public func decode(_ type: T.Type, forKey key: KeyedDecodingContainer.Key) throws -> T where T: FallbackDecodingWrapper { + return try decodeIfPresent(T.self, forKey: key) ?? T(wrappedValue: T.ValueProvider.defaultValue) + } +} + +//MARK: Enable Customizing one direction + +/// Ensures there isn't an extra level added +extension FallbackEncoding: Decodable, TransientDecodable where ValueProvider.ValueType: Decodable { } +/// Ensures there isn't an extra level added +extension FallbackDecoding: Encodable, TransientEncodable where ValueProvider.ValueType: Encodable { } + + +//MARK: Conditional Equatable Conformance + +extension FallbackEncoding: Equatable where ValueProvider.ValueType: Equatable {} +extension FallbackDecoding: Equatable where ValueProvider.ValueType: Equatable {} +extension FallbackCoding: Equatable where ValueProvider.ValueType: Equatable {} + +//MARK: Conditional Hashable Conformance + +extension FallbackEncoding: Hashable where ValueProvider.ValueType: Hashable {} +extension FallbackDecoding: Hashable where ValueProvider.ValueType: Hashable {} +extension FallbackCoding: Hashable where ValueProvider.ValueType: Hashable {} + + diff --git a/JSONCreator_iOS/JSONCreator/CodableWrappers/Core/ImmutableWrapper.swift b/JSONCreator_iOS/JSONCreator/CodableWrappers/Core/ImmutableWrapper.swift new file mode 100644 index 0000000..d056854 --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/CodableWrappers/Core/ImmutableWrapper.swift @@ -0,0 +1,71 @@ +// +// ImmutableWrapper.swift +// +// +// Created by PJ Fechner on 7/7/20. +// + +import Foundation + +//MARK: - Immutable Wrapper + +public protocol AnyImmutableWrapper { + associatedtype T + var wrappedValue: T { get } + init(wrappedValue: T) +} + +/// Wraps the type to make it Immutable, (en/de)coding is transient and won't affect it's wrapped Type +@propertyWrapper +public struct Immutable: AnyImmutableWrapper { + public let wrappedValue: T + + public init(wrappedValue: T) { + self.wrappedValue = wrappedValue + } +} + + +//MARK: - Conditional Equatable Conformances + + +// TransientCodable will handle the (en/de)coding here when needed without adding additional layers +extension Immutable: Encodable, TransientEncodable where T: Encodable { } +extension Immutable: Decodable, TransientDecodable where T: Decodable { } +extension Immutable: TransientCodable where T: Codable { } + +extension Immutable: Equatable where T: Equatable { } +extension Immutable: Hashable where T: Hashable { } + +// MARK: - Handling Immutable and Optional interaction + +extension Immutable: OptionalDecodingWrapper where T: Decodable & ExpressibleByNilLiteral { } +extension Immutable: OptionalEncodingWrapper where T: Encodable & ExpressibleByNilLiteral { } + +extension KeyedDecodingContainer { + // This is used to override the default decoding behavior for OptionalWrapper to avoid a missing key Error + public func decode(_ type: T.Type, forKey key: KeyedDecodingContainer.Key) throws -> T where T : Decodable, T: AnyImmutableWrapper, T.T: OptionalDecodingWrapper { + return try decodeIfPresent(T.self, forKey: key) ?? T(wrappedValue: .init(wrappedValue: nil)) + } +} + +extension KeyedEncodingContainer { + // Used to make make sure OptionalCodingWrappers encode no value when it's wrappedValue is nil. + public mutating func encode(_ value: T, forKey key: KeyedEncodingContainer.Key) throws where T: Encodable, T: AnyImmutableWrapper, T.T: OptionalEncodingWrapper { + + if case Optional.none = value.wrappedValue.wrappedValue as Any { + return + } else { + try encodeIfPresent(value, forKey: key) + } + } +} + +// MARK: - Handling interaction with FallbackDecodingWrapper + +extension KeyedDecodingContainer { + // This is used to override the default decoding behavior for `EmptyFallbackDecodableWrapper` to allow a value to avoid a missing key Error + public func decode(_ type: T.Type, forKey key: KeyedDecodingContainer.Key) throws -> T where T : Decodable, T: AnyImmutableWrapper, T.T: FallbackDecodingWrapper { + return try decodeIfPresent(T.self, forKey: key) ?? T(wrappedValue: T.T(wrappedValue: T.T.ValueProvider.defaultValue)) + } +} diff --git a/JSONCreator_iOS/JSONCreator/CodableWrappers/Core/OmitCodingWrappers.swift b/JSONCreator_iOS/JSONCreator/CodableWrappers/Core/OmitCodingWrappers.swift new file mode 100644 index 0000000..9410da2 --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/CodableWrappers/Core/OmitCodingWrappers.swift @@ -0,0 +1,103 @@ +// +// OmitCodingWrappers.swift +// +// +// Created by PJ Fechner on 7/7/20. +// + +import Foundation + +//MARK: - OmitWrappers + + +/// Add this to an Optional Property to not included it when Encoding or Decoding +@propertyWrapper +public struct OmitEncoding: OmitableFromEncoding { + + public var wrappedValue: WrappedType? + public init(wrappedValue: WrappedType?) { + self.wrappedValue = wrappedValue + } +} + +/// Add this to an Optional Property to not included it when Encoding or Decoding +@propertyWrapper +public struct OmitDecoding: OmitableFromDecoding { + + public var wrappedValue: WrappedType? + public init(wrappedValue: WrappedType?) { + self.wrappedValue = wrappedValue + } +} + +/// Add this to an Optional Property to not included it when Encoding or Decoding +@propertyWrapper +public struct OmitCoding: OmitableFromCoding { + + public var wrappedValue: WrappedType? + public init(wrappedValue: WrappedType?) { + self.wrappedValue = wrappedValue + } +} + + +//MARK: - OmitCoding protocols + +/// Protocol to indicate instances should be skipped when encoding +public protocol OmitableFromEncoding: Encodable { } + +extension KeyedDecodingContainer { + // This is used to override the default decoding behavior for OptionalCodingWrapper to allow a value to avoid a missing key Error + public func decode(_ type: T.Type, forKey key: KeyedDecodingContainer.Key) throws -> T where T: OmitableFromDecoding { + return try decodeIfPresent(T.self, forKey: key) ?? T(wrappedValue: nil) + } +} + +extension KeyedEncodingContainer { + // Used to make make sure OmitableFromEncoding never encodes a value + public mutating func encode(_ value: T, forKey key: KeyedEncodingContainer.Key) throws where T: OmitableFromEncoding { + return + } +} + +extension OmitableFromEncoding { + // This shouldn't ever be called since KeyedEncodingContainer should skip it due to the included extension + public func encode(to encoder: Encoder) throws { return } +} + +/// Protocol to indicate instances should be skipped when decoding +public protocol OmitableFromDecoding: Decodable { + associatedtype WrappedType: ExpressibleByNilLiteral + init(wrappedValue: WrappedType) +} + +extension OmitableFromDecoding { + /// Inits the value with nil + public init(from decoder: Decoder) throws { + self.init(wrappedValue: nil) + } +} + +/// Combination of OmitableFromEncoding and OmitableFromDecoding +typealias OmitableFromCoding = OmitableFromEncoding & OmitableFromDecoding + +/// This makes sure the decoding isn't altered by adding this Wrapper +extension OmitEncoding: Decodable, TransientDecodable where WrappedType: Decodable { } + +/// This makes sure the encoding isn't altered by adding this Wrapper +extension OmitDecoding: Encodable, TransientEncodable where WrappedType: Encodable { } + + + +//MARK: - Conditional Equatable Conformance + +extension OmitEncoding: Equatable where WrappedType: Equatable { } +extension OmitDecoding: Equatable where WrappedType: Equatable { } +extension OmitCoding: Equatable where WrappedType: Equatable { } + +//MARK: - Conditional Hashable Conformance + +extension OmitEncoding: Hashable where WrappedType: Hashable { } +extension OmitDecoding: Hashable where WrappedType: Hashable { } +extension OmitCoding: Hashable where WrappedType: Hashable { } + diff --git a/JSONCreator_iOS/JSONCreator/CodableWrappers/Core/OptionalWrappers.swift b/JSONCreator_iOS/JSONCreator/CodableWrappers/Core/OptionalWrappers.swift new file mode 100644 index 0000000..e9d989d --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/CodableWrappers/Core/OptionalWrappers.swift @@ -0,0 +1,128 @@ +// +// OptionalWrappers.swift +// +// Copyright © 2019 PJ Fechner. All rights reserved. + +import Foundation + +//MARK: - OptionalWrapper + +public protocol OptionalEncodingWrapper { + associatedtype WrappedType: ExpressibleByNilLiteral + var wrappedValue: WrappedType { get } +} + +public protocol OptionalDecodingWrapper { + associatedtype WrappedType: ExpressibleByNilLiteral + init(wrappedValue: WrappedType) +} +/// Protocol for a PropertyWrapper to properly handle Coding when the wrappedValue is Optional +public typealias OptionalCodingWrapper = OptionalEncodingWrapper & OptionalDecodingWrapper + + +extension KeyedDecodingContainer { + // This is used to override the default decoding behavior for OptionalWrapper to avoid a missing key Error + public func decode(_ type: T.Type, forKey key: KeyedDecodingContainer.Key) throws -> T where T : Decodable, T: OptionalDecodingWrapper { + return try decodeIfPresent(T.self, forKey: key) ?? T(wrappedValue: nil) + } +} + +extension KeyedEncodingContainer { + // Used to make make sure OptionalCodingWrappers encode no value when it's wrappedValue is nil. + public mutating func encode(_ value: T, forKey key: KeyedEncodingContainer.Key) throws where T: Encodable, T: OptionalEncodingWrapper { + + if case Optional.none = value.wrappedValue as Any { + return + } + + try encodeIfPresent(value, forKey: key) + } +} + +//MARK: - OptionalCoding and Wrapper + +/// Contract for a Type that wraps a StaticEncoder and makes it usable when the WrappedType is Optional +public protocol OptionalEncodable: Encodable, OptionalEncodingWrapper where WrappedType == EncoderWrapper.CustomEncoder.OriginalType? { + associatedtype EncoderWrapper: StaticEncoderWrapper +} + +public extension OptionalEncodable { + // Encodes the wrappedValue using the CustomEncoder if the value exists + func encode(to encoder: Encoder) throws { + if let wrappedValue = wrappedValue { + try EncoderWrapper.CustomEncoder.encode(value: wrappedValue, to: encoder) + } + } +} + +/// Contract for a Type that wraps a StaticDecoder and makes it usable the WrappedType is Optional +public protocol OptionalDecodable: Decodable, OptionalDecodingWrapper where WrappedType == DecoderWrapper.CustomDecoder.DecodedType? { + associatedtype DecoderWrapper: StaticDecoderWrapper +} + +extension OptionalDecodable { + // Decodes using the DecoderWrapper's CustomDecoder + // This should never be called due to KeyedDecodingContainer.decode overriding it. + public init(from decoder: Decoder) throws { + self.init(wrappedValue: try? DecoderWrapper.CustomDecoder.decode(from: decoder)) + } +} + +/// Combination of OptionalStaticDecoding and OptionalStaticEncoding +public typealias OptionalCodable = OptionalDecodable & OptionalEncodable + +/// Wraps `StaticEncoderWrapper` generically to allow the wrapped property to be Optional +@propertyWrapper +public struct OptionalEncoding: OptionalEncodable { + public typealias EncoderWrapper = CustomDecoderWrapper + + public var wrappedValue: CustomDecoderWrapper.CustomEncoder.OriginalType? + public init(wrappedValue: CustomDecoderWrapper.CustomEncoder.OriginalType?) { + self.wrappedValue = wrappedValue + } +} + +/// Wraps `StaticDecoderWrapper` generically to allow the wrapped property to be Optional +@propertyWrapper +public struct OptionalDecoding: OptionalDecodable { + public typealias DecoderWrapper = CustomDecoderWrapper + + public var wrappedValue: CustomDecoderWrapper.CustomDecoder.DecodedType? + public init(wrappedValue: CustomDecoderWrapper.CustomDecoder.DecodedType?) { + self.wrappedValue = wrappedValue + } +} + +/// Wraps `StaticCodingWrapper` generically to allow the wrapped property to be Optional +@propertyWrapper +public struct OptionalCoding: OptionalCodable { + + public typealias DecoderWrapper = CustomCoderWrapper + public typealias EncoderWrapper = CustomCoderWrapper + + public var wrappedValue: CustomCoderWrapper.CustomEncoder.OriginalType? + public init(wrappedValue: CustomCoderWrapper.CustomDecoder.DecodedType?) { + self.wrappedValue = wrappedValue + } +} + +//MARK: Enable Customizing one direction + +/// Ensures there isn't an extra level added +extension OptionalEncoding: Decodable, TransientDecodable where CustomDecoderWrapper.CustomEncoder.OriginalType: Decodable { } +/// Ensures there isn't an extra level added +extension OptionalDecoding: Encodable, TransientEncodable where CustomDecoderWrapper.CustomDecoder.DecodedType: Encodable { } + +//MARK: Conditional Equatable Conformance + +extension OptionalEncoding: Equatable where CustomDecoderWrapper.CustomEncoder.OriginalType: Equatable {} +extension OptionalDecoding: Equatable where CustomDecoderWrapper.CustomDecoder.DecodedType: Equatable {} +extension OptionalCoding: Equatable where CustomCoderWrapper.CustomEncoder.OriginalType: Equatable {} + +//MARK: Conditional Hashable Conformance + +extension OptionalEncoding: Hashable where CustomDecoderWrapper.CustomEncoder.OriginalType: Hashable {} +extension OptionalDecoding: Hashable where CustomDecoderWrapper.CustomDecoder.DecodedType: Hashable {} +extension OptionalCoding: Hashable where CustomCoderWrapper.CustomEncoder.OriginalType: Hashable {} + + diff --git a/JSONCreator_iOS/JSONCreator/CodableWrappers/Core/StaticCodingWrappers.swift b/JSONCreator_iOS/JSONCreator/CodableWrappers/Core/StaticCodingWrappers.swift new file mode 100644 index 0000000..4218fa4 --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/CodableWrappers/Core/StaticCodingWrappers.swift @@ -0,0 +1,98 @@ +// +// CustomPropertyCoding.swift +// +// +// Created by PJ Fechner on 9/26/19. +// Copyright © 2019 PJ Fechner. All rights reserved. + +import Foundation + +//MARK: - Custom Coding Property Wrappers + +/// Customize the encoding of a property using the `CustomEncoder` +@propertyWrapper +public struct EncodingUses: StaticEncoderWrapper { + + public var wrappedValue: CustomEncoder.OriginalType + public init(wrappedValue: CustomEncoder.OriginalType) { + self.wrappedValue = wrappedValue + } +} + +/// Customize the decoding of a property using the `CustomDecoder` +@propertyWrapper +public struct DecodingUses: StaticDecoderWrapper { + + public var wrappedValue: CustomDecoder.DecodedType + public init(wrappedValue: CustomDecoder.DecodedType) { + self.wrappedValue = wrappedValue + } +} + +/// Customize the encoding and decoding of a property using the `CustomCoder` +@propertyWrapper +public struct CodingUses: StaticCodingWrapper { + public typealias CustomEncoder = CustomCoder + public typealias CustomDecoder = CustomCoder + + public var wrappedValue: CustomCoder.CodingType + public init(wrappedValue: CustomCoder.CodingType) { + self.wrappedValue = wrappedValue + } +} + +//MARK: - Static Coding Wrapper Protocols + +/// Contract for a Static Encoding Property Wrapper +/// This allows multiple wrappers to use the same `encode(to encoder: Encoder)` rather than reimplementing it. +public protocol StaticEncoderWrapper: Encodable { + associatedtype CustomEncoder: StaticEncoder + /// The value to be encoded + var wrappedValue: CustomEncoder.OriginalType { get } +} + +extension StaticEncoderWrapper { + /// Encodes the `wrappedValue` using the `CustomEncoder` + public func encode(to encoder: Encoder) throws { + try CustomEncoder.encode(value: wrappedValue, to: encoder) + } +} + +/// Contract for a Static Decoding Property Wrapper +/// This allows multiple wrappers to use the same `init(from decoder: Decoder)` rather than reimplementing it. +public protocol StaticDecoderWrapper: Decodable { + associatedtype CustomDecoder: StaticDecoder + init(wrappedValue: CustomDecoder.DecodedType) +} + +extension StaticDecoderWrapper { + /// Decodes the `wrappedValue` using the `CustomDecoder` + public init(from decoder: Decoder) throws { + self.init(wrappedValue: try CustomDecoder.decode(from: decoder)) + } +} + +/// Combines `StaticEncoderWrapper` and `StaticDecoderWrapper` +public protocol StaticCodingWrapper: StaticEncoderWrapper & StaticDecoderWrapper where CustomEncoder.OriginalType == CustomDecoder.DecodedType { + associatedtype CustomCoder: StaticCoder +} + +//MARK: Enable Customizing one direction + +/// Ensures there isn't an extra level added +extension EncodingUses: Decodable, TransientDecodable where CustomEncoder.OriginalType: Decodable { } +/// Ensures there isn't an extra level added +extension DecodingUses: Encodable, TransientEncodable where CustomDecoder.DecodedType: Encodable { } + + +//MARK: - Conditional Equatable Conformance + +extension EncodingUses: Equatable where CustomEncoder.OriginalType: Equatable {} +extension DecodingUses: Equatable where CustomDecoder.DecodedType: Equatable {} +extension CodingUses: Equatable where CustomCoder.CodingType: Equatable {} + +//MARK: - Conditional Hashable Conformance + +extension EncodingUses: Hashable where CustomEncoder.OriginalType: Hashable {} +extension DecodingUses: Hashable where CustomDecoder.DecodedType: Hashable {} +extension CodingUses: Hashable where CustomCoder.CodingType: Hashable {} diff --git a/JSONCreator_iOS/JSONCreator/CodableWrappers/Core/TransientCoding.swift b/JSONCreator_iOS/JSONCreator/CodableWrappers/Core/TransientCoding.swift new file mode 100644 index 0000000..959d016 --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/CodableWrappers/Core/TransientCoding.swift @@ -0,0 +1,98 @@ +// +// TransientCoding.swift +// +// +// Created by PJ Fechner on 7/7/20. +// + +import Foundation + +//MARK: - Transient Property Wrappers + + +/// Indicates the encoding should be done with the wrapped value directly rather than in a nested container +@propertyWrapper +public struct TransientEncoding: TransientEncodable { + + public var wrappedValue: T + public init(wrappedValue: T) { + self.wrappedValue = wrappedValue + } +} + +/// Indicates the decoding should be done from the current container rather a new level of nesting +@propertyWrapper +public struct TransientDecoding: TransientDecodable { + + public var wrappedValue: T + public init(wrappedValue: T) { + self.wrappedValue = wrappedValue + } +} + + +/// Indicates the (en/de)coding should be done directly rather than at a new level of nesting +@propertyWrapper +public struct TransientCoding: TransientCodable { + + public var wrappedValue: T + public init(wrappedValue: T) { + self.wrappedValue = wrappedValue + } +} + + +//MARK: - Transient Protocols + +/// Contract for a Type that encodes it's value directly rather than encoding an extra level for itself. +public protocol TransientEncodable: Encodable { + associatedtype ValueType: Encodable + // The value to be encoded + var wrappedValue: ValueType { get } +} + +public extension TransientEncodable { + // Encodes the wrapped value directly at the current level + func encode(to encoder: Encoder) throws { + try wrappedValue.encode(to: encoder) + } +} + +/// Contract for Type that decodes it's value at the currently level of the encoding rather than from a nested container +public protocol TransientDecodable: Decodable { + associatedtype InitType: Decodable + // The init to use when decoding + init(wrappedValue: InitType) +} +public extension TransientDecodable { + // Decodes the value directly at the current level of encoding + init(from decoder: Decoder) throws { + self.init(wrappedValue: try InitType(from: decoder)) + } +} +/// Combination of TransientEncodable & TransientEncodable +public protocol TransientCodable: TransientEncodable, TransientDecodable where ValueType == InitType { } + + +//MARK: Enable Customizing one direction + +extension TransientEncoding: Decodable where T: Decodable { + //Ensures there isn't an extra level added + public init(from decoder: Decoder) throws { + wrappedValue = try T(from: decoder) + } +} + +extension TransientDecoding: Encodable where T: Encodable { + //Ensures there isn't an extra level added + public func encode(to encoder: Encoder) throws { + try wrappedValue.encode(to: encoder) + } +} + + +//MARK: - Conditional Equatable Conformance + +extension TransientEncoding: Equatable where T: Equatable {} +extension TransientDecoding: Equatable where T: Equatable {} +extension TransientCoding: Equatable where T: Equatable {} diff --git a/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/BoolCoding.swift b/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/BoolCoding.swift new file mode 100644 index 0000000..e365f18 --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/BoolCoding.swift @@ -0,0 +1,59 @@ +// +// BoolCoding.swift +// +// +// Created by PJ Fechner on 12/8/19. +// Copyright © 2019 PJ Fechner. All rights reserved. + +import Foundation + +public protocol NonConformingBoolValueProvider { + /// The Type being converted to/from a Bool + associatedtype EncodedType: Codable, Equatable + /// Convert the Encoded Type to a Bool. Should return nil for invalid values + static func value(for typeValue: EncodedType) -> Bool? + /// Convert a Bool to the EncodedType + static func value(for boolean: Bool) -> EncodedType +} + +/// Int <-> Bool converter available for any Type adhering to FixedWidthInteger & Codable. +/// Uses 0 as false, and > 0 as true. +public struct BoolAsIntegerValueProvider: NonConformingBoolValueProvider where ValueType: FixedWidthInteger & Codable { + static public func value(for typeValue: ValueType) -> Bool? { typeValue > 0 ? true : false } + static public func value(for boolean: Bool) -> ValueType { boolean ? 1 : 0} +} + +/// String <-> Bool converter. +/// Uses lowercase "true" and "false". Values are `lowerCased()` before comparing. +public struct BoolAsStringValueProvider: NonConformingBoolValueProvider { + static public func value(for typeValue: String) -> Bool? { + switch typeValue.lowercased() { + case "true": return true + case "false": return false + default: + print("Failed to convert \(typeValue) to Boolean return nil") + return nil + } + } + static public func value(for boolean: Bool) -> String { boolean ? "true" : "false"} +} + + +/// Uses the passed ValueProvider for (de)serailization of `Bool?` +public struct NonConformingBoolStaticCoder: StaticCoder { + + public static func decode(from decoder: Decoder) throws -> Bool { + let encodedTypeValue = try ValueProvider.EncodedType(from: decoder) + if let convertedValue = ValueProvider.value(for: encodedTypeValue) { + return convertedValue + } + else { + throw DecodingError.typeMismatch(Bool.self, DecodingError.Context(codingPath: decoder.codingPath, + debugDescription: "Failed to convert \(ValueProvider.EncodedType.self) to Bool")) + } + } + + public static func encode(value: Bool, to encoder: Encoder) throws { + try ValueProvider.value(for: value).encode(to: encoder) + } +} diff --git a/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/DataCoding.swift b/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/DataCoding.swift new file mode 100644 index 0000000..c55d15b --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/DataCoding.swift @@ -0,0 +1,28 @@ +// +// DataCoding.swift +// +// +// Created by PJ Fechner on 10/16/19. +// Copyright © 2019 PJ Fechner. All rights reserved. + +import Foundation + + +/// Uses Base64 for (de)serailization of `Data` +public struct Base64DataStaticCoder: StaticCoder { + + public static func decode(from decoder: Decoder) throws -> Data { + + let stringValue = try String(from: decoder) + + guard let value = Data.init(base64Encoded: stringValue) else { + throw DecodingError.valueNotFound(self, DecodingError.Context(codingPath: decoder.codingPath, + debugDescription: "Expected \(Data.self) but could not convert \(stringValue) to Data")) + } + return value + } + + public static func encode(value: Data, to encoder: Encoder) throws { + try value.base64EncodedString().encode(to: encoder) + } +} diff --git a/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/DateCoding.swift b/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/DateCoding.swift new file mode 100644 index 0000000..e579a66 --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/DateCoding.swift @@ -0,0 +1,139 @@ +// +// DateCoding.swift +// +// +// Created by PJ Fechner on 10/16/19. +// Copyright © 2019 PJ Fechner. All rights reserved. + +import Foundation + +/// Uses secondsSince1970 for (de)serailization of `Date` +public struct SecondsSince1970DateStaticCoder: StaticCoder { + + public static func decode(from decoder: Decoder) throws -> Date { + + let value = try TimeInterval(from: decoder) + let valueDate = Date(timeIntervalSince1970: value) + return valueDate + } + + public static func encode(value: Date, to encoder: Encoder) throws { + try value.timeIntervalSince1970.encode(to: encoder) + } +} + +/// Uses millisecondsSince1970 for (de)serailization of `Date` +public struct MillisecondsSince1970DateStaticCoder: StaticCoder { + + public static func decode(from decoder: Decoder) throws -> Date { + + let value = try TimeInterval(from: decoder) + let valueDate = Date(timeIntervalSince1970: value / 1000) + return valueDate + } + + public static func encode(value: Date, to encoder: Encoder) throws { + try (value.timeIntervalSince1970 * 1000).encode(to: encoder) + } +} + +//MARK: - Custom DateFormatter + +/// A `StaticDecoder` that uses a DateFormatter for decoding +/// - Note: Implement to use a custom `DateFormatter` for deserialization in the `StaticDecoder` Property Wrapper +/// - Example: `@StaticDecoder` +public protocol DateFormatterStaticDecoder: StaticDecoder { + static var dateFormatter: DateFormatter { get } +} +/// A `StaticEncoder` that uses a DateFormatter for decoding +/// - Note: Implement to use a custom `DateFormatter` for serialization in the `StaticEncoder` Property Wrapper +/// - Example: `@StaticEncoder` +public protocol DateFormatterStaticEncoder: StaticEncoder { + static var dateFormatter: DateFormatter { get } +} + +/// Combination of `CustomDateFormatterEncoder` & `CustomDateFormatterDecoder` +/// - Note: Implement to use a custom `DateFormatter` for (de)serialization in the `StaticCoder` Property Wrapper +/// - Example: `@StaticCoder` +public typealias DateFormatterStaticCoder = StaticCoder & DateFormatterStaticEncoder & DateFormatterStaticDecoder + +extension DateFormatterStaticDecoder { + /// Uses `dateFormatter` for decoding + public static func decode(from decoder: Decoder) throws -> Date { + let stringValue = try String(from: decoder) + + guard let value = dateFormatter.date(from: stringValue) else { + throw DecodingError.valueNotFound(self, DecodingError.Context(codingPath: decoder.codingPath, + debugDescription: "Expected \(Data.self) but could not convert \(stringValue) to Data")) + } + return value + } +} + +extension DateFormatterStaticEncoder { +/// Uses `dateFormatter` for encoding + public static func encode(value: Date, to encoder: Encoder) throws { + try dateFormatter.string(from: value).encode(to: encoder) + } +} + +//MARK: - ISO8601 + + + +/// Uses `ISO8601DateFormatter` with `formatOptions` set to `.withInternetDateTime` for (de)serailization of `Date` +/// - Note: Implement a `StaticCoder` to use a custom formatter +@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) +public struct ISO8601DateStaticCoder: ISO8601DateFormatterStaticCoder { + + public static let iso8601DateFormatter: ISO8601DateFormatter = { + let formatter = ISO8601DateFormatter() + formatter.formatOptions = .withInternetDateTime + return formatter + }() +} + +//MARK: Custom + +/// A `StaticDecoder` that uses an ISO8601DateFormatter for decoding +/// - Note: Implement to use a custom `ISO8601DateFormatter` for deserialization in the `StaticDecoder` Property Wrapper +/// - Example: `@StaticDecoder` +@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) +public protocol ISO8601DateFormatterStaticDecoder: StaticDecoder { + static var iso8601DateFormatter: ISO8601DateFormatter { get } +} +/// A `StaticEncoder` that uses an ISO8601DateFormatter for decoding +/// - Note: Implement to use a custom `ISO8601DateFormatter` for serialization in the `StaticEncoder` Property Wrapper +/// - Example: `@StaticEncoder` +@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) +public protocol ISO8601DateFormatterStaticEncoder: StaticEncoder { + static var iso8601DateFormatter: ISO8601DateFormatter { get } +} + +/// Combination of `ISO8601DateFormatterStaticEncoder` & `ISO8601DateFormatterStaticDecoder` +/// - Note: Implement to use a custom `ISO8601DateFormatter` for (de)serialization in the `StaticCoder` Property Wrapper +/// - Example: `@StaticCoder` +@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) +public typealias ISO8601DateFormatterStaticCoder = StaticCoder & ISO8601DateFormatterStaticEncoder & ISO8601DateFormatterStaticDecoder + +@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) +extension ISO8601DateFormatterStaticDecoder { + /// Uses `ISO8601DateFormatter` for decoding + public static func decode(from decoder: Decoder) throws -> Date { + let stringValue = try String(from: decoder) + + guard let value = iso8601DateFormatter.date(from: stringValue) else { + throw DecodingError.valueNotFound(self, DecodingError.Context(codingPath: decoder.codingPath, + debugDescription: "Expected \(Data.self) but could not convert \(stringValue) to Data")) + } + return value + } +} + +@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) +extension ISO8601DateFormatterStaticEncoder { +/// Uses `dateFormatter` for encoding + public static func encode(value: Date, to encoder: Encoder) throws { + try iso8601DateFormatter.string(from: value).encode(to: encoder) + } +} diff --git a/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/FloatingPointCoding.swift b/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/FloatingPointCoding.swift new file mode 100644 index 0000000..a030f52 --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/FloatingPointCoding.swift @@ -0,0 +1,99 @@ +// +// FloatingPointCoding.swift +// +// +// Created by PJ Fechner on 10/16/19. +// Copyright © 2019 PJ Fechner. All rights reserved. + +import Foundation + + +/// A provider for the data needed for (de)serializing non conforming floating point values +public protocol NonConformingDecimalValueProvider { + /// The seralized `String` value to use when a number of `infiniti` + static var positiveInfinity: String { get } + /// The seralized `String` value to use when a number of `-infiniti` + static var negativeInfinity: String { get } + /// The seralized `String` value to use when a number of `NaN` + static var nan: String { get } +} + +/// Uses the `ValueProvider` for (de)serialization of a non-conforming `Float` +public struct NonConformingFloatStaticCoder: StaticCoder { + private init() { } + + public static func decode(from decoder: Decoder) throws -> Float { + guard let stringValue = try? String(from: decoder) else { + return try Float(from: decoder) + } + switch stringValue { + case ValueProvider.positiveInfinity: return Float.infinity + case ValueProvider.negativeInfinity: return -Float.infinity + case ValueProvider.nan: return Float.nan + default: + guard let value = Float(stringValue) else { + throw DecodingError.valueNotFound(self, DecodingError.Context(codingPath: decoder.codingPath, + debugDescription: "Expected \(Float.self) but could not convert \(stringValue) to Float")) + } + return value + } + } + + public static func encode(value: Float, to encoder: Encoder) throws { + + //For some reason the switch with nan doesn't work 🤷‍♂️ as of Swift 5.2 + if value.isNaN { + return try ValueProvider.nan.encode(to: encoder) + } + else if value == Float.infinity { + return try ValueProvider.positiveInfinity.encode(to: encoder) + } + else if value == -Float.infinity { + return try ValueProvider.negativeInfinity.encode(to: encoder) + } + else { + try value.encode(to: encoder) + } + } +} + + + +/// Uses the `ValueProvider` for (de)serialization of a non-conforming `Double` +public struct NonConformingDoubleStaticCoder: StaticCoder { + private init() { } + + public static func decode(from decoder: Decoder) throws -> Double { + guard let stringValue = try? String(from: decoder) else { + return try Double(from: decoder) + } + switch stringValue { + case ValueProvider.positiveInfinity: return Double.infinity + case ValueProvider.negativeInfinity: return -Double.infinity + case ValueProvider.nan: return Double.nan + default: + guard let value = Double(stringValue) else { + throw DecodingError.valueNotFound(self, DecodingError.Context(codingPath: decoder.codingPath, + debugDescription: "Expected \(Double.self) but could not convert \(stringValue) to Float")) + } + return value + } + } + + public static func encode(value: Double, to encoder: Encoder) throws { + + //For some reason the switch with nan doesn't work 🤷‍♂️ as of Swift 5.2 + if value.isNaN { + return try ValueProvider.nan.encode(to: encoder) + } + else if value == Double.infinity { + return try ValueProvider.positiveInfinity.encode(to: encoder) + } + else if value == -Double.infinity { + return try ValueProvider.negativeInfinity.encode(to: encoder) + } + else { + try value.encode(to: encoder) + } + } +} diff --git a/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/NilFiltering.swift b/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/NilFiltering.swift new file mode 100644 index 0000000..0babb7a --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/NilFiltering.swift @@ -0,0 +1,46 @@ +// +// NilFiltering.swift +// +// +// Created by PJ Fechner on 7/10/20. +// + +import Foundation + +/// Decodes an array, removing any nil values +public struct ArrayNilFilteringStaticDecoder: StaticDecoder { + public static func decode(from decoder: Decoder) throws -> Array { + var container = try decoder.unkeyedContainer() + return try container.filteringNils() + } +} + +/// Uses Decodes a Set, removing any nil values +public struct SetNilFilteringStaticDecoder: StaticDecoder where T: Hashable { + public static func decode(from decoder: Decoder) throws -> Set { + var container = try decoder.unkeyedContainer() + return try Set(container.filteringNils()) + } +} + +/// Uses Decodes a dictionary, removing any nil values +public struct DictionaryNilFilteringStaticDecoder: StaticDecoder where Key: Hashable { + public static func decode(from decoder: Decoder) throws -> [Key:T] { + try Dictionary(from: decoder).compactMapValues{$0} + } +} + +extension UnkeyedDecodingContainer { + ///This decodes real items while filtering any nil values. + @inlinable mutating func filteringNils() throws -> [T] { + var items: [T] = [] + while !isAtEnd { + // At least for PLists, `decodeIfPresent` seems to break when a value is `$null`. + // This is why `Optional` is required + if let item = try decodeIfPresent(Optional.self) as? T { + items.append(item) + } + } + return items + } +} diff --git a/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/NullEncoding.swift b/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/NullEncoding.swift new file mode 100644 index 0000000..5b6087d --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/NullEncoding.swift @@ -0,0 +1,40 @@ +// +// NullEncoding.swift +// +// +// Created by PJ Fechner on 7/12/20. +// + +import Foundation +//MARK: - EncodeNulls + +public protocol AnyNullEncoder { + associatedtype T: Encodable + static func encode(value: T, to encoder: Encoder) throws +} + +/// Encodes a nil value in a singleValueContainer using `encodeNil` rather than it being omitted. +public struct NullStaticEncoder: StaticEncoder, AnyNullEncoder where T: ExpressibleByNilLiteral { + public static func encode(value: T, to encoder: Encoder) throws { + + if case Optional.none = value as Any { + var container = encoder.singleValueContainer() + try container.encodeNil() + return + } + try value.encode(to: encoder) + } +} + + +extension KeyedEncodingContainer { + // Used to make bybass the `OptionalCodingWrappers` which encodes no value when it's wrappedValue is nil. + public mutating func encode(_ value: T, forKey key: KeyedEncodingContainer.Key) throws where T: OptionalEncodingWrapper & StaticEncoderWrapper, T.CustomEncoder: AnyNullEncoder { + try T.CustomEncoder.encode(value: value.wrappedValue, to: superEncoder(forKey: key)) + } + + // Used to bybass the `OptionalCodingWrappers` when wrapped in an `Immutable`, which encodes no value when it's wrappedValue.wrappedValue is nil. + public mutating func encode(_ value: T, forKey key: KeyedEncodingContainer.Key) throws where T: Encodable, T: AnyImmutableWrapper, T.T: OptionalEncodingWrapper & StaticEncoderWrapper, T.T.CustomEncoder: AnyNullEncoder { + try T.T.CustomEncoder.encode(value: value.wrappedValue.wrappedValue, to: superEncoder(forKey: key)) + } +} diff --git a/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/StaticCoding.swift b/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/StaticCoding.swift new file mode 100644 index 0000000..8393dbc --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/CodableWrappers/StaticCoders/StaticCoding.swift @@ -0,0 +1,37 @@ +// +// File.swift +// +// +// Created by PJ Fechner on 7/7/20. +// + +import Foundation + +//MARK: - Static Coding Protocols + +/// Mirror of `Encodable`'s functionality but in a static context +/// - Attention: When implementing ensure an additional level of nesting is not introduced +public protocol StaticEncoder { + /// The Type this encodes + associatedtype OriginalType: Encodable + + /// Mirror of `Encodable`'s `encode(to: Encoder)` but in a static context + static func encode(value: OriginalType, to encoder: Encoder) throws +} + +/// Mirror of `Decodable`'s functionality but in a static context +/// - Attention: When implementing ensure an additional level of nesting is not introduced +public protocol StaticDecoder { + /// The Type this will decode + associatedtype DecodedType: Decodable + + /// Mirror of `Decodable`'s `init(from: Decoder)` but in a static context + static func decode(from decoder: Decoder) throws -> DecodedType +} + +/// Combines `StaticDecoder` and `StaticEncoder` +/// - Attention: When implementing ensure an additional level of nesting is not introduced +public protocol StaticCoder: StaticDecoder & StaticEncoder where DecodedType == OriginalType { + /// `StaticDecoder.DecodedType` & `StaticEncoder.OriginalType` + typealias CodingType = DecodedType +} diff --git a/JSONCreator_iOS/JSONCreator/DecodableDefaults+VDS.swift b/JSONCreator_iOS/JSONCreator/DecodableDefaults+VDS.swift index 30e002d..bc56346 100644 --- a/JSONCreator_iOS/JSONCreator/DecodableDefaults+VDS.swift +++ b/JSONCreator_iOS/JSONCreator/DecodableDefaults+VDS.swift @@ -11,63 +11,6 @@ import VDS import MVMCore //MARK: - Decodable Defaults -extension VDSFontCategory { - public enum DefaultFeature: DecodableDefault.Source { - public static var defaultValue: VDSFontCategory { .feature } - } - public enum DefaultTitle: DecodableDefault.Source { - public static var defaultValue: VDSFontCategory { .title } - } - public enum DefaultBody: DecodableDefault.Source { - public static var defaultValue: VDSFontCategory { .body } - } - public enum DefaultMicro: DecodableDefault.Source { - public static var defaultValue: VDSFontCategory { .micro } - } -} - -extension VDSFontSize { - public enum Default2XLarge: DecodableDefault.Source { - public static var defaultValue: VDSFontSize { .xxlarge } - } - public enum DefaultXLarge: DecodableDefault.Source { - public static var defaultValue: VDSFontSize { .xlarge } - } - public enum DefaultLarge: DecodableDefault.Source { - public static var defaultValue: VDSFontSize { .large } - } - public enum DefaultMedium: DecodableDefault.Source { - public static var defaultValue: VDSFontSize { .medium } - } - public enum DefaultSmall: DecodableDefault.Source { - public static var defaultValue: VDSFontSize { .small } - } - public enum DefaultXSmall: DecodableDefault.Source { - public static var defaultValue: VDSFontSize { .xsmall } - } -} - -extension VDSTextPosition { - public enum DefaultLeft: DecodableDefault.Source { - public static var defaultValue: VDSTextPosition { .left } - } - public enum DefaultRight: DecodableDefault.Source { - public static var defaultValue: VDSTextPosition { .right } - } - public enum DefaultCenter: DecodableDefault.Source { - public static var defaultValue: VDSTextPosition { .center } - } -} - -extension VDSFontWeight { - public enum DefaultBold: DecodableDefault.Source { - public static var defaultValue: VDSFontWeight { .bold } - } - public enum DefaultRegular: DecodableDefault.Source { - public static var defaultValue: VDSFontWeight { .regular } - } -} - extension Toggle { public enum DefaultOffText: DecodableDefault.Source { public static var defaultValue: String { "Off" } @@ -92,26 +35,9 @@ extension DecodableDefault { public typealias Light = DecodableDefault.Wrapper public typealias Dark = DecodableDefault.Wrapper } - - public struct VDSTypography { - public typealias FontCategoryFeature = DecodableDefault.Wrapper - public typealias FontCategoryTitle = DecodableDefault.Wrapper - public typealias FontCategoryBody = DecodableDefault.Wrapper - public typealias FontCategoryMicro = DecodableDefault.Wrapper - public typealias FontWeightBold = DecodableDefault.Wrapper - public typealias FontWeightRegular = DecodableDefault.Wrapper - public typealias FontSize2XLarge = DecodableDefault.Wrapper - public typealias FontSizeXLarge = DecodableDefault.Wrapper - public typealias FontSizeLarge = DecodableDefault.Wrapper - public typealias FontSizeMedium = DecodableDefault.Wrapper - public typealias FontSizeSmall = DecodableDefault.Wrapper - public typealias FontSizeXSmall = DecodableDefault.Wrapper - public typealias TextPositionLeft = DecodableDefault.Wrapper - public typealias TextPositionRight = DecodableDefault.Wrapper - public typealias TextPositionCenter = DecodableDefault.Wrapper + + public struct VDSToggle { + public typealias OffText = DecodableDefault.Wrapper + public typealias OnText = DecodableDefault.Wrapper } -// public struct VDSToggle { -// public typealias OffText = DecodableDefault.Wrapper -// public typealias OnText = DecodableDefault.Wrapper -// } } diff --git a/JSONCreator_iOS/JSONCreator/JSON/Samples/Wifi/TestModel.json b/JSONCreator_iOS/JSONCreator/JSON/Samples/Wifi/TestModel.json new file mode 100644 index 0000000..c905f6e --- /dev/null +++ b/JSONCreator_iOS/JSONCreator/JSON/Samples/Wifi/TestModel.json @@ -0,0 +1,30 @@ +{ + "moleculeName": "testModel", + "text": "Here's your update", + "action": { + "actionType": "openPage", + "pageType": "updateProfile", + "extraParameters": { + "from": "none" + }, + "presentationStyle": "push" + }, + "actions": [ + { + "actionType": "openPage", + "pageType": "updateProfile", + "extraParameters": { + "from": "none" + }, + "presentationStyle": "push" + }, + { + "actionType": "openPage", + "pageType": "deleteProfile", + "extraParameters": { + "from": "none" + }, + "presentationStyle": "push" + } + ] +} diff --git a/JSONCreator_iOS/JSONCreator/TestToggle.swift b/JSONCreator_iOS/JSONCreator/TestToggle.swift index 46ca9fb..32aaa8a 100644 --- a/JSONCreator_iOS/JSONCreator/TestToggle.swift +++ b/JSONCreator_iOS/JSONCreator/TestToggle.swift @@ -54,8 +54,8 @@ open class TestToggle: ToggleBase, MoleculeViewProtocol, MVMCor //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- - open override func onStateChange(viewModel: ModelType) { - super.onStateChange(viewModel: viewModel) + open override func updateView(viewModel: ModelType) { + super.updateView(viewModel: viewModel) onModelChange(model: viewModel) } @@ -67,6 +67,10 @@ open class TestToggle: ToggleBase, MoleculeViewProtocol, MVMCor // MARK:- MVMCoreViewProtocol public func updateView(_ size: CGFloat) {} public func setupView() {} + + open override func toggle() { + super.toggle() + } // MARK:- MoleculeViewProtocol public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { diff --git a/JSONCreator_iOS/JSONCreator/TestToggleModel.swift b/JSONCreator_iOS/JSONCreator/TestToggleModel.swift index dc0beeb..ac8af65 100644 --- a/JSONCreator_iOS/JSONCreator/TestToggleModel.swift +++ b/JSONCreator_iOS/JSONCreator/TestToggleModel.swift @@ -13,7 +13,6 @@ import VDS //MARK: - Model public class TestToggleModel: MoleculeModelProtocol, FormFieldProtocol, VDS.ToggleModel { - //-------------------------------------------------- // MARK: - Properties @@ -35,7 +34,7 @@ public class TestToggleModel: MoleculeModelProtocol, FormFieldProtocol, VDS.Togg public var enabled: Bool = true //ToggleModelProtocol - public var id: String? + public var id = UUID() public var showText: Bool = false public var on: Bool = false public var surface: Surface = .light @@ -51,9 +50,8 @@ public class TestToggleModel: MoleculeModelProtocol, FormFieldProtocol, VDS.Togg public var accessibilityValueDisabled: String? public var accessibilityLabelEnabled: String? public var accessibilityLabelDisabled: String? - public var fontSize: VDSFontSize = .small - public var textPosition: VDSTextPosition = .left - public var fontWeight: VDSFontWeight = .regular + public var typograpicalStyle: VDS.TypographicalStyle = .BodyLarge + public var textPosition: TextPosition = .left public var offText: String = "Off" public var onText: String = "On" //-------------------------------------------------- @@ -80,9 +78,8 @@ public class TestToggleModel: MoleculeModelProtocol, FormFieldProtocol, VDS.Togg case dataClickStream case dataTrack case disabled //which to use - case fontSize + case typograpicalStyle case textPosition - case fontWeight case offText case onText } @@ -139,7 +136,6 @@ public class TestToggleModel: MoleculeModelProtocol, FormFieldProtocol, VDS.Togg } //vds toggle - id = try typeContainer.decodeIfPresent(String.self, forKey: .id) showText = try typeContainer.decodeIfPresent(Bool.self, forKey: .showText) ?? false on = try typeContainer.decodeIfPresent(Bool.self, forKey: .on) ?? false @@ -147,9 +143,8 @@ public class TestToggleModel: MoleculeModelProtocol, FormFieldProtocol, VDS.Togg dataAnalyticsTrack = try typeContainer.decodeIfPresent(String.self, forKey: .dataAnalyticsTrack) dataClickStream = try typeContainer.decodeIfPresent(String.self, forKey: .dataClickStream) dataTrack = try typeContainer.decodeIfPresent(String.self, forKey: .dataTrack) - fontSize = try typeContainer.decodeIfPresent(VDSFontSize.self, forKey: .fontSize) ?? .small - textPosition = try typeContainer.decodeIfPresent(VDSTextPosition.self, forKey: .textPosition) ?? .left - fontWeight = try typeContainer.decodeIfPresent(VDSFontWeight.self, forKey: .fontWeight) ?? .regular + typograpicalStyle = try typeContainer.decodeIfPresent(TypographicalStyle.self, forKey: .typograpicalStyle) ?? .BodyLarge + textPosition = try typeContainer.decodeIfPresent(TextPosition.self, forKey: .textPosition) ?? .left offText = try typeContainer.decodeIfPresent(String.self, forKey: .offText) ?? "Off" onText = try typeContainer.decodeIfPresent(String.self, forKey: .onText) ?? "On" @@ -193,9 +188,8 @@ public class TestToggleModel: MoleculeModelProtocol, FormFieldProtocol, VDS.Togg try container.encode(dataClickStream, forKey: .dataClickStream) try container.encode(dataTrack, forKey: .dataTrack) try container.encode(disabled, forKey: .disabled) - try container.encodeIfPresent(fontSize, forKey: .fontSize) + try container.encodeIfPresent(typograpicalStyle, forKey: .typograpicalStyle) try container.encodeIfPresent(textPosition, forKey: .textPosition) - try container.encodeIfPresent(fontWeight, forKey: .fontWeight) try container.encodeIfPresent(offText, forKey: .offText) try container.encodeIfPresent(onText, forKey: .onText) } diff --git a/dependency.txt b/dependency.txt index 8104f9a..ee0bea8 100644 --- a/dependency.txt +++ b/dependency.txt @@ -3,6 +3,4 @@ mvm_core https://gitlab.verizon.com/BPHV_MIPS/mvm_core.git develop mvm_core_ui https://gitlab.verizon.com/BPHV_MIPS/mvm_core_ui.git develop -vds https://gitlab.verizon.com/V520390/vds.git developvds - -vds_sample https://gitlab.verizon.com/V520390/vdssample develop \ No newline at end of file +vds_ios https://gitlab.verizon.com/BPHV_MIPS/vds_ios develop \ No newline at end of file