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 }
}
extension ActionModelProtocol {
public extension ActionModelProtocol {
public var actionType: String? {
var actionType: String? {
get { return Self.identifier }
}
public static var categoryCodingKey: String {
static var categoryCodingKey: String {
return "actionType"
}
public static var categoryName: String {
static var categoryName: String {
return "\(ActionModelProtocol.self)"
}
}

View File

@ -16,7 +16,7 @@ public protocol Model: Codable {
/// Name of the defining object.
static var categoryName: String { get }
/// The JSON key name of the
/// The primary category key name of the
static var categoryCodingKey: String { get }
/// Convenience function to decode to model using a keyed container.

View File

@ -9,6 +9,7 @@
import Foundation
public struct ModelRegistry {
public enum Error: Swift.Error {
@ -33,11 +34,7 @@ public struct ModelRegistry {
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 {
@ -61,6 +58,23 @@ public struct ModelRegistry {
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{
guard let category = getCategory(for: type) else {
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)
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)")
throw ModelRegistry.Error.decoderErrorModelNotMapped
}
@ -119,7 +133,7 @@ extension KeyedDecodingContainer where Key: CodingKey {
/// Decodes an array of registered model based on the identifiers, optional.
public func decodeModelsIfPresent<TypeKey: CodingKey>(codingKey: KeyedDecodingContainer<K>.Key, typeCodingKey: TypeKey) throws -> [Model]? {
guard contains(codingKey),
var container = try? nestedUnkeyedContainer(forKey: codingKey)
var container = try? self.nestedUnkeyedContainer(forKey: codingKey)
else { return nil }
return try container.decodeModelsIfPresent(typeCodingKey: typeCodingKey)
@ -211,7 +225,7 @@ public extension UnkeyedDecodingContainer {
while !containerCopy.isAtEnd {
let nestedContainer = try containerCopy.nestedContainer(keyedBy: TypeKey.self)
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)")
throw ModelRegistry.Error.decoderErrorModelNotMapped
}