Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
0391962ac7
commit
1146ba0b8c
4
.gitignore
vendored
4
.gitignore
vendored
@ -11,8 +11,8 @@ mvm_core
|
||||
mfprepayshop_ios
|
||||
mvm_core_ui
|
||||
mvmreactnative
|
||||
vds
|
||||
VDSSample
|
||||
vds_ios
|
||||
vds_ios_sample
|
||||
|
||||
# frameworks
|
||||
contentTransferFramework.framework
|
||||
|
||||
5
JSONCreator.xcworkspace/contents.xcworkspacedata
generated
5
JSONCreator.xcworkspace/contents.xcworkspacedata
generated
@ -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">
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
@ -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>
|
||||
@ -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() ?? []
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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 { }
|
||||
@ -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>>
|
||||
@ -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> { [] }
|
||||
}
|
||||
|
||||
|
||||
@ -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 {}
|
||||
|
||||
|
||||
@ -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))
|
||||
}
|
||||
}
|
||||
@ -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 { }
|
||||
|
||||
@ -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 {}
|
||||
|
||||
|
||||
@ -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 {}
|
||||
@ -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 {}
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -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))
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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>
|
||||
// }
|
||||
}
|
||||
|
||||
30
JSONCreator_iOS/JSONCreator/JSON/Samples/Wifi/TestModel.json
Normal file
30
JSONCreator_iOS/JSONCreator/JSON/Samples/Wifi/TestModel.json
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -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]?) {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
Loading…
Reference in New Issue
Block a user