update with new code, move core code to mvmcore
This commit is contained in:
parent
a256bfab1b
commit
16c7b61108
@ -39,6 +39,13 @@
|
|||||||
8876D5F31FB50AB000EB2E3D /* UIFont+MFSpacing.m in Sources */ = {isa = PBXBuildFile; fileRef = 8876D5E51FB50AB000EB2E3D /* UIFont+MFSpacing.m */; };
|
8876D5F31FB50AB000EB2E3D /* UIFont+MFSpacing.m in Sources */ = {isa = PBXBuildFile; fileRef = 8876D5E51FB50AB000EB2E3D /* UIFont+MFSpacing.m */; };
|
||||||
8876D5F41FB50AB000EB2E3D /* UILabel+MFCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = 8876D5E61FB50AB000EB2E3D /* UILabel+MFCustom.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
8876D5F41FB50AB000EB2E3D /* UILabel+MFCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = 8876D5E61FB50AB000EB2E3D /* UILabel+MFCustom.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
8876D5F51FB50AB000EB2E3D /* UILabel+MFCustom.m in Sources */ = {isa = PBXBuildFile; fileRef = 8876D5E71FB50AB000EB2E3D /* UILabel+MFCustom.m */; };
|
8876D5F51FB50AB000EB2E3D /* UILabel+MFCustom.m in Sources */ = {isa = PBXBuildFile; fileRef = 8876D5E71FB50AB000EB2E3D /* UILabel+MFCustom.m */; };
|
||||||
|
946EE1A3237B59C30036751F /* Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 946EE1A2237B59C30036751F /* Model.swift */; };
|
||||||
|
946EE1A7237B5B1C0036751F /* ModelRegistry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 946EE1A6237B5B1C0036751F /* ModelRegistry.swift */; };
|
||||||
|
946EE1AB237B5C940036751F /* Decoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 946EE1AA237B5C940036751F /* Decoder.swift */; };
|
||||||
|
946EE1B0237B5EF70036751F /* JSONHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 946EE1AF237B5EF70036751F /* JSONHelper.swift */; };
|
||||||
|
946EE1B2237B5F260036751F /* JSONValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 946EE1B1237B5F260036751F /* JSONValue.swift */; };
|
||||||
|
946EE1B4237B619D0036751F /* Encoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 946EE1B3237B619D0036751F /* Encoder.swift */; };
|
||||||
|
946EE1BC237B691A0036751F /* ActionMapModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 946EE1BB237B691A0036751F /* ActionMapModel.swift */; };
|
||||||
A332F33F20C7231700DCD9D9 /* MVMCoreViewControllerAnimatedTransitioning.h in Headers */ = {isa = PBXBuildFile; fileRef = A332F33E20C7231600DCD9D9 /* MVMCoreViewControllerAnimatedTransitioning.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
A332F33F20C7231700DCD9D9 /* MVMCoreViewControllerAnimatedTransitioning.h in Headers */ = {isa = PBXBuildFile; fileRef = A332F33E20C7231600DCD9D9 /* MVMCoreViewControllerAnimatedTransitioning.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
AF1201832108C9B400E2F592 /* MVMCoreViewManagerViewControllerProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = AF1201812108C9B400E2F592 /* MVMCoreViewManagerViewControllerProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
AF1201832108C9B400E2F592 /* MVMCoreViewManagerViewControllerProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = AF1201812108C9B400E2F592 /* MVMCoreViewManagerViewControllerProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
AF26DDAE1FCE6A37004E8F65 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = AF26DDB01FCE6A37004E8F65 /* Localizable.strings */; };
|
AF26DDAE1FCE6A37004E8F65 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = AF26DDB01FCE6A37004E8F65 /* Localizable.strings */; };
|
||||||
@ -168,6 +175,13 @@
|
|||||||
8876D5E51FB50AB000EB2E3D /* UIFont+MFSpacing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIFont+MFSpacing.m"; sourceTree = "<group>"; };
|
8876D5E51FB50AB000EB2E3D /* UIFont+MFSpacing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIFont+MFSpacing.m"; sourceTree = "<group>"; };
|
||||||
8876D5E61FB50AB000EB2E3D /* UILabel+MFCustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UILabel+MFCustom.h"; sourceTree = "<group>"; };
|
8876D5E61FB50AB000EB2E3D /* UILabel+MFCustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UILabel+MFCustom.h"; sourceTree = "<group>"; };
|
||||||
8876D5E71FB50AB000EB2E3D /* UILabel+MFCustom.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UILabel+MFCustom.m"; sourceTree = "<group>"; };
|
8876D5E71FB50AB000EB2E3D /* UILabel+MFCustom.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UILabel+MFCustom.m"; sourceTree = "<group>"; };
|
||||||
|
946EE1A2237B59C30036751F /* Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Model.swift; sourceTree = "<group>"; };
|
||||||
|
946EE1A6237B5B1C0036751F /* ModelRegistry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelRegistry.swift; sourceTree = "<group>"; };
|
||||||
|
946EE1AA237B5C940036751F /* Decoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Decoder.swift; sourceTree = "<group>"; };
|
||||||
|
946EE1AF237B5EF70036751F /* JSONHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONHelper.swift; sourceTree = "<group>"; };
|
||||||
|
946EE1B1237B5F260036751F /* JSONValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONValue.swift; sourceTree = "<group>"; };
|
||||||
|
946EE1B3237B619D0036751F /* Encoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Encoder.swift; sourceTree = "<group>"; };
|
||||||
|
946EE1BB237B691A0036751F /* ActionMapModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionMapModel.swift; sourceTree = "<group>"; };
|
||||||
A332F33E20C7231600DCD9D9 /* MVMCoreViewControllerAnimatedTransitioning.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreViewControllerAnimatedTransitioning.h; sourceTree = "<group>"; };
|
A332F33E20C7231600DCD9D9 /* MVMCoreViewControllerAnimatedTransitioning.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreViewControllerAnimatedTransitioning.h; sourceTree = "<group>"; };
|
||||||
AF1201812108C9B400E2F592 /* MVMCoreViewManagerViewControllerProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreViewManagerViewControllerProtocol.h; sourceTree = "<group>"; };
|
AF1201812108C9B400E2F592 /* MVMCoreViewManagerViewControllerProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreViewManagerViewControllerProtocol.h; sourceTree = "<group>"; };
|
||||||
AF26DDAF1FCE6A37004E8F65 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
AF26DDAF1FCE6A37004E8F65 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
@ -310,6 +324,7 @@
|
|||||||
8876D5CB1FB50A9E00EB2E3D /* MVMCore */ = {
|
8876D5CB1FB50A9E00EB2E3D /* MVMCore */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
946EE19B237B4DB80036751F /* Models */,
|
||||||
AFBB96311FBA341E0008D868 /* Constants */,
|
AFBB96311FBA341E0008D868 /* Constants */,
|
||||||
8876D5D41FB50AAB00EB2E3D /* Utility */,
|
8876D5D41FB50AAB00EB2E3D /* Utility */,
|
||||||
AF43A7191FC5BE9E008E9347 /* MainProtocols */,
|
AF43A7191FC5BE9E008E9347 /* MainProtocols */,
|
||||||
@ -363,6 +378,52 @@
|
|||||||
path = Categories;
|
path = Categories;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
946EE19B237B4DB80036751F /* Models */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
946EE1B6237B66630036751F /* ActionType */,
|
||||||
|
946EE1A9237B5C720036751F /* Extensions */,
|
||||||
|
946EE1A8237B5C650036751F /* Model */,
|
||||||
|
946EE1AC237B5CB10036751F /* JSON */,
|
||||||
|
);
|
||||||
|
path = Models;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
946EE1A8237B5C650036751F /* Model */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
946EE1A2237B59C30036751F /* Model.swift */,
|
||||||
|
946EE1A6237B5B1C0036751F /* ModelRegistry.swift */,
|
||||||
|
);
|
||||||
|
path = Model;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
946EE1A9237B5C720036751F /* Extensions */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
946EE1AA237B5C940036751F /* Decoder.swift */,
|
||||||
|
946EE1B3237B619D0036751F /* Encoder.swift */,
|
||||||
|
);
|
||||||
|
path = Extensions;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
946EE1AC237B5CB10036751F /* JSON */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
946EE1AF237B5EF70036751F /* JSONHelper.swift */,
|
||||||
|
946EE1B1237B5F260036751F /* JSONValue.swift */,
|
||||||
|
);
|
||||||
|
path = JSON;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
946EE1B6237B66630036751F /* ActionType */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
946EE1BB237B691A0036751F /* ActionMapModel.swift */,
|
||||||
|
);
|
||||||
|
path = ActionType;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
AF26DDAB1FCE5CF2004E8F65 /* Strings */ = {
|
AF26DDAB1FCE5CF2004E8F65 /* Strings */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -767,6 +828,7 @@
|
|||||||
files = (
|
files = (
|
||||||
AFED77A71FCCA29400BAE689 /* MVMCoreViewControllerProgrammaticMappingObject.m in Sources */,
|
AFED77A71FCCA29400BAE689 /* MVMCoreViewControllerProgrammaticMappingObject.m in Sources */,
|
||||||
AFBB96A01FBA3A9A0008D868 /* MVMCoreAlertOperation.m in Sources */,
|
AFBB96A01FBA3A9A0008D868 /* MVMCoreAlertOperation.m in Sources */,
|
||||||
|
946EE1A7237B5B1C0036751F /* ModelRegistry.swift in Sources */,
|
||||||
AFBB96641FBA3A570008D868 /* MVMCoreLoadHandler.m in Sources */,
|
AFBB96641FBA3A570008D868 /* MVMCoreLoadHandler.m in Sources */,
|
||||||
AFFCFA671FCCC0D700FD0730 /* MVMCoreLoadingOverlayHandler.m in Sources */,
|
AFFCFA671FCCC0D700FD0730 /* MVMCoreLoadingOverlayHandler.m in Sources */,
|
||||||
AFBB968E1FBA3A9A0008D868 /* MVMCoreNavigationHandler.m in Sources */,
|
AFBB968E1FBA3A9A0008D868 /* MVMCoreNavigationHandler.m in Sources */,
|
||||||
@ -782,10 +844,14 @@
|
|||||||
D282AAB62240085300C46919 /* MVMCoreGetterUtility+Extension.swift in Sources */,
|
D282AAB62240085300C46919 /* MVMCoreGetterUtility+Extension.swift in Sources */,
|
||||||
AFBB965F1FBA3A570008D868 /* MFFreebeeOperation.m in Sources */,
|
AFBB965F1FBA3A570008D868 /* MFFreebeeOperation.m in Sources */,
|
||||||
AFBB96901FBA3A9A0008D868 /* MVMCoreNavigationObject.m in Sources */,
|
AFBB96901FBA3A9A0008D868 /* MVMCoreNavigationObject.m in Sources */,
|
||||||
|
946EE1AB237B5C940036751F /* Decoder.swift in Sources */,
|
||||||
|
946EE1BC237B691A0036751F /* ActionMapModel.swift in Sources */,
|
||||||
AFBB96A61FBA3A9A0008D868 /* MVMCoreTopAlertOperation.m in Sources */,
|
AFBB96A61FBA3A9A0008D868 /* MVMCoreTopAlertOperation.m in Sources */,
|
||||||
881D26931FCC9D180079C521 /* MVMCoreErrorObject.m in Sources */,
|
881D26931FCC9D180079C521 /* MVMCoreErrorObject.m in Sources */,
|
||||||
|
946EE1B0237B5EF70036751F /* JSONHelper.swift in Sources */,
|
||||||
30349BF21FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m in Sources */,
|
30349BF21FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m in Sources */,
|
||||||
8876D5E91FB50AB000EB2E3D /* NSArray+MFConvenience.m in Sources */,
|
8876D5E91FB50AB000EB2E3D /* NSArray+MFConvenience.m in Sources */,
|
||||||
|
946EE1B2237B5F260036751F /* JSONValue.swift in Sources */,
|
||||||
AFBB96971FBA3A9A0008D868 /* MVMCorePresentViewControllerOperation.m in Sources */,
|
AFBB96971FBA3A9A0008D868 /* MVMCorePresentViewControllerOperation.m in Sources */,
|
||||||
AFBB96581FBA3A570008D868 /* FreeBeeAuthObject.m in Sources */,
|
AFBB96581FBA3A570008D868 /* FreeBeeAuthObject.m in Sources */,
|
||||||
AF43A5781FBA5B7C008E9347 /* MVMCoreJSONConstants.m in Sources */,
|
AF43A5781FBA5B7C008E9347 /* MVMCoreJSONConstants.m in Sources */,
|
||||||
@ -806,12 +872,14 @@
|
|||||||
AF43A7071FC4D7A2008E9347 /* MVMCoreObject.m in Sources */,
|
AF43A7071FC4D7A2008E9347 /* MVMCoreObject.m in Sources */,
|
||||||
01DF561421F90ADC00CC099B /* Dictionary+MFConvenience.swift in Sources */,
|
01DF561421F90ADC00CC099B /* Dictionary+MFConvenience.swift in Sources */,
|
||||||
AFBB96B11FBA3B590008D868 /* MVMCoreDispatchUtility.m in Sources */,
|
AFBB96B11FBA3B590008D868 /* MVMCoreDispatchUtility.m in Sources */,
|
||||||
|
946EE1A3237B59C30036751F /* Model.swift in Sources */,
|
||||||
AFBB965B1FBA3A570008D868 /* FreeBeeUrlObject.m in Sources */,
|
AFBB965B1FBA3A570008D868 /* FreeBeeUrlObject.m in Sources */,
|
||||||
AFEA17A9209B6A1C00BC6740 /* MVMCoreBlockOperation.m in Sources */,
|
AFEA17A9209B6A1C00BC6740 /* MVMCoreBlockOperation.m in Sources */,
|
||||||
AF43A70A1FC4F415008E9347 /* MVMCoreCache.m in Sources */,
|
AF43A70A1FC4F415008E9347 /* MVMCoreCache.m in Sources */,
|
||||||
AF43A6FF1FBE3252008E9347 /* Reachability.m in Sources */,
|
AF43A6FF1FBE3252008E9347 /* Reachability.m in Sources */,
|
||||||
AFBB96921FBA3A9A0008D868 /* MVMCoreNavigationOperation.m in Sources */,
|
AFBB96921FBA3A9A0008D868 /* MVMCoreNavigationOperation.m in Sources */,
|
||||||
AFBB96611FBA3A570008D868 /* MVMCoreLoadObject.m in Sources */,
|
AFBB96611FBA3A570008D868 /* MVMCoreLoadObject.m in Sources */,
|
||||||
|
946EE1B4237B619D0036751F /* Encoder.swift in Sources */,
|
||||||
AFBB96941FBA3A9A0008D868 /* MVMCorePresentAnimationOperation.m in Sources */,
|
AFBB96941FBA3A9A0008D868 /* MVMCorePresentAnimationOperation.m in Sources */,
|
||||||
AF43A5841FBB66DE008E9347 /* MVMCoreConstants.m in Sources */,
|
AF43A5841FBB66DE008E9347 /* MVMCoreConstants.m in Sources */,
|
||||||
AFBB966A1FBA3A570008D868 /* MVMCoreLoadRequestOperation.m in Sources */,
|
AFBB966A1FBA3A570008D868 /* MVMCoreLoadRequestOperation.m in Sources */,
|
||||||
|
|||||||
19
MVMCore/MVMCore/Models/ActionType/ActionMapModel.swift
Normal file
19
MVMCore/MVMCore/Models/ActionType/ActionMapModel.swift
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// ActionMapModel.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Suresh, Kamlesh on 10/3/19.
|
||||||
|
// Copyright © 2019 Suresh, Kamlesh. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objcMembers public class ActionMapModel: Codable {
|
||||||
|
public var actionType: String?
|
||||||
|
public var pageType: String?
|
||||||
|
|
||||||
|
public init(actionType: String?, pageType: String?) {
|
||||||
|
self.actionType = actionType
|
||||||
|
self.pageType = pageType
|
||||||
|
}
|
||||||
|
}
|
||||||
55
MVMCore/MVMCore/Models/Extensions/Decoder.swift
Normal file
55
MVMCore/MVMCore/Models/Extensions/Decoder.swift
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
//
|
||||||
|
// Decoder.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Matt Brunce on 11/12/19.
|
||||||
|
// Copyright © 2019 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol AnyDecoder {
|
||||||
|
func decode<T: Decodable>(_ type: T.Type, from data: Data) throws -> T
|
||||||
|
}
|
||||||
|
|
||||||
|
extension JSONDecoder: AnyDecoder {}
|
||||||
|
extension PropertyListDecoder: AnyDecoder {}
|
||||||
|
|
||||||
|
extension Data {
|
||||||
|
public func decode<T: Decodable>(using decoder: AnyDecoder = JSONDecoder()) throws -> T {
|
||||||
|
return try decoder.decode(T.self, from: self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension KeyedDecodingContainerProtocol {
|
||||||
|
public func decode<T: Decodable>(forKey key: Key) throws -> T {
|
||||||
|
return try decode(T.self, forKey: key)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func decode<T: Decodable>(
|
||||||
|
forKey key: Key,
|
||||||
|
default defaultExpression: @autoclosure () -> T
|
||||||
|
) throws -> T {
|
||||||
|
return try decodeIfPresent(T.self, forKey: key) ?? defaultExpression()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Decodable {
|
||||||
|
public static func decode(fileName: String, bundle: Bundle = Bundle.main) throws -> Self {
|
||||||
|
guard let path = bundle.path(forResource: fileName, ofType: ".json") else {
|
||||||
|
throw JSONError.pathNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let jsonData = try? Data(contentsOf: URL(fileURLWithPath: path)) else {
|
||||||
|
throw JSONError.data(path: path)
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
return try jsonData.decode()
|
||||||
|
} catch {
|
||||||
|
throw JSONError.other(error: error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
37
MVMCore/MVMCore/Models/Extensions/Encoder.swift
Normal file
37
MVMCore/MVMCore/Models/Extensions/Encoder.swift
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
//
|
||||||
|
// Encoder.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Matt Brunce on 11/12/19.
|
||||||
|
// Copyright © 2019 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol AnyEncoder {
|
||||||
|
func encode<T: Encodable>(_ value: T) throws -> Data
|
||||||
|
}
|
||||||
|
|
||||||
|
extension JSONEncoder: AnyEncoder {}
|
||||||
|
extension PropertyListEncoder: AnyEncoder {}
|
||||||
|
|
||||||
|
extension Encodable {
|
||||||
|
public func encode(using encoder: AnyEncoder = JSONEncoder()) throws -> Data {
|
||||||
|
return try encoder.encode(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func toJSON() -> JSONDictionary? {
|
||||||
|
guard let data = try? self.encode() else { return nil }
|
||||||
|
return (try? JSONSerialization.jsonObject(with: data, options: .allowFragments)).flatMap { $0 as? JSONDictionary }
|
||||||
|
}
|
||||||
|
|
||||||
|
public func toJSONString() -> String? {
|
||||||
|
guard let json = self.toJSON(),
|
||||||
|
let data = try? JSONSerialization.data(withJSONObject: json, options: .prettyPrinted),
|
||||||
|
let string = String(data: data, encoding: .utf8) else{
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
18
MVMCore/MVMCore/Models/JSON/JSONHelper.swift
Normal file
18
MVMCore/MVMCore/Models/JSON/JSONHelper.swift
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// JSONHelper.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Matt Brunce on 11/12/19.
|
||||||
|
// Copyright © 2019 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public typealias JSONArray = [[String: Any]]
|
||||||
|
public typealias JSONDictionary = [String: Any]
|
||||||
|
|
||||||
|
public enum JSONError: Error {
|
||||||
|
case pathNotFound
|
||||||
|
case data(path: String)
|
||||||
|
case other(error: Error)
|
||||||
|
}
|
||||||
132
MVMCore/MVMCore/Models/JSON/JSONValue.swift
Normal file
132
MVMCore/MVMCore/Models/JSON/JSONValue.swift
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
//
|
||||||
|
// JSONValue.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Matt Brunce on 11/12/19.
|
||||||
|
// Copyright © 2019 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public typealias JSONValueArray = [[String: JSONValue]]
|
||||||
|
public typealias JSONValueDictionary = [String: JSONValue]
|
||||||
|
|
||||||
|
public enum JSONValueError: Error {
|
||||||
|
case encode
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Optional {
|
||||||
|
func or(_ other: Optional) -> Optional {
|
||||||
|
switch self {
|
||||||
|
case .none: return other
|
||||||
|
case .some: return self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolve(with error: @autoclosure () -> Error) throws -> Wrapped {
|
||||||
|
switch self {
|
||||||
|
case .none: throw error()
|
||||||
|
case .some(let wrapped): return wrapped
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum JSONValue: Codable, Equatable {
|
||||||
|
case string(String)
|
||||||
|
case int(Int)
|
||||||
|
case double(Double)
|
||||||
|
case bool(Bool)
|
||||||
|
case object([String: JSONValue])
|
||||||
|
case array([JSONValue])
|
||||||
|
case null
|
||||||
|
public init(from decoder: Decoder) throws {
|
||||||
|
let container = try decoder.singleValueContainer()
|
||||||
|
let value = ((try? container.decode(String.self)).map(JSONValue.string))
|
||||||
|
.or((try? container.decode(Int.self)).map(JSONValue.int))
|
||||||
|
.or((try? container.decode(Double.self)).map(JSONValue.double))
|
||||||
|
.or((try? container.decode(Bool.self)).map(JSONValue.bool))
|
||||||
|
.or((try? container.decode([String: JSONValue].self)).map(JSONValue.object))
|
||||||
|
.or((try? container.decode([JSONValue].self)).map(JSONValue.array))
|
||||||
|
|
||||||
|
self = value ?? JSONValue.null
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode<T: Decodable>() throws -> T {
|
||||||
|
let encoded = try JSONEncoder().encode(self)
|
||||||
|
return try JSONDecoder().decode(T.self, from: encoded)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.singleValueContainer()
|
||||||
|
switch self {
|
||||||
|
case .string(let string): try container.encode(string)
|
||||||
|
case .int(let int): try container.encode(int)
|
||||||
|
case .double(let double): try container.encode(double)
|
||||||
|
case .bool(let bool): try container.encode(bool)
|
||||||
|
case .object(let object): try container.encode(object)
|
||||||
|
case .array(let array): try container.encode(array)
|
||||||
|
case .null: break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func ==(lhs: JSONValue, rhs: JSONValue) -> Bool {
|
||||||
|
let ld = try? lhs.encode()
|
||||||
|
let rd = try? lhs.encode()
|
||||||
|
return ld == rd
|
||||||
|
}
|
||||||
|
|
||||||
|
extension JSONValue: ExpressibleByStringLiteral {
|
||||||
|
public init(stringLiteral value: String) {
|
||||||
|
self = .string(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension JSONValue: ExpressibleByIntegerLiteral {
|
||||||
|
public init(integerLiteral value: Int) {
|
||||||
|
self = .int(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension JSONValue: ExpressibleByFloatLiteral {
|
||||||
|
public init(floatLiteral value: Double) {
|
||||||
|
self = .double(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension JSONValue: ExpressibleByBooleanLiteral {
|
||||||
|
public init(booleanLiteral value: Bool) {
|
||||||
|
self = .bool(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension JSONValue: ExpressibleByArrayLiteral {
|
||||||
|
public init(arrayLiteral elements: JSONValue...) {
|
||||||
|
self = .array(elements)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension JSONValue: ExpressibleByDictionaryLiteral {
|
||||||
|
public init(dictionaryLiteral elements: (String, JSONValue)...) {
|
||||||
|
self = .object([String: JSONValue](uniqueKeysWithValues: elements))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Dictionary where Key == String, Value == Any {
|
||||||
|
public func toJSONValue() throws -> [String: JSONValue] {
|
||||||
|
let data = try JSONSerialization.data(withJSONObject: self, options: .prettyPrinted)
|
||||||
|
return try JSONDecoder().decode([String:JSONValue].self, from: data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Dictionary where Key == String, Value == JSONValue {
|
||||||
|
public func toJSONObject() throws -> JSONDictionary {
|
||||||
|
let encoded = try JSONEncoder().encode(self)
|
||||||
|
guard let json = try JSONSerialization.jsonObject(with: encoded, options: .mutableContainers) as? JSONDictionary else {
|
||||||
|
throw JSONValueError.encode
|
||||||
|
}
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
16
MVMCore/MVMCore/Models/Model/Model.swift
Normal file
16
MVMCore/MVMCore/Models/Model/Model.swift
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// Model.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Matt Brunce on 11/12/19.
|
||||||
|
// Copyright © 2019 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol Model: Codable {
|
||||||
|
|
||||||
|
static var identifier: String { get set }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
97
MVMCore/MVMCore/Models/Model/ModelRegistry.swift
Normal file
97
MVMCore/MVMCore/Models/Model/ModelRegistry.swift
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
//
|
||||||
|
// ModelRegistry.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Matt Brunce on 11/12/19.
|
||||||
|
// Copyright © 2019 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public struct ModelRegistry {
|
||||||
|
public enum Error: Swift.Error {
|
||||||
|
case keyNotFound
|
||||||
|
case encoderError
|
||||||
|
case decoderError
|
||||||
|
case decoderErrorObjectNotPresent
|
||||||
|
case decoderErrorModelNotMapped
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate static var types = [String: Model.Type]()
|
||||||
|
|
||||||
|
public static func register<M: Model>(_ type: M.Type) {
|
||||||
|
types[M.identifier] = type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extension KeyedDecodingContainer where Key : CodingKey{
|
||||||
|
public enum TypeCodingKey: String, CodingKey {
|
||||||
|
//need to discuss this the enum
|
||||||
|
case moleculeName
|
||||||
|
case actionMap
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: - Decode
|
||||||
|
public func decode<T>(codingKey: KeyedDecodingContainer<K>.Key, typeCodingKey: TypeCodingKey) throws -> T {
|
||||||
|
guard let model: Model = try decodeIfPresent(codingKey: codingKey, typeCodingKey: typeCodingKey) else {
|
||||||
|
throw ModelRegistry.Error.decoderErrorObjectNotPresent
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let m = model as? T else {
|
||||||
|
throw ModelRegistry.Error.decoderError
|
||||||
|
}
|
||||||
|
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
public func decode(codingKey: KeyedDecodingContainer<K>.Key) throws -> ActionMapModel {
|
||||||
|
return try decode(codingKey: codingKey, typeCodingKey: .actionMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: - DecodeIfPresent
|
||||||
|
public func decodeIfPresent<T>(codingKey: KeyedDecodingContainer<K>.Key, typeCodingKey: TypeCodingKey) throws -> T? {
|
||||||
|
|
||||||
|
//get the type string
|
||||||
|
let meta = try self.nestedContainer(keyedBy: TypeCodingKey.self, forKey: codingKey)
|
||||||
|
guard let type = try meta.decodeIfPresent(String.self, forKey: typeCodingKey) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//get the type
|
||||||
|
guard let found = ModelRegistry.types[type] else {
|
||||||
|
throw ModelRegistry.Error.decoderErrorModelNotMapped
|
||||||
|
}
|
||||||
|
|
||||||
|
//get the decoder for the propertyKey
|
||||||
|
let decoder = try self.superDecoder(forKey: codingKey)
|
||||||
|
|
||||||
|
//decode the type using the decoder
|
||||||
|
let model = try found.init(from: decoder)
|
||||||
|
|
||||||
|
guard let m = model as? T else {
|
||||||
|
throw ModelRegistry.Error.decoderError
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
public func decodeIfPresent(codingKey: KeyedDecodingContainer<K>.Key) throws -> ActionMapModel? {
|
||||||
|
return try decodeIfPresent(codingKey: codingKey, typeCodingKey: .actionMap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extension KeyedEncodingContainer where Key : CodingKey {
|
||||||
|
|
||||||
|
public mutating func encodeIfPresent(_ value: Model?, forKey key: KeyedEncodingContainer<K>.Key) throws {
|
||||||
|
if let v = value {
|
||||||
|
let encoder = self.superEncoder(forKey: key)
|
||||||
|
try v.encode(to: encoder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public mutating func encode(_ value: Model, forKey key: KeyedEncodingContainer<K>.Key) throws {
|
||||||
|
let encoder = self.superEncoder(forKey: key)
|
||||||
|
try value.encode(to: encoder)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user