Merge branch 'develop' of gitlab.verizon.com:BPHV_MIPS/mvm_core into develop
This commit is contained in:
commit
29afdf10ed
@ -42,6 +42,7 @@ extern NSString * const URLComponentKeepAlive;
|
|||||||
|
|
||||||
extern NSString * const NotificationResponseLoaded;
|
extern NSString * const NotificationResponseLoaded;
|
||||||
extern NSString * const MVMCoreNotificationGoingToServer;
|
extern NSString * const MVMCoreNotificationGoingToServer;
|
||||||
|
extern NSString * const MVMCoreNotificationViewControllerChanged;
|
||||||
|
|
||||||
#pragma mark - Image Cache
|
#pragma mark - Image Cache
|
||||||
extern NSTimeInterval const ImageTimeOut;
|
extern NSTimeInterval const ImageTimeOut;
|
||||||
|
|||||||
@ -29,6 +29,7 @@ NSString * const URLComponentKeepAlive = @"isAlive.jsp";
|
|||||||
|
|
||||||
NSString * const NotificationResponseLoaded = @"responseLoaded";
|
NSString * const NotificationResponseLoaded = @"responseLoaded";
|
||||||
NSString * const MVMCoreNotificationGoingToServer = @"MVMCoreGoServer";
|
NSString * const MVMCoreNotificationGoingToServer = @"MVMCoreGoServer";
|
||||||
|
NSString * const MVMCoreNotificationViewControllerChanged = @"MVMCoreNotificationViewControllerChanged";
|
||||||
|
|
||||||
#pragma mark - Image Cache
|
#pragma mark - Image Cache
|
||||||
NSTimeInterval const ImageTimeOut = 60;
|
NSTimeInterval const ImageTimeOut = 60;
|
||||||
|
|||||||
@ -8,10 +8,6 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public enum ActionCodingKey: String, CodingKey {
|
|
||||||
case actionType
|
|
||||||
}
|
|
||||||
|
|
||||||
public protocol ActionModelProtocol: ModelProtocol {
|
public protocol ActionModelProtocol: ModelProtocol {
|
||||||
|
|
||||||
var actionType: String? { get set }
|
var actionType: String? { get set }
|
||||||
|
|||||||
@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
public struct ModelRegistry {
|
public struct ModelRegistry {
|
||||||
|
|
||||||
public enum Error: Swift.Error {
|
public enum Error: Swift.Error {
|
||||||
@ -45,24 +44,21 @@ public struct ModelRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static func getCategory<T>(for type: T.Type) -> Category? {
|
private static func getCategory<T>(for type: T.Type) -> Category? {
|
||||||
return categories["\(T.self)"]
|
// Temporary code till we find a better solution.
|
||||||
|
//if this is a protocol composotion, loop through each protocol for a category lookup
|
||||||
|
let protocols = String(describing: T.self).components(separatedBy: "&").compactMap{$0.trimmingCharacters(in: .whitespaces)}
|
||||||
|
return protocols.compactMap({ (p) -> Category? in
|
||||||
|
guard let c = categories[p] else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}).first
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func getType<T>(for name: String, with type: T.Type) -> ModelProtocol.Type? {
|
public static func getType<T>(for name: String, with type: T.Type) -> ModelProtocol.Type? {
|
||||||
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) -> ModelProtocol.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 ModelProtocol protocol")
|
throw ModelRegistry.Error.decoderOther(message: "decodeModelsIfPresent only works for objects implementing the ModelProtocol protocol")
|
||||||
@ -77,32 +73,46 @@ 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<T>(codingKey: KeyedDecodingContainer<K>.Key) throws -> T {
|
||||||
|
guard let model: T = try decodeModelIfPresent(codingKey: codingKey) else {
|
||||||
guard let model: ModelProtocol = 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
|
||||||
}
|
}
|
||||||
|
return model
|
||||||
|
}
|
||||||
|
|
||||||
if let model = model as? M {
|
/// Decodes an array of registered model based on the identifiers.
|
||||||
return model
|
public func decodeModels<T>(codingKey: KeyedDecodingContainer<K>.Key) throws -> [T] {
|
||||||
} else {
|
guard let model: [T] = try decodeModelsIfPresent(codingKey: codingKey) else {
|
||||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ModelRegistry Error decoderError: \(codingKey)")
|
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ModelRegistry Error decoderErrorObjectNotPresent: \(codingKey)")
|
||||||
throw ModelRegistry.Error.decoderError
|
throw ModelRegistry.Error.decoderErrorObjectNotPresent
|
||||||
}
|
}
|
||||||
|
return model
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Decodes an array with arrays of models based on the identifiers.
|
||||||
|
public func decodeModels2D<T>(codingKey: KeyedDecodingContainer<K>.Key) throws -> [[T]] {
|
||||||
|
guard let models: [[T]] = try decodeModels2DIfPresent(codingKey: codingKey) else {
|
||||||
|
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ModelRegistry Error decoderErrorObjectNotPresent: \(codingKey)")
|
||||||
|
throw ModelRegistry.Error.decoderErrorObjectNotPresent
|
||||||
|
}
|
||||||
|
return models
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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<T>(codingKey: KeyedDecodingContainer<K>.Key) throws -> T? {
|
||||||
//get the identifier string
|
//create coding key
|
||||||
guard contains(codingKey),
|
let typeCodingKey = try ModelRegistry.getCodingKey(for: T.self)
|
||||||
let container = try? nestedContainer(keyedBy: TypeKey.self, forKey: codingKey),
|
|
||||||
let identifier = try? container.decodeIfPresent(String.self, forKey: typeCodingKey)
|
|
||||||
else { return nil }
|
|
||||||
|
|
||||||
guard let type = ModelRegistry.getType(for: identifier, with: typeCodingKey.stringValue) else {
|
//get the container that holds the identifier value
|
||||||
|
guard contains(codingKey),
|
||||||
|
let container = try? self.nestedContainer(keyedBy: AnyCodingKey.self, forKey: codingKey),
|
||||||
|
let identifier = try container.decodeIfPresent(String.self, forKey: typeCodingKey) else { return nil }
|
||||||
|
|
||||||
|
//get the type from the identifier value in the Registry
|
||||||
|
guard let type = ModelRegistry.getType(for: identifier, with: T.self) else {
|
||||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ModelProtocol not mapped: \(identifier)")
|
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ModelProtocol not mapped: \(identifier)")
|
||||||
throw ModelRegistry.Error.decoderErrorModelNotMapped
|
throw ModelRegistry.Error.decoderErrorModelNotMapped
|
||||||
}
|
}
|
||||||
@ -110,7 +120,7 @@ extension KeyedDecodingContainer where Key: CodingKey {
|
|||||||
//decode the type using the decoder
|
//decode the type using the decoder
|
||||||
let model = try type.decode(keyedContainer: self, codingKey: codingKey)
|
let model = try type.decode(keyedContainer: self, codingKey: codingKey)
|
||||||
|
|
||||||
if let model = model as? M {
|
if let model = model as? T {
|
||||||
return model
|
return model
|
||||||
} else {
|
} else {
|
||||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ModelRegistry Error decoderError: \(codingKey)")
|
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ModelRegistry Error decoderError: \(codingKey)")
|
||||||
@ -119,39 +129,21 @@ 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 -> [ModelProtocol]? {
|
public func decodeModelsIfPresent<T>(codingKey: KeyedDecodingContainer<K>.Key) throws -> [T]? {
|
||||||
guard contains(codingKey),
|
guard contains(codingKey),
|
||||||
var container = try? self.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()
|
||||||
}
|
|
||||||
|
|
||||||
/// Decodes an array of registered model based on the identifiers.
|
|
||||||
public func decodeModels<TypeKey: CodingKey>(codingKey: KeyedDecodingContainer<K>.Key, typeCodingKey: TypeKey) throws -> [ModelProtocol] {
|
|
||||||
guard let models: [ModelProtocol] = try decodeModelsIfPresent(codingKey: codingKey, typeCodingKey: typeCodingKey) else {
|
|
||||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ModelRegistry Error decoderErrorObjectNotPresent: \(codingKey)")
|
|
||||||
throw ModelRegistry.Error.decoderErrorObjectNotPresent
|
|
||||||
}
|
|
||||||
return models
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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 -> [[ModelProtocol]]? {
|
public func decodeModels2DIfPresent<T>(codingKey: KeyedDecodingContainer<K>.Key) throws -> [[T]]? {
|
||||||
guard contains(codingKey),
|
guard contains(codingKey),
|
||||||
var container = try? nestedUnkeyedContainer(forKey: codingKey)
|
var container = try? nestedUnkeyedContainer(forKey: codingKey)
|
||||||
else { return nil }
|
else { return nil }
|
||||||
|
|
||||||
return try container.decodeModels2DIfPresent(typeCodingKey: typeCodingKey)
|
return try container.decodeModels2DIfPresent()
|
||||||
}
|
|
||||||
|
|
||||||
/// Decodes an array with arrays of models based on the identifiers.
|
|
||||||
public func decodeModels2D<TypeKey: CodingKey>(codingKey: KeyedDecodingContainer<K>.Key, typeCodingKey: TypeKey) throws -> [[ModelProtocol]] {
|
|
||||||
guard let models: [[ModelProtocol]] = try decodeModels2DIfPresent(codingKey: codingKey, typeCodingKey: typeCodingKey) else {
|
|
||||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ModelRegistry Error decoderErrorObjectNotPresent: \(codingKey)")
|
|
||||||
throw ModelRegistry.Error.decoderErrorObjectNotPresent
|
|
||||||
}
|
|
||||||
return models
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,36 +197,42 @@ public extension KeyedEncodingContainer where Key: CodingKey {
|
|||||||
public extension UnkeyedDecodingContainer {
|
public extension UnkeyedDecodingContainer {
|
||||||
|
|
||||||
/// Decodes the container into a list of Models.
|
/// Decodes the container into a list of Models.
|
||||||
mutating func decodeModelsIfPresent<TypeKey: CodingKey>(typeCodingKey: TypeKey) throws -> [ModelProtocol]? {
|
mutating func decodeModelsIfPresent<T>() throws -> [T]? {
|
||||||
|
let typeCodingKey = try ModelRegistry.getCodingKey(for: T.self)
|
||||||
var models = [ModelProtocol]()
|
var models = [T]()
|
||||||
var containerCopy = self
|
var containerCopy = self
|
||||||
|
|
||||||
|
// Iterate and decode each.
|
||||||
while !containerCopy.isAtEnd {
|
while !containerCopy.isAtEnd {
|
||||||
let nestedContainer = try containerCopy.nestedContainer(keyedBy: TypeKey.self)
|
let nestedContainer = try containerCopy.nestedContainer(keyedBy: AnyCodingKey.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: typeCodingKey.stringValue) else {
|
guard let type = ModelRegistry.getType(for: identifier, with: T.self) 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)
|
if let model = try type.init(from: decoder) as? T {
|
||||||
models.append(model)
|
models.append(model)
|
||||||
|
} else {
|
||||||
|
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ModelRegistry Error decoderError: \(typeCodingKey)")
|
||||||
|
throw ModelRegistry.Error.decoderError
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return models
|
return models
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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.
|
||||||
mutating func decodeModels2DIfPresent<TypeKey: CodingKey>(typeCodingKey: TypeKey) throws -> [[ModelProtocol]]? {
|
mutating func decodeModels2DIfPresent<T>() throws -> [[T]]? {
|
||||||
|
let typeCodingKey = try ModelRegistry.getCodingKey(for: T.self)
|
||||||
var modelLists = [[ModelProtocol]]()
|
var modelLists = [[T]]()
|
||||||
var containerCopy = self
|
var containerCopy = self
|
||||||
|
|
||||||
|
// Iterate and decode each.
|
||||||
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: [T] = try arraycontainerCopy.decodeModelsIfPresent() else {
|
||||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ModelRegistry Error decoderErrorModelNotMapped: \(typeCodingKey)")
|
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ModelRegistry Error decoderErrorModelNotMapped: \(typeCodingKey)")
|
||||||
throw ModelRegistry.Error.decoderErrorModelNotMapped
|
throw ModelRegistry.Error.decoderErrorModelNotMapped
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import "MVMCoreDismissViewControllerOperation.h"
|
#import "MVMCoreDismissViewControllerOperation.h"
|
||||||
|
#import "MVMCoreConstants.h"
|
||||||
|
|
||||||
typedef NS_ENUM(NSInteger, DismissType) {
|
typedef NS_ENUM(NSInteger, DismissType) {
|
||||||
DismissTypeTop = 0,
|
DismissTypeTop = 0,
|
||||||
@ -77,6 +78,10 @@ typedef NS_ENUM(NSInteger, DismissType) {
|
|||||||
if (viewController.presentedViewController || viewController.presentingViewController) {
|
if (viewController.presentedViewController || viewController.presentingViewController) {
|
||||||
[viewController dismissViewControllerAnimated:self.animate completion:^{
|
[viewController dismissViewControllerAnimated:self.animate completion:^{
|
||||||
[self markAsFinished];
|
[self markAsFinished];
|
||||||
|
// Notify that page has changed
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:MVMCoreNotificationViewControllerChanged object:nil];
|
||||||
|
});
|
||||||
}];
|
}];
|
||||||
} else {
|
} else {
|
||||||
[self markAsFinished];
|
[self markAsFinished];
|
||||||
|
|||||||
@ -242,6 +242,10 @@
|
|||||||
[self.delegate navigationController:navigationController displayedViewController:viewController];
|
[self.delegate navigationController:navigationController displayedViewController:viewController];
|
||||||
}
|
}
|
||||||
[self markAsFinished];
|
[self markAsFinished];
|
||||||
|
// Notify that page has changed
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:MVMCoreNotificationViewControllerChanged object:nil];
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC {
|
- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC {
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
#import "MVMCoreAlertController.h"
|
#import "MVMCoreAlertController.h"
|
||||||
#import "MVMCorePresentAnimationOperation.h"
|
#import "MVMCorePresentAnimationOperation.h"
|
||||||
#import "MVMCoreDispatchUtility.h"
|
#import "MVMCoreDispatchUtility.h"
|
||||||
|
#import "MVMCoreConstants.h"
|
||||||
|
|
||||||
@interface MVMCorePresentViewControllerOperation ()
|
@interface MVMCorePresentViewControllerOperation ()
|
||||||
|
|
||||||
@ -74,6 +75,10 @@ static void * XXContext = &XXContext;
|
|||||||
animationOperation.delegate = self.delegate;
|
animationOperation.delegate = self.delegate;
|
||||||
[animationOperation setCompletionBlock:^{
|
[animationOperation setCompletionBlock:^{
|
||||||
[self markAsFinished];
|
[self markAsFinished];
|
||||||
|
// Notify that page has changed
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:MVMCoreNotificationViewControllerChanged object:nil];
|
||||||
|
});
|
||||||
}];
|
}];
|
||||||
[[NSOperationQueue mainQueue] addOperation:animationOperation];
|
[[NSOperationQueue mainQueue] addOperation:animationOperation];
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user