integrating changes to make fan out instance models into categories due to name conflicts
This commit is contained in:
parent
605959a58f
commit
53e05ca42f
@ -31,6 +31,7 @@
|
|||||||
01F2A04E23A82CF500D954D8 /* ActionPopupModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F2A04D23A82CF500D954D8 /* ActionPopupModel.swift */; };
|
01F2A04E23A82CF500D954D8 /* ActionPopupModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F2A04D23A82CF500D954D8 /* ActionPopupModel.swift */; };
|
||||||
01F2A05023A82D0800D954D8 /* ActionTopAlertModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F2A04F23A82D0800D954D8 /* ActionTopAlertModel.swift */; };
|
01F2A05023A82D0800D954D8 /* ActionTopAlertModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F2A04F23A82D0800D954D8 /* ActionTopAlertModel.swift */; };
|
||||||
01F2A05223A8325100D954D8 /* ModelMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F2A05123A8325100D954D8 /* ModelMapping.swift */; };
|
01F2A05223A8325100D954D8 /* ModelMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F2A05123A8325100D954D8 /* ModelMapping.swift */; };
|
||||||
|
0A42538F23F3414800554656 /* Codable+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A42538E23F3414800554656 /* Codable+Helpers.swift */; };
|
||||||
30349BF11FCCA78A00546A1E /* MVMCoreSessionTimeHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 30349BEF1FCCA78A00546A1E /* MVMCoreSessionTimeHandler.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
30349BF11FCCA78A00546A1E /* MVMCoreSessionTimeHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 30349BEF1FCCA78A00546A1E /* MVMCoreSessionTimeHandler.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
30349BF21FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 30349BF01FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m */; };
|
30349BF21FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 30349BF01FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m */; };
|
||||||
881D26931FCC9D180079C521 /* MVMCoreErrorObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 881D268F1FCC9D180079C521 /* MVMCoreErrorObject.m */; };
|
881D26931FCC9D180079C521 /* MVMCoreErrorObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 881D268F1FCC9D180079C521 /* MVMCoreErrorObject.m */; };
|
||||||
@ -177,6 +178,7 @@
|
|||||||
01F2A05123A8325100D954D8 /* ModelMapping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelMapping.swift; sourceTree = "<group>"; };
|
01F2A05123A8325100D954D8 /* ModelMapping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelMapping.swift; sourceTree = "<group>"; };
|
||||||
0A11030B20864F94008ADD90 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
|
0A11030B20864F94008ADD90 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
0A11030C20864F9A008ADD90 /* es-MX */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-MX"; path = "es-MX.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
0A11030C20864F9A008ADD90 /* es-MX */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-MX"; path = "es-MX.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||||
|
0A42538E23F3414800554656 /* Codable+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Codable+Helpers.swift"; sourceTree = "<group>"; };
|
||||||
30349BEF1FCCA78A00546A1E /* MVMCoreSessionTimeHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreSessionTimeHandler.h; sourceTree = "<group>"; };
|
30349BEF1FCCA78A00546A1E /* MVMCoreSessionTimeHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreSessionTimeHandler.h; sourceTree = "<group>"; };
|
||||||
30349BF01FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreSessionTimeHandler.m; sourceTree = "<group>"; };
|
30349BF01FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreSessionTimeHandler.m; sourceTree = "<group>"; };
|
||||||
881D268F1FCC9D180079C521 /* MVMCoreErrorObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreErrorObject.m; sourceTree = "<group>"; };
|
881D268F1FCC9D180079C521 /* MVMCoreErrorObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreErrorObject.m; sourceTree = "<group>"; };
|
||||||
@ -429,6 +431,7 @@
|
|||||||
children = (
|
children = (
|
||||||
946EE1AA237B5C940036751F /* Decoder.swift */,
|
946EE1AA237B5C940036751F /* Decoder.swift */,
|
||||||
946EE1B3237B619D0036751F /* Encoder.swift */,
|
946EE1B3237B619D0036751F /* Encoder.swift */,
|
||||||
|
0A42538E23F3414800554656 /* Codable+Helpers.swift */,
|
||||||
);
|
);
|
||||||
path = Extensions;
|
path = Extensions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -894,6 +897,7 @@
|
|||||||
946EE1AB237B5C940036751F /* Decoder.swift in Sources */,
|
946EE1AB237B5C940036751F /* Decoder.swift in Sources */,
|
||||||
946EE1BC237B691A0036751F /* ActionOpenPageModel.swift in Sources */,
|
946EE1BC237B691A0036751F /* ActionOpenPageModel.swift in Sources */,
|
||||||
AFBB96A61FBA3A9A0008D868 /* MVMCoreTopAlertOperation.m in Sources */,
|
AFBB96A61FBA3A9A0008D868 /* MVMCoreTopAlertOperation.m in Sources */,
|
||||||
|
0A42538F23F3414800554656 /* Codable+Helpers.swift in Sources */,
|
||||||
881D26931FCC9D180079C521 /* MVMCoreErrorObject.m in Sources */,
|
881D26931FCC9D180079C521 /* MVMCoreErrorObject.m in Sources */,
|
||||||
946EE1B0237B5EF70036751F /* JSONHelper.swift in Sources */,
|
946EE1B0237B5EF70036751F /* JSONHelper.swift in Sources */,
|
||||||
30349BF21FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m in Sources */,
|
30349BF21FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m in Sources */,
|
||||||
|
|||||||
@ -13,10 +13,29 @@ public enum ActionCodingKey: String, CodingKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public protocol ActionModelProtocol: Model {
|
public protocol ActionModelProtocol: Model {
|
||||||
|
|
||||||
var actionType: String? { get set }
|
var actionType: String? { get set }
|
||||||
var extraParameters: JSONValueDictionary? { get set }
|
var extraParameters: JSONValueDictionary? { get set }
|
||||||
var analyticsData: JSONValueDictionary? { get set }
|
var analyticsData: JSONValueDictionary? { get set }
|
||||||
|
|
||||||
|
static var categoryName: String { get }
|
||||||
|
static var categoryCodingKey: String { get }
|
||||||
|
|
||||||
// Temporary fix till server changes
|
// Temporary fix till server changes
|
||||||
var title: String? { get set }
|
var title: String? { get set }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension ActionModelProtocol {
|
||||||
|
|
||||||
|
public var actionType: String? {
|
||||||
|
get { return Self.identifier }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static var categoryCodingKey: String {
|
||||||
|
return "actionType"
|
||||||
|
}
|
||||||
|
|
||||||
|
public static var categoryName: String {
|
||||||
|
return "\(ActionModelProtocol.self)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers public class ActionPopupModel: ActionModelProtocol {
|
@objcMembers public class ActionPopupModel: ActionModelProtocol {
|
||||||
|
|
||||||
public static var identifier: String = "popup"
|
public static var identifier: String = "popup"
|
||||||
public var actionType: String?
|
public var actionType: String?
|
||||||
public var title: String?
|
public var title: String?
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
@objcMembers public class ActionTopAlertModel: ActionModelProtocol {
|
@objcMembers public class ActionTopAlertModel: ActionModelProtocol {
|
||||||
|
|
||||||
public static var identifier: String = "topAlert"
|
public static var identifier: String = "topAlert"
|
||||||
public var actionType: String?
|
public var actionType: String?
|
||||||
public var pageType: String
|
public var pageType: String
|
||||||
|
|||||||
45
MVMCore/MVMCore/Models/Extensions/Codable+Helpers.swift
Normal file
45
MVMCore/MVMCore/Models/Extensions/Codable+Helpers.swift
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
//
|
||||||
|
// Codable+Helpers.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Kevin Christiano on 2/11/20.
|
||||||
|
// Copyright © 2020 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// MARK: - Date formatters
|
||||||
|
/// Protocol acting as a common API for all types of date formatters,
|
||||||
|
/// such as `DateFormatter` and `ISO8601DateFormatter`.
|
||||||
|
public protocol AnyDateFormatter {
|
||||||
|
/// Format a string into a date
|
||||||
|
func date(from string: String) -> Date?
|
||||||
|
/// Format a date into a string
|
||||||
|
func string(from date: Date) -> String
|
||||||
|
}
|
||||||
|
|
||||||
|
extension DateFormatter: AnyDateFormatter {}
|
||||||
|
|
||||||
|
@available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
|
||||||
|
extension ISO8601DateFormatter: AnyDateFormatter {}
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: supporting types
|
||||||
|
public struct AnyCodingKey: CodingKey {
|
||||||
|
|
||||||
|
public var stringValue: String
|
||||||
|
public var intValue: Int?
|
||||||
|
|
||||||
|
public init(_ string: String) {
|
||||||
|
stringValue = string
|
||||||
|
}
|
||||||
|
|
||||||
|
public init?(stringValue: String) {
|
||||||
|
self.stringValue = stringValue
|
||||||
|
}
|
||||||
|
|
||||||
|
public init?(intValue: Int) {
|
||||||
|
self.intValue = intValue
|
||||||
|
self.stringValue = String(intValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -10,19 +10,30 @@ import Foundation
|
|||||||
|
|
||||||
public protocol Model: Codable {
|
public protocol Model: Codable {
|
||||||
|
|
||||||
|
/// The key name of the molecule
|
||||||
static var identifier: String { get }
|
static var identifier: String { get }
|
||||||
|
|
||||||
|
/// Name of the defining object.
|
||||||
|
static var categoryName: String { get }
|
||||||
|
|
||||||
|
/// The JSON key name of the
|
||||||
|
static var categoryCodingKey: String { get }
|
||||||
|
|
||||||
/// Convenience function to decode to model using a keyed container.
|
/// Convenience function to decode to model using a keyed container.
|
||||||
static func decode<K: CodingKey>(keyedContainer: KeyedDecodingContainer<K>, codingKey: K) throws -> Self?
|
static func decode<K: CodingKey>(keyedContainer: KeyedDecodingContainer<K>, codingKey: K) throws -> Self?
|
||||||
|
|
||||||
/// Convenience function to decode to model using an unkeyed container.
|
/// Convenience function to decode to model using an unkeyed container.
|
||||||
static func decode(unkeyedContainer: inout UnkeyedDecodingContainer) throws -> Self?
|
static func decode(unkeyedContainer: inout UnkeyedDecodingContainer) throws -> Self?
|
||||||
|
|
||||||
/// Convenience function to encode model using a keyed container.
|
/// Convenience function to encode model using a keyed container.
|
||||||
func encode<K: CodingKey>(keyedContainer: inout KeyedEncodingContainer<K>, codingKey: K) throws
|
func encode<K: CodingKey>(keyedContainer: inout KeyedEncodingContainer<K>, codingKey: K) throws
|
||||||
|
|
||||||
/// Convenience function to encode model using an unkeyed container.
|
/// Convenience function to encode model using an unkeyed container.
|
||||||
func encode(unkeyedContainer: inout UnkeyedEncodingContainer) throws
|
func encode(unkeyedContainer: inout UnkeyedEncodingContainer) throws
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Model {
|
extension Model {
|
||||||
|
|
||||||
static public func decode<K: CodingKey>(keyedContainer: KeyedDecodingContainer<K>, codingKey: K) throws -> Self? {
|
static public func decode<K: CodingKey>(keyedContainer: KeyedDecodingContainer<K>, codingKey: K) throws -> Self? {
|
||||||
return try keyedContainer.decodeIfPresent(self, forKey: codingKey)
|
return try keyedContainer.decodeIfPresent(self, forKey: codingKey)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,31 +10,73 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public struct ModelRegistry {
|
public struct ModelRegistry {
|
||||||
|
|
||||||
public enum Error: Swift.Error {
|
public enum Error: Swift.Error {
|
||||||
case keyNotFound
|
case keyNotFound
|
||||||
case encoderError
|
case encoderError
|
||||||
case decoderError
|
case decoderError
|
||||||
|
case decoderOther(message: String)
|
||||||
case decoderErrorObjectNotPresent
|
case decoderErrorObjectNotPresent
|
||||||
case decoderErrorModelNotMapped
|
case decoderErrorModelNotMapped
|
||||||
|
case other(message: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
fileprivate static var types = [String: Model.Type]()
|
private struct Category {
|
||||||
|
var name: String
|
||||||
/// Register the model.
|
var codingKey: String
|
||||||
public static func register<M: Model>(_ type: M.Type) {
|
var instanceTypes: [String: Model.Type] = [:]
|
||||||
types[M.identifier] = type
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func getType(for name: String) -> Model.Type? {
|
private static var categories: [String: Category] = [:]
|
||||||
return types[name]
|
|
||||||
|
/// Registers models for Atomic use.
|
||||||
|
public static func register<M: Model>(_ type: M.Type) throws {
|
||||||
|
|
||||||
|
var category: Category
|
||||||
|
print("\n\n")
|
||||||
|
print("HI= \(M.identifier)")
|
||||||
|
print("HI= \(M.categoryName)")
|
||||||
|
print("HI= \(M.categoryCodingKey)")
|
||||||
|
print("\n\n")
|
||||||
|
if let c = categories[M.categoryName] {
|
||||||
|
category = c
|
||||||
|
} else {
|
||||||
|
category = Category(name: M.categoryName, codingKey: M.categoryCodingKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check to ensure the Category/Type combination doesn't exist.
|
||||||
|
if category.instanceTypes[M.identifier] != nil {
|
||||||
|
throw ModelRegistry.Error.other(message: "Model: \(M.identifier) already exists in Category: \(M.categoryName)")
|
||||||
|
}
|
||||||
|
|
||||||
|
category.instanceTypes[M.identifier] = type
|
||||||
|
categories[M.categoryName] = category
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func getCategory<T>(for type: T.Type) -> Category? {
|
||||||
|
return categories["\(T.self)"]
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func getType<T>(for name: String, with type: T.Type) -> Model.Type? {
|
||||||
|
return getCategory(for: type)?.instanceTypes[name]
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func getCodingKey<T>(for type: T.Type) throws -> AnyCodingKey{
|
||||||
|
guard let category = getCategory(for: type) else {
|
||||||
|
throw ModelRegistry.Error.decoderOther(message: "decodeModelsIfPresent only works for objects implementing the Model protocol")
|
||||||
|
}
|
||||||
|
|
||||||
|
return AnyCodingKey(category.codingKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension KeyedDecodingContainer where Key: CodingKey {
|
extension KeyedDecodingContainer where Key: CodingKey {
|
||||||
|
|
||||||
//MARK: - Decode
|
// MARK: - Decode
|
||||||
|
|
||||||
/// Decodes to a registered model based on the identifier
|
/// Decodes to a registered model based on the identifier
|
||||||
public func decodeModel<M, TypeKey: CodingKey>(codingKey: KeyedDecodingContainer<K>.Key, typeCodingKey: TypeKey) throws -> M {
|
public func decodeModel<M, TypeKey: CodingKey>(codingKey: KeyedDecodingContainer<K>.Key, typeCodingKey: TypeKey) throws -> M {
|
||||||
|
|
||||||
guard let model: Model = try decodeModelIfPresent(codingKey: codingKey, typeCodingKey: typeCodingKey) else {
|
guard let model: Model = try decodeModelIfPresent(codingKey: codingKey, typeCodingKey: typeCodingKey) else {
|
||||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ModelRegistry Error decoderErrorObjectNotPresent: \(codingKey)")
|
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ModelRegistry Error decoderErrorObjectNotPresent: \(codingKey)")
|
||||||
throw ModelRegistry.Error.decoderErrorObjectNotPresent
|
throw ModelRegistry.Error.decoderErrorObjectNotPresent
|
||||||
@ -48,18 +90,17 @@ extension KeyedDecodingContainer where Key: CodingKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - DecodeIfPresent
|
// MARK: - DecodeIfPresent
|
||||||
|
|
||||||
/// Decodes to a registered model based on the identifier, optional.
|
/// Decodes to a registered model based on the identifier, optional.
|
||||||
public func decodeModelIfPresent<M, TypeKey: CodingKey>(codingKey: KeyedDecodingContainer<K>.Key, typeCodingKey: TypeKey) throws -> M? {
|
public func decodeModelIfPresent<M, TypeKey: CodingKey>(codingKey: KeyedDecodingContainer<K>.Key, typeCodingKey: TypeKey) throws -> M? {
|
||||||
//get the identifier string
|
//get the identifier string
|
||||||
guard contains(codingKey),
|
guard contains(codingKey),
|
||||||
let container = try? nestedContainer(keyedBy: TypeKey.self, forKey: codingKey),
|
let container = try? nestedContainer(keyedBy: TypeKey.self, forKey: codingKey),
|
||||||
let identifier = try? container.decodeIfPresent(String.self, forKey: typeCodingKey) else {
|
let identifier = try? container.decodeIfPresent(String.self, forKey: typeCodingKey)
|
||||||
return nil
|
else { return nil }
|
||||||
}
|
|
||||||
|
|
||||||
//get the type
|
guard let type = ModelRegistry.getType(for: identifier, with: M.self) else {
|
||||||
guard let type = ModelRegistry.getType(for: identifier) else {
|
|
||||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "Model not mapped: \(identifier)")
|
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "Model not mapped: \(identifier)")
|
||||||
throw ModelRegistry.Error.decoderErrorModelNotMapped
|
throw ModelRegistry.Error.decoderErrorModelNotMapped
|
||||||
}
|
}
|
||||||
@ -78,9 +119,9 @@ extension KeyedDecodingContainer where Key: CodingKey {
|
|||||||
/// Decodes an array of registered model based on the identifiers, optional.
|
/// Decodes an array of registered model based on the identifiers, optional.
|
||||||
public func decodeModelsIfPresent<TypeKey: CodingKey>(codingKey: KeyedDecodingContainer<K>.Key, typeCodingKey: TypeKey) throws -> [Model]? {
|
public func decodeModelsIfPresent<TypeKey: CodingKey>(codingKey: KeyedDecodingContainer<K>.Key, typeCodingKey: TypeKey) throws -> [Model]? {
|
||||||
guard contains(codingKey),
|
guard contains(codingKey),
|
||||||
var container = try? nestedUnkeyedContainer(forKey: codingKey) else {
|
var container = try? nestedUnkeyedContainer(forKey: codingKey)
|
||||||
return nil
|
else { return nil }
|
||||||
}
|
|
||||||
return try container.decodeModelsIfPresent(typeCodingKey: typeCodingKey)
|
return try container.decodeModelsIfPresent(typeCodingKey: typeCodingKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,9 +137,9 @@ extension KeyedDecodingContainer where Key: CodingKey {
|
|||||||
/// Decodes an array with arrays of models based on the identifiers, optional.
|
/// Decodes an array with arrays of models based on the identifiers, optional.
|
||||||
public func decodeModels2DIfPresent<TypeKey: CodingKey>(codingKey: KeyedDecodingContainer<K>.Key, typeCodingKey: TypeKey) throws -> [[Model]]? {
|
public func decodeModels2DIfPresent<TypeKey: CodingKey>(codingKey: KeyedDecodingContainer<K>.Key, typeCodingKey: TypeKey) throws -> [[Model]]? {
|
||||||
guard contains(codingKey),
|
guard contains(codingKey),
|
||||||
var container = try? nestedUnkeyedContainer(forKey: codingKey) else {
|
var container = try? nestedUnkeyedContainer(forKey: codingKey)
|
||||||
return nil
|
else { return nil }
|
||||||
}
|
|
||||||
return try container.decodeModels2DIfPresent(typeCodingKey: typeCodingKey)
|
return try container.decodeModels2DIfPresent(typeCodingKey: typeCodingKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,40 +153,44 @@ extension KeyedDecodingContainer where Key: CodingKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension KeyedEncodingContainer where Key: CodingKey {
|
public extension KeyedEncodingContainer where Key: CodingKey {
|
||||||
|
|
||||||
/// Encodes a model, optional.
|
/// Encodes a model, optional.
|
||||||
public mutating func encodeModelIfPresent(_ value: Model?, forKey key: KeyedEncodingContainer<K>.Key) throws {
|
mutating func encodeModelIfPresent(_ value: Model?, forKey key: KeyedEncodingContainer<K>.Key) throws {
|
||||||
if let value = value {
|
if let value = value {
|
||||||
let encoder = self.superEncoder(forKey: key)
|
let encoder = superEncoder(forKey: key)
|
||||||
try value.encode(to: encoder)
|
try value.encode(to: encoder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encodes a model.
|
/// Encodes a model.
|
||||||
public mutating func encodeModel(_ value: Model, forKey key: KeyedEncodingContainer<K>.Key) throws {
|
mutating func encodeModel(_ value: Model, forKey key: KeyedEncodingContainer<K>.Key) throws {
|
||||||
let encoder = self.superEncoder(forKey: key)
|
let encoder = superEncoder(forKey: key)
|
||||||
try value.encode(to: encoder)
|
try value.encode(to: encoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encodes an array of models
|
/// Encodes an array of models
|
||||||
public mutating func encodeModels(_ list: [Model], forKey key:KeyedEncodingContainer<K>.Key) throws {
|
mutating func encodeModels(_ list: [Model], forKey key:KeyedEncodingContainer<K>.Key) throws {
|
||||||
try encodeModelsIfPresent(list, forKey: key)
|
try encodeModelsIfPresent(list, forKey: key)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encodes an array of models, optional, need instance type as input paramaeter list
|
/// Encodes an array of models, optional, need instance type as input paramaeter list
|
||||||
public mutating func encodeModelsIfPresent(_ list: [Model]?, forKey key:KeyedEncodingContainer<K>.Key) throws {
|
mutating func encodeModelsIfPresent(_ list: [Model]?, forKey key:KeyedEncodingContainer<K>.Key) throws {
|
||||||
|
|
||||||
guard let list = list else { return }
|
guard let list = list else { return }
|
||||||
var unkeyedContainer = self.nestedUnkeyedContainer(forKey: key)
|
var unkeyedContainer = nestedUnkeyedContainer(forKey: key)
|
||||||
|
|
||||||
for model in list {
|
for model in list {
|
||||||
try model.encode(unkeyedContainer: &unkeyedContainer)
|
try model.encode(unkeyedContainer: &unkeyedContainer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience function for encoding the container into a list of lists of Models. needs instance type as input paramaeter list
|
/// Convenience function for encoding the container into a list of lists of Models. needs instance type as input paramaeter list
|
||||||
public mutating func encodeModels2D(_ list: [[Model]]?, forKey key:KeyedEncodingContainer<K>.Key) throws {
|
mutating func encodeModels2D(_ list: [[Model]]?, forKey key:KeyedEncodingContainer<K>.Key) throws {
|
||||||
|
|
||||||
guard let list = list else { return }
|
guard let list = list else { return }
|
||||||
var unkeyedContainer = self.nestedUnkeyedContainer(forKey: key)
|
var unkeyedContainer = nestedUnkeyedContainer(forKey: key)
|
||||||
|
|
||||||
for models in list {
|
for models in list {
|
||||||
var arrayunkeyedContainer = unkeyedContainer.nestedUnkeyedContainer()
|
var arrayunkeyedContainer = unkeyedContainer.nestedUnkeyedContainer()
|
||||||
for model in models {
|
for model in models {
|
||||||
@ -155,20 +200,22 @@ extension KeyedEncodingContainer where Key: CodingKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension UnkeyedDecodingContainer {
|
public extension UnkeyedDecodingContainer {
|
||||||
|
|
||||||
/// Decodes the container into a list of Models.
|
/// Decodes the container into a list of Models.
|
||||||
public mutating func decodeModelsIfPresent<TypeKey: CodingKey>(typeCodingKey: TypeKey) throws -> [Model]? {
|
mutating func decodeModelsIfPresent<TypeKey: CodingKey>(typeCodingKey: TypeKey) throws -> [Model]? {
|
||||||
|
|
||||||
var models = [Model]()
|
var models = [Model]()
|
||||||
var containerCopy = self
|
var containerCopy = self
|
||||||
|
|
||||||
while !containerCopy.isAtEnd {
|
while !containerCopy.isAtEnd {
|
||||||
let nestedContainer = try containerCopy.nestedContainer(keyedBy: TypeKey.self)
|
let nestedContainer = try containerCopy.nestedContainer(keyedBy: TypeKey.self)
|
||||||
if let identifier = try nestedContainer.decodeIfPresent(String.self, forKey: typeCodingKey) {
|
if let identifier = try nestedContainer.decodeIfPresent(String.self, forKey: typeCodingKey) {
|
||||||
//get the type
|
guard let type = ModelRegistry.getType(for: identifier, with: TypeKey.self) else {
|
||||||
guard let type = ModelRegistry.getType(for: identifier) else {
|
|
||||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ModelRegistry Error decoderErrorModelNotMapped: \(identifier)")
|
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ModelRegistry Error decoderErrorModelNotMapped: \(identifier)")
|
||||||
throw ModelRegistry.Error.decoderErrorModelNotMapped
|
throw ModelRegistry.Error.decoderErrorModelNotMapped
|
||||||
}
|
}
|
||||||
//now get the decoder to use for the type
|
// Now get the decoder to use for the type
|
||||||
let decoder = try self.superDecoder()
|
let decoder = try self.superDecoder()
|
||||||
let model = try type.init(from: decoder)
|
let model = try type.init(from: decoder)
|
||||||
models.append(model)
|
models.append(model)
|
||||||
@ -178,9 +225,11 @@ extension UnkeyedDecodingContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience function for decoding the container into a list of lists of Models.
|
/// Convenience function for decoding the container into a list of lists of Models.
|
||||||
public mutating func decodeModels2DIfPresent<TypeKey: CodingKey>(typeCodingKey: TypeKey) throws -> [[Model]]? {
|
mutating func decodeModels2DIfPresent<TypeKey: CodingKey>(typeCodingKey: TypeKey) throws -> [[Model]]? {
|
||||||
|
|
||||||
var modelLists = [[Model]]()
|
var modelLists = [[Model]]()
|
||||||
var containerCopy = self
|
var containerCopy = self
|
||||||
|
|
||||||
while !containerCopy.isAtEnd {
|
while !containerCopy.isAtEnd {
|
||||||
var arraycontainerCopy = try containerCopy.nestedUnkeyedContainer()
|
var arraycontainerCopy = try containerCopy.nestedUnkeyedContainer()
|
||||||
guard let models = try arraycontainerCopy.decodeModelsIfPresent(typeCodingKey: typeCodingKey) else {
|
guard let models = try arraycontainerCopy.decodeModelsIfPresent(typeCodingKey: typeCodingKey) else {
|
||||||
|
|||||||
@ -10,12 +10,12 @@ import Foundation
|
|||||||
|
|
||||||
@objcMembers public class ModelMapping: NSObject {
|
@objcMembers public class ModelMapping: NSObject {
|
||||||
public static func registerObjects() {
|
public static func registerObjects() {
|
||||||
ModelRegistry.register(ActionOpenPageModel.self)
|
try? ModelRegistry.register(ActionOpenPageModel.self)
|
||||||
ModelRegistry.register(ActionOpenUrlModel.self)
|
try? ModelRegistry.register(ActionOpenUrlModel.self)
|
||||||
ModelRegistry.register(ActionOpenAppModel.self)
|
try? ModelRegistry.register(ActionOpenAppModel.self)
|
||||||
ModelRegistry.register(ActionCallModel.self)
|
try? ModelRegistry.register(ActionCallModel.self)
|
||||||
ModelRegistry.register(ActionPopupModel.self)
|
try? ModelRegistry.register(ActionPopupModel.self)
|
||||||
ModelRegistry.register(ActionTopAlertModel.self)
|
try? ModelRegistry.register(ActionTopAlertModel.self)
|
||||||
ModelRegistry.register(ActionBackModel.self)
|
try? ModelRegistry.register(ActionBackModel.self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "MVMCoreRequestParameters.h"
|
#import "MVMCoreRequestParameters.h"
|
||||||
|
|
||||||
#define ENABLE_HARD_CODED_RESPONSE 0 && DEBUG
|
#define ENABLE_HARD_CODED_RESPONSE 1 && DEBUG
|
||||||
|
|
||||||
#if ENABLE_HARD_CODED_RESPONSE
|
#if ENABLE_HARD_CODED_RESPONSE
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user