integrating changes to make fan out instance models into categories due to name conflicts

This commit is contained in:
Kevin G Christiano 2020-02-12 14:14:01 -05:00
parent 53e05ca42f
commit ffd61f91c3
3 changed files with 27 additions and 13 deletions

View File

@ -25,17 +25,17 @@ public protocol ActionModelProtocol: Model {
var title: String? { get set } var title: String? { get set }
} }
extension ActionModelProtocol { public extension ActionModelProtocol {
public var actionType: String? { var actionType: String? {
get { return Self.identifier } get { return Self.identifier }
} }
public static var categoryCodingKey: String { static var categoryCodingKey: String {
return "actionType" return "actionType"
} }
public static var categoryName: String { static var categoryName: String {
return "\(ActionModelProtocol.self)" return "\(ActionModelProtocol.self)"
} }
} }

View File

@ -16,7 +16,7 @@ public protocol Model: Codable {
/// Name of the defining object. /// Name of the defining object.
static var categoryName: String { get } static var categoryName: String { get }
/// The JSON key name of the /// The primary category key name of the
static var categoryCodingKey: String { get } 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.

View File

@ -9,6 +9,7 @@
import Foundation import Foundation
public struct ModelRegistry { public struct ModelRegistry {
public enum Error: Swift.Error { public enum Error: Swift.Error {
@ -33,11 +34,7 @@ public struct ModelRegistry {
public static func register<M: Model>(_ type: M.Type) throws { public static func register<M: Model>(_ type: M.Type) throws {
var category: Category 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] { if let c = categories[M.categoryName] {
category = c category = c
} else { } else {
@ -61,6 +58,23 @@ public struct ModelRegistry {
return getCategory(for: type)?.instanceTypes[name] return getCategory(for: type)?.instanceTypes[name]
} }
private static func getCategory(for typeString: String) -> Category? {
for (_, value) in categories where value.codingKey == typeString {
return value
}
return nil
}
public static func getType(for name: String, with typeString: String) -> Model.Type? {
return getCategory(for: typeString)?.instanceTypes[name]
}
public static func getCodingKey<T>(for type: T.Type) throws -> AnyCodingKey{ public static func getCodingKey<T>(for type: T.Type) throws -> AnyCodingKey{
guard let category = getCategory(for: type) else { guard let category = getCategory(for: type) else {
throw ModelRegistry.Error.decoderOther(message: "decodeModelsIfPresent only works for objects implementing the Model protocol") throw ModelRegistry.Error.decoderOther(message: "decodeModelsIfPresent only works for objects implementing the Model protocol")
@ -100,7 +114,7 @@ extension KeyedDecodingContainer where Key: CodingKey {
let identifier = try? container.decodeIfPresent(String.self, forKey: typeCodingKey) let identifier = try? container.decodeIfPresent(String.self, forKey: typeCodingKey)
else { return nil } else { return nil }
guard let type = ModelRegistry.getType(for: identifier, with: M.self) else { guard let type = ModelRegistry.getType(for: identifier, with: typeCodingKey.stringValue) else {
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "Model not mapped: \(identifier)") MVMCoreLoggingHandler.logDebugMessage(withDelegate: "Model not mapped: \(identifier)")
throw ModelRegistry.Error.decoderErrorModelNotMapped throw ModelRegistry.Error.decoderErrorModelNotMapped
} }
@ -119,7 +133,7 @@ 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) var container = try? self.nestedUnkeyedContainer(forKey: codingKey)
else { return nil } else { return nil }
return try container.decodeModelsIfPresent(typeCodingKey: typeCodingKey) return try container.decodeModelsIfPresent(typeCodingKey: typeCodingKey)
@ -211,7 +225,7 @@ public extension UnkeyedDecodingContainer {
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) {
guard let type = ModelRegistry.getType(for: identifier, with: TypeKey.self) else { guard let type = ModelRegistry.getType(for: identifier, with: typeCodingKey.stringValue) else {
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ModelRegistry Error decoderErrorModelNotMapped: \(identifier)") MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ModelRegistry Error decoderErrorModelNotMapped: \(identifier)")
throw ModelRegistry.Error.decoderErrorModelNotMapped throw ModelRegistry.Error.decoderErrorModelNotMapped
} }