Signed-off-by: Matt Bruce <matt.bruce@verizon.com>

This commit is contained in:
Matt Bruce 2022-10-11 11:25:01 -05:00
parent 0391962ac7
commit 1146ba0b8c
26 changed files with 1839 additions and 114 deletions

4
.gitignore vendored
View File

@ -11,8 +11,8 @@ mvm_core
mfprepayshop_ios
mvm_core_ui
mvmreactnative
vds
VDSSample
vds_ios
vds_ios_sample
# frameworks
contentTransferFramework.framework

View File

@ -2,10 +2,7 @@
<Workspace
version = "1.0">
<FileRef
location = "group:VDSSample/VDSSample.xcodeproj">
</FileRef>
<FileRef
location = "group:vds/VDS.xcodeproj">
location = "group:vds_ios/VDS.xcodeproj">
</FileRef>
<FileRef
location = "group:mvm_core/MVMCore/MVMCore.xcodeproj">

View File

@ -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 = "<group>"; };
EA84F74028BD558F00D67ABC /* ImmutableWrapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImmutableWrapper.swift; sourceTree = "<group>"; };
EA84F74128BD558F00D67ABC /* OptionalWrappers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionalWrappers.swift; sourceTree = "<group>"; };
EA84F74228BD558F00D67ABC /* FallbackCoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FallbackCoding.swift; sourceTree = "<group>"; };
EA84F74328BD558F00D67ABC /* OmitCodingWrappers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OmitCodingWrappers.swift; sourceTree = "<group>"; };
EA84F74428BD558F00D67ABC /* StaticCodingWrappers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StaticCodingWrappers.swift; sourceTree = "<group>"; };
EA84F74628BD558F00D67ABC /* NilFiltering.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NilFiltering.swift; sourceTree = "<group>"; };
EA84F74728BD558F00D67ABC /* DateCoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateCoding.swift; sourceTree = "<group>"; };
EA84F74828BD558F00D67ABC /* FloatingPointCoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatingPointCoding.swift; sourceTree = "<group>"; };
EA84F74928BD558F00D67ABC /* BoolCoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoolCoding.swift; sourceTree = "<group>"; };
EA84F74A28BD558F00D67ABC /* DataCoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataCoding.swift; sourceTree = "<group>"; };
EA84F74B28BD558F00D67ABC /* NullEncoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NullEncoding.swift; sourceTree = "<group>"; };
EA84F74C28BD558F00D67ABC /* StaticCoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StaticCoding.swift; sourceTree = "<group>"; };
EA84F74E28BD558F00D67ABC /* EmptyDefaults.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmptyDefaults.swift; sourceTree = "<group>"; };
EA84F74F28BD558F00D67ABC /* CustomWrappers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomWrappers.swift; sourceTree = "<group>"; };
EA84F75028BD558F00D67ABC /* ConveienceAdherence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConveienceAdherence.swift; sourceTree = "<group>"; };
EAA54A91286A47ED00B9136B /* WifiViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WifiViewController.swift; sourceTree = "<group>"; };
EAA658142875FA5E00484A7D /* VDSFormControlsTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSFormControlsTokens.xcframework; path = ../SharedFrameworks/VDSFormControlsTokens.xcframework; sourceTree = "<group>"; };
EACA5E5D2853DBC900CBA65B /* VDSColorTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSColorTokens.xcframework; path = ../SharedFrameworks/VDSColorTokens.xcframework; sourceTree = "<group>"; };
@ -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 = "<group>";
};
EA84F73D28BD558F00D67ABC /* CodableWrappers */ = {
isa = PBXGroup;
children = (
EA84F73E28BD558F00D67ABC /* Core */,
EA84F74528BD558F00D67ABC /* StaticCoders */,
EA84F74D28BD558F00D67ABC /* Convenience */,
);
path = CodableWrappers;
sourceTree = "<group>";
};
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 = "<group>";
};
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 = "<group>";
};
EA84F74D28BD558F00D67ABC /* Convenience */ = {
isa = PBXGroup;
children = (
EA84F74E28BD558F00D67ABC /* EmptyDefaults.swift */,
EA84F74F28BD558F00D67ABC /* CustomWrappers.swift */,
EA84F75028BD558F00D67ABC /* ConveienceAdherence.swift */,
);
path = Convenience;
sourceTree = "<group>";
};
/* 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;
};

View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1340"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D2B1E3EE22F4A68F0065F95C"
BuildableName = "JSONCreator.app"
BlueprintName = "JSONCreator"
ReferencedContainer = "container:JSONCreator.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D2B1E3EE22F4A68F0065F95C"
BuildableName = "JSONCreator.app"
BlueprintName = "JSONCreator"
ReferencedContainer = "container:JSONCreator.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D2B1E3EE22F4A68F0065F95C"
BuildableName = "JSONCreator.app"
BlueprintName = "JSONCreator"
ReferencedContainer = "container:JSONCreator.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -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<AnyModel<ActionModelProtocol>> var action: ActionModelProtocol
@OptionalModels<AnyModels<ActionModelProtocol>> var actions: [ActionModelProtocol]?
}
//4 class
//2 optional (single/array)
//2 non-optional (single/array)
@propertyWrapper
public struct ModelCodable<ModelType> {
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<ModelType> {
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<ModelType> {
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<ModelType> {
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<ModelType>: 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<ModelType>: 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<ModelType: WrappedModel> {
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<ModelType: WrappedModels> {
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<ModelType: WrappedModel> {
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<ModelType: WrappedModels> {
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<T>() 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<T>() throws -> [T] {
var container = try unkeyedContainer()
return try container.decodeModelsIfPresent() ?? []
}
}

View File

@ -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 { }

View File

@ -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<ValueProvider: NonConformingDecimalValueProvider> = EncodingUses<NonConformingFloatStaticCoder<ValueProvider>>
/// Use the values in `ValueProvider` when decoding this immutable Property with non-conforming numbers, also known as IEEE 754 exceptional values.
public typealias NonConformingFloatDecoding<ValueProvider: NonConformingDecimalValueProvider> = DecodingUses<NonConformingFloatStaticCoder<ValueProvider>>
/// 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<ValueProvider: NonConformingDecimalValueProvider> = CodingUses<NonConformingFloatStaticCoder<ValueProvider>>
/// 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<ValueProvider: NonConformingDecimalValueProvider> = EncodingUses<NonConformingDoubleStaticCoder<ValueProvider>>
/// Use the values in `ValueProvider` when decoding this immutable Property with non-conforming numbers, also known as IEEE 754 exceptional values.
public typealias NonConformingDoubleDecoding<ValueProvider: NonConformingDecimalValueProvider> = DecodingUses<NonConformingDoubleStaticCoder<ValueProvider>>
/// 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<ValueProvider: NonConformingDecimalValueProvider> = CodingUses<NonConformingDoubleStaticCoder<ValueProvider>>
//MARK: - Data
//MARK: Base64
/// Encode this immutable `Data` Property as a Base64 encoded String
public typealias Base64Encoding = EncodingUses<Base64DataStaticCoder>
/// Decode this immutable `Data` Property as a Base64 encoded String
public typealias Base64Decoding = DecodingUses<Base64DataStaticCoder>
/// (En/De)code this immutable `Data` Property as a Base64 encoded String
public typealias Base64Coding = CodingUses<Base64DataStaticCoder>
//MARK: - Date
//MARK: millisecondsSince1970
/// Encode this immutable `Date` Property using millisecondsSince1970
public typealias MillisecondsSince1970DateEncoding = EncodingUses<MillisecondsSince1970DateStaticCoder>
/// Decode this immutable `Date` Property using millisecondsSince1970
public typealias MillisecondsSince1970DateDecoding = DecodingUses<MillisecondsSince1970DateStaticCoder>
/// (En/De)code this immutable `Date` Property using millisecondsSince1970
public typealias MillisecondsSince1970DateCoding = CodingUses<MillisecondsSince1970DateStaticCoder>
//MARK: secondsSince1970
/// Encode this immutable `Date` Property using secondsSince1970
public typealias SecondsSince1970DateEncoding = EncodingUses<SecondsSince1970DateStaticCoder>
/// Decode this immutable `Date` Property using secondsSince1970
public typealias SecondsSince1970DateDecoding = DecodingUses<SecondsSince1970DateStaticCoder>
/// (En/De)code this immutable `Date` Property using secondsSince1970
public typealias SecondsSince1970DateCoding = CodingUses<SecondsSince1970DateStaticCoder>
//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<ISO8601DateStaticCoder>
/// 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<ISO8601DateStaticCoder>
/// (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<ISO8601DateStaticCoder>
//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<CustomEncoder: ISO8601DateFormatterStaticEncoder> = EncodingUses<CustomEncoder>
@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<CustomDecoder: ISO8601DateFormatterStaticDecoder> = DecodingUses<CustomDecoder>
/// (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<CustomCoder: ISO8601DateFormatterStaticCoder> = CodingUses<CustomCoder>
//MARK: DateFormatter
/// Encode this immutable `Date` Property using the passed formatter
public typealias DateFormatterEncoding<CustomEncoder: DateFormatterStaticEncoder> = EncodingUses<CustomEncoder>
/// Decode this immutable `Date` Property using the passed formatter
public typealias DateFormatterDecoding<CustomDecoder: DateFormatterStaticDecoder> = DecodingUses<CustomDecoder>
/// (En/De)code this immutable `Date` Property using the passed formatter
public typealias DateFormatterCoding<CustomCoder: DateFormatterStaticCoder> = CodingUses<CustomCoder>
//MARK: - Bool
//MARK: NonConformingBool
/// Encode this immutable `Bool` Property using the passed NonConformingBoolValueProvider
public typealias NonConformingBoolEncoding<ValueProvider: NonConformingBoolValueProvider> = EncodingUses<NonConformingBoolStaticCoder<ValueProvider>>
/// Decode this immutable `Bool` Property using the passed NonConformingBoolValueProvider
public typealias NonConformingBoolDecoding<ValueProvider: NonConformingBoolValueProvider> = DecodingUses<NonConformingBoolStaticCoder<ValueProvider>>
/// (En/De)code this immutable `Bool` Property using the passed NonConformingBoolValueProvider
public typealias NonConformingBoolCoding<ValueProvider: NonConformingBoolValueProvider> = CodingUses<NonConformingBoolStaticCoder<ValueProvider>>
//MARK: BoolAsInteger
/// Convenience typealias
public typealias BoolAsIntegerStaticCoder<ValueType: FixedWidthInteger & Codable> = NonConformingBoolStaticCoder<BoolAsIntegerValueProvider<ValueType>>
/// Encode this immutable `Bool` Property as the passed Integer Type using 1 as true and 0 as false
public typealias BoolAsIntegerEncoding<ValueType: FixedWidthInteger & Codable> = EncodingUses<BoolAsIntegerStaticCoder<ValueType>>
/// Decode this immutable `Bool` Property as passed Integer Type using 1 as true and 0 as false
public typealias BoolFromIntegerDecoding<ValueType: FixedWidthInteger & Codable> = DecodingUses<BoolAsIntegerStaticCoder<ValueType>>
/// (En/De)code this immutable `Bool` Property as passed Integer Type using 1 as true and 0 as false
public typealias BoolAsIntegerCoding<ValueType: FixedWidthInteger & Codable> = CodingUses<BoolAsIntegerStaticCoder<ValueType>>
//MARK: BoolAsInt
/// Encode this immutable `Bool` Property as an Int using 1 as true and 0 as false
public typealias BoolAsIntEncoding = BoolAsIntegerEncoding<Int>
/// Decode this immutable `Bool` Property as an Int using 1 as true and 0 as false
public typealias BoolFromIntDecoding = BoolFromIntegerDecoding<Int>
/// (En/De)code this immutable `Bool` Property as an Int using 1 as true and 0 as false
public typealias BoolAsIntCoding = BoolAsIntegerCoding<Int>
/// Convenience typealias
public typealias BoolAsStringStaticCoder = NonConformingBoolStaticCoder<BoolAsStringValueProvider>
/// Encode this immutable `Bool` Property as a String using "true" for true and "false" for false
public typealias BoolAsStringEncoding = EncodingUses<BoolAsStringStaticCoder>
/// Decode this immutable `Bool` Property as a String using "true" for true and "false" for false
public typealias BoolFromStringDecoding = DecodingUses<BoolAsStringStaticCoder>
/// (En/De)code this immutable `Bool` Property a String using "true" for true and "false" for false
public typealias BoolAsStringCoding = CodingUses<BoolAsStringStaticCoder>
//MARK: NilFiltering
/// Filters any nil values when decoding
public typealias LossyArrayDecoding<T: Decodable> = DecodingUses<ArrayNilFilteringStaticDecoder<T>>
/// Filters any nil values when decoding
public typealias LossySetDecoding<T: Decodable & Hashable> = DecodingUses<SetNilFilteringStaticDecoder<T>>
/// Filters any nil values when decoding
public typealias LossyDictionaryDecoding<T: Decodable, Key: Decodable & Hashable> = DecodingUses<DictionaryNilFilteringStaticDecoder<T, Key>>
//MARK: NullEncoding
/// Encodes a nil value in a singleValueContainer using `encodeNil` rather than it being omitted.
public typealias EncodeNulls<T: Encodable & ExpressibleByNilLiteral> = EncodingUses<NullStaticEncoder<T>>

View File

@ -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<T>: FallbackValueProvider {
public static var defaultValue: Array<T> { [] }
}
/// Empty FallbackValueProvider for Dictionary: [:]
public struct EmptyDictionary<Key: Hashable, Value>: FallbackValueProvider {
public static var defaultValue: Dictionary<Key, Value> { [:] }
}
/// Empty FallbackValueProvider for Set: []
public struct EmptySet<T: Hashable>: FallbackValueProvider {
public static var defaultValue: Set<T> { [] }
}

View File

@ -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<ValueProvider: FallbackValueProvider>: 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<ValueProvider: FallbackValueProvider>: 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<ValueProvider: FallbackValueProvider>: 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<T>(_ type: T.Type, forKey key: KeyedDecodingContainer<K>.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 {}

View File

@ -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<T>: 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<T>(_ type: T.Type, forKey key: KeyedDecodingContainer<K>.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<T>(_ value: T, forKey key: KeyedEncodingContainer<K>.Key) throws where T: Encodable, T: AnyImmutableWrapper, T.T: OptionalEncodingWrapper {
if case Optional<Any>.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<T>(_ type: T.Type, forKey key: KeyedDecodingContainer<K>.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))
}
}

View File

@ -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<WrappedType: Encodable>: 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<WrappedType: Decodable>: 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<WrappedType: Codable>: 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<T>(_ type: T.Type, forKey key: KeyedDecodingContainer<K>.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<T>(_ value: T, forKey key: KeyedEncodingContainer<K>.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 { }

View File

@ -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<T>(_ type: T.Type, forKey key: KeyedDecodingContainer<K>.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<T>(_ value: T, forKey key: KeyedEncodingContainer<K>.Key) throws where T: Encodable, T: OptionalEncodingWrapper {
if case Optional<Any>.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<CustomDecoderWrapper: StaticEncoderWrapper>: 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<CustomDecoderWrapper: StaticDecoderWrapper>: 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<CustomCoderWrapper: StaticCodingWrapper>: 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 {}

View File

@ -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<CustomEncoder: StaticEncoder>: 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<CustomDecoder: StaticDecoder>: 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<CustomCoder: StaticCoder>: 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 {}

View File

@ -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<T:Codable>: 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<T:Codable>: 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<T:Codable>: 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 {}

View File

@ -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<ValueType>: 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<ValueProvider: NonConformingBoolValueProvider>: 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)
}
}

View File

@ -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)
}
}

View File

@ -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<YourCustomDateFormatterDecoder>`
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<YourCustomDateFormatterEncoder>`
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<YourCustomDateFormatterCoder>`
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<YourCustomISO8601DateFormatterDecoder>`
@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<YourCustomISO8601DateFormatterEncoder>`
@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<YourCustomISO8601DateFormatterCoder>`
@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)
}
}

View File

@ -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<ValueProvider: NonConformingDecimalValueProvider>: 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<ValueProvider: NonConformingDecimalValueProvider>: 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)
}
}
}

View File

@ -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<T: Decodable>: StaticDecoder {
public static func decode(from decoder: Decoder) throws -> Array<T> {
var container = try decoder.unkeyedContainer()
return try container.filteringNils()
}
}
/// Uses Decodes a Set, removing any nil values
public struct SetNilFilteringStaticDecoder<T: Decodable>: StaticDecoder where T: Hashable {
public static func decode(from decoder: Decoder) throws -> Set<T> {
var container = try decoder.unkeyedContainer()
return try Set(container.filteringNils())
}
}
/// Uses Decodes a dictionary, removing any nil values
public struct DictionaryNilFilteringStaticDecoder<T: Decodable, Key: Decodable>: StaticDecoder where Key: Hashable {
public static func decode(from decoder: Decoder) throws -> [Key:T] {
try Dictionary<Key, T?>(from: decoder).compactMapValues{$0}
}
}
extension UnkeyedDecodingContainer {
///This decodes real items while filtering any nil values.
@inlinable mutating func filteringNils<T: Decodable>() throws -> [T] {
var items: [T] = []
while !isAtEnd {
// At least for PLists, `decodeIfPresent` seems to break when a value is `$null`.
// This is why `Optional<T>` is required
if let item = try decodeIfPresent(Optional<T>.self) as? T {
items.append(item)
}
}
return items
}
}

View File

@ -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<T: Encodable>: StaticEncoder, AnyNullEncoder where T: ExpressibleByNilLiteral {
public static func encode(value: T, to encoder: Encoder) throws {
if case Optional<Any>.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<T>(_ value: T, forKey key: KeyedEncodingContainer<K>.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<T>(_ value: T, forKey key: KeyedEncodingContainer<K>.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))
}
}

View File

@ -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
}

View File

@ -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<VDS.Surface.DefaultLight>
public typealias Dark = DecodableDefault.Wrapper<VDS.Surface.DefaultDark>
}
public struct VDSTypography {
public typealias FontCategoryFeature = DecodableDefault.Wrapper<VDSFontCategory.DefaultFeature>
public typealias FontCategoryTitle = DecodableDefault.Wrapper<VDSFontCategory.DefaultTitle>
public typealias FontCategoryBody = DecodableDefault.Wrapper<VDSFontCategory.DefaultBody>
public typealias FontCategoryMicro = DecodableDefault.Wrapper<VDSFontCategory.DefaultMicro>
public typealias FontWeightBold = DecodableDefault.Wrapper<VDSFontWeight.DefaultBold>
public typealias FontWeightRegular = DecodableDefault.Wrapper<VDSFontWeight.DefaultRegular>
public typealias FontSize2XLarge = DecodableDefault.Wrapper<VDSFontSize.Default2XLarge>
public typealias FontSizeXLarge = DecodableDefault.Wrapper<VDSFontSize.DefaultXLarge>
public typealias FontSizeLarge = DecodableDefault.Wrapper<VDSFontSize.DefaultLarge>
public typealias FontSizeMedium = DecodableDefault.Wrapper<VDSFontSize.DefaultMedium>
public typealias FontSizeSmall = DecodableDefault.Wrapper<VDSFontSize.DefaultSmall>
public typealias FontSizeXSmall = DecodableDefault.Wrapper<VDSFontSize.DefaultXSmall>
public typealias TextPositionLeft = DecodableDefault.Wrapper<VDSTextPosition.DefaultLeft>
public typealias TextPositionRight = DecodableDefault.Wrapper<VDSTextPosition.DefaultRight>
public typealias TextPositionCenter = DecodableDefault.Wrapper<VDSTextPosition.DefaultCenter>
public struct VDSToggle {
public typealias OffText = DecodableDefault.Wrapper<VDS.Toggle.DefaultOffText>
public typealias OnText = DecodableDefault.Wrapper<VDS.Toggle.DefaultOnText>
}
// public struct VDSToggle {
// public typealias OffText = DecodableDefault.Wrapper<VDS.VDSToggle.DefaultOffText>
// public typealias OnText = DecodableDefault.Wrapper<VDS.VDSToggle.DefaultOnText>
// }
}

View File

@ -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"
}
]
}

View File

@ -54,8 +54,8 @@ open class TestToggle: ToggleBase<TestToggleModel>, 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<TestToggleModel>, 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]?) {

View File

@ -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)
}

View File

@ -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
vds_ios https://gitlab.verizon.com/BPHV_MIPS/vds_ios develop