modernization.
Adding json protocol to continue to support legacy (unfortunately)
This commit is contained in:
parent
71b2146862
commit
e6dca10d87
@ -92,6 +92,8 @@
|
||||
AF43A7411FC5FA6F008E9347 /* MVMCoreViewProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = AF43A7401FC5FA6F008E9347 /* MVMCoreViewProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
AF43A74C1FC6109F008E9347 /* MVMCoreSessionObject.h in Headers */ = {isa = PBXBuildFile; fileRef = AF43A74A1FC6109F008E9347 /* MVMCoreSessionObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
AF43A74D1FC6109F008E9347 /* MVMCoreSessionObject.m in Sources */ = {isa = PBXBuildFile; fileRef = AF43A74B1FC6109F008E9347 /* MVMCoreSessionObject.m */; };
|
||||
AF60A7F2289212CA00919EEB /* MVMError.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF60A7F1289212CA00919EEB /* MVMError.swift */; };
|
||||
AF60A7F4289212EB00919EEB /* MVMCoreError.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF60A7F3289212EB00919EEB /* MVMCoreError.swift */; };
|
||||
AF69D4E9286E54D500BC6862 /* ActionCallHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF69D4E8286E54D500BC6862 /* ActionCallHandler.swift */; };
|
||||
AF69D4EB286E586200BC6862 /* ActionRestartHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF69D4EA286E586200BC6862 /* ActionRestartHandler.swift */; };
|
||||
AF69D4ED286E5D8C00BC6862 /* ActionCancelHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF69D4EC286E5D8C00BC6862 /* ActionCancelHandler.swift */; };
|
||||
@ -253,6 +255,8 @@
|
||||
AF43A7401FC5FA6F008E9347 /* MVMCoreViewProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreViewProtocol.h; sourceTree = "<group>"; };
|
||||
AF43A74A1FC6109F008E9347 /* MVMCoreSessionObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreSessionObject.h; sourceTree = "<group>"; };
|
||||
AF43A74B1FC6109F008E9347 /* MVMCoreSessionObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreSessionObject.m; sourceTree = "<group>"; };
|
||||
AF60A7F1289212CA00919EEB /* MVMError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMError.swift; sourceTree = "<group>"; };
|
||||
AF60A7F3289212EB00919EEB /* MVMCoreError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreError.swift; sourceTree = "<group>"; };
|
||||
AF69D4E8286E54D500BC6862 /* ActionCallHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionCallHandler.swift; sourceTree = "<group>"; };
|
||||
AF69D4EA286E586200BC6862 /* ActionRestartHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionRestartHandler.swift; sourceTree = "<group>"; };
|
||||
AF69D4EC286E5D8C00BC6862 /* ActionCancelHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionCancelHandler.swift; sourceTree = "<group>"; };
|
||||
@ -403,6 +407,8 @@
|
||||
8876D5D41FB50AAB00EB2E3D /* Utility */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
AF60A7F1289212CA00919EEB /* MVMError.swift */,
|
||||
AF60A7F3289212EB00919EEB /* MVMCoreError.swift */,
|
||||
881D26911FCC9D180079C521 /* MVMCoreErrorObject.h */,
|
||||
881D268F1FCC9D180079C521 /* MVMCoreErrorObject.m */,
|
||||
881D26921FCC9D180079C521 /* MVMCoreOperation.h */,
|
||||
@ -921,6 +927,7 @@
|
||||
30349BF21FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m in Sources */,
|
||||
D2DEDCB923C6400600C44CC4 /* UnitInterval.swift in Sources */,
|
||||
94C014D3242119E6005811A9 /* ActionPreviousSubmitModel.swift in Sources */,
|
||||
AF60A7F2289212CA00919EEB /* MVMError.swift in Sources */,
|
||||
8876D5E91FB50AB000EB2E3D /* NSArray+MFConvenience.m in Sources */,
|
||||
D27073B725BB45C4001C7246 /* ActionActionsModel.swift in Sources */,
|
||||
946EE1B2237B5F260036751F /* JSONValue.swift in Sources */,
|
||||
@ -967,6 +974,7 @@
|
||||
AFBB96611FBA3A570008D868 /* MVMCoreLoadObject.m in Sources */,
|
||||
AF787413286DEF8B00670588 /* ActionBackHandler.swift in Sources */,
|
||||
946EE1B4237B619D0036751F /* Encoder.swift in Sources */,
|
||||
AF60A7F4289212EB00919EEB /* MVMCoreError.swift in Sources */,
|
||||
AFBB96941FBA3A9A0008D868 /* MVMCorePresentAnimationOperation.m in Sources */,
|
||||
94C014D524211AF0005811A9 /* ActionCancelModel.swift in Sources */,
|
||||
AF43A5841FBB66DE008E9347 /* MVMCoreConstants.m in Sources */,
|
||||
|
||||
@ -8,10 +8,29 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
open class ActionActionsHandler: MVMCoreActionHandlerProtocol {
|
||||
open class ActionActionsHandler: MVMCoreJSONActionHandlerProtocol {
|
||||
required public init() {}
|
||||
|
||||
public func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
open func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
guard let model = model as? ActionActionsModel else { return }
|
||||
let actions = JSON.arrayForKey("actions")
|
||||
if model.concurrent {
|
||||
await withThrowingTaskGroup(of: Void.self) { group in
|
||||
for case let (index, action as [AnyHashable: Any]) in actions.enumerated() {
|
||||
group.addTask{
|
||||
try await MVMCoreActionHandler.shared()?.handleAction(with: model.actions[index], json: action, additionalData: additionalData, delegateObject: delegateObject)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for case let (index, action as [AnyHashable: Any]) in actions.enumerated() {
|
||||
try Task.checkCancellation()
|
||||
try await MVMCoreActionHandler.shared()?.handleAction(with: model.actions[index], json: action, additionalData: additionalData, delegateObject: delegateObject)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
guard let model = model as? ActionActionsModel else { return }
|
||||
if model.concurrent {
|
||||
// TODO: inspect warning.
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers open class ActionActionsModel: ActionModelProtocol {
|
||||
open class ActionActionsModel: ActionModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -8,23 +8,24 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
open class ActionBackHandler: MVMCoreActionHandlerProtocol {
|
||||
open class ActionBackHandler: MVMCoreJSONActionHandlerProtocol {
|
||||
required public init() {}
|
||||
|
||||
public func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
guard let model = model as? ActionBackModel else { return }
|
||||
open func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
if let closure = delegateObject?.actionDelegate?.handleBackAction {
|
||||
// Legacy code will use the old handler function and break the task chain here.
|
||||
try await MVMCoreActionHandler.getOriginalJSON(with: model, additionalData: additionalData) { json, additionalData in
|
||||
closure(json, additionalData)
|
||||
}
|
||||
closure(JSON, additionalData)
|
||||
} else {
|
||||
await withCheckedContinuation { (continuation: CheckedContinuation<Void, Never>) in
|
||||
Task {
|
||||
await MVMCoreNavigationHandler.shared()?.removeCurrentViewController(true, completionHandler: {
|
||||
continuation.resume()
|
||||
})
|
||||
}
|
||||
try await performAction(model, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
}
|
||||
|
||||
open func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
await withCheckedContinuation { (continuation: CheckedContinuation<Void, Never>) in
|
||||
Task(priority: .userInitiated) {
|
||||
await MVMCoreNavigationHandler.shared()?.removeCurrentViewController(true, completionHandler: {
|
||||
continuation.resume()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
|
||||
@objcMembers public class ActionBackModel: ActionModelProtocol {
|
||||
public struct ActionBackModel: ActionModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -11,7 +11,7 @@ import Foundation
|
||||
open class ActionCallHandler: MVMCoreActionHandlerProtocol {
|
||||
required public init() {}
|
||||
|
||||
public func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
open func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
guard let model = model as? ActionCallModel else { return }
|
||||
// https://developer.apple.com/library/archive/featuredarticles/iPhoneURLScheme_Reference/PhoneLinks/PhoneLinks.html#//apple_ref/doc/uid/TP40007899-CH6-SW1
|
||||
try await ActionOpenUrlHandler.openURL(with: "tel://\(model.callNumber)")
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
|
||||
@objcMembers public class ActionCallModel: ActionModelProtocol {
|
||||
public struct ActionCallModel: ActionModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -8,12 +8,13 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
open class ActionCancelHandler: MVMCoreActionHandlerProtocol {
|
||||
open class ActionCancelHandler: MVMCoreJSONActionHandlerProtocol {
|
||||
required public init() {}
|
||||
|
||||
open func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
delegateObject?.actionDelegate?.handleCancel?(JSON, additionalData: additionalData)
|
||||
}
|
||||
|
||||
open func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
try await MVMCoreActionHandler.getOriginalJSON(with: model, additionalData: additionalData) { json, additionalData in
|
||||
delegateObject?.actionDelegate?.handleCancel?(json, additionalData: additionalData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
|
||||
@objcMembers public class ActionCancelModel: ActionModelProtocol {
|
||||
public struct ActionCancelModel: ActionModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -20,7 +20,7 @@ open class ActionContactHandler: NSObject, MVMCoreActionHandlerProtocol, CNConta
|
||||
private func continueInTask(with closure: @escaping () async -> Void) async {
|
||||
let _: Bool = await withCheckedContinuation { continuation in
|
||||
self.continuation = continuation
|
||||
Task {
|
||||
Task(priority: .userInitiated) {
|
||||
await closure()
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
import ContactsUI
|
||||
|
||||
|
||||
@objcMembers public class ActionContactModel: ActionModelProtocol {
|
||||
public struct ActionContactModel: ActionModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -12,9 +12,6 @@ public protocol ActionDelegateProtocol: MVMCoreActionDelegateProtocol {
|
||||
/// Allows the delegate to cancel the action.
|
||||
func shouldPerform(action: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) -> Bool
|
||||
|
||||
/// Allows the delegate to create the request parameters as desired.
|
||||
func getRequestParameters(for model: ActionOpenPageModel, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) throws -> (MVMCoreRequestParameters,[AnyHashable : Any]?)
|
||||
|
||||
/// Allows the delegate to handle any custom actions that are not registered with the Action Handler.
|
||||
func handlesUnknownAction(for model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws -> Bool
|
||||
}
|
||||
@ -25,11 +22,6 @@ public extension ActionDelegateProtocol {
|
||||
return true
|
||||
}
|
||||
|
||||
func getRequestParameters(for model: ActionOpenPageModel, delegateObject: DelegateObject? = nil, additionalData: [AnyHashable : Any]? = nil) throws -> (MVMCoreRequestParameters,[AnyHashable : Any]?) {
|
||||
let json = try MVMCoreActionHandler.convertActionToJSON(model)
|
||||
return (MVMCoreRequestParameters(actionMap: json)!,additionalData)
|
||||
}
|
||||
|
||||
func handlesUnknownAction(for model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -11,5 +11,5 @@ import Foundation
|
||||
open class ActionNoopHandler: MVMCoreActionHandlerProtocol {
|
||||
required public init() {}
|
||||
|
||||
public func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {}
|
||||
open func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {}
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
// Copyright © 2020 myverizon. All rights reserved.
|
||||
//
|
||||
|
||||
@objcMembers public class ActionNoopModel: ActionModelProtocol {
|
||||
public struct ActionNoopModel: ActionModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -8,30 +8,54 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
open class ActionOpenPageHandler: MVMCoreActionHandlerProtocol {
|
||||
public protocol ActionOpenPageDelegateProtocol {
|
||||
/// Allows the delegate to create the request parameters as desired.
|
||||
func getRequestParameters(for model: ActionOpenPageModel, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) throws -> (MVMCoreRequestParameters,[AnyHashable : Any]?)
|
||||
}
|
||||
|
||||
open class ActionOpenPageHandler: MVMCoreJSONActionHandlerProtocol {
|
||||
required public init() {}
|
||||
|
||||
open func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
open func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
guard let model = model as? ActionOpenPageModel else { return }
|
||||
try await MVMCoreActionHandler.getOriginalJSON(with: model, additionalData: additionalData) { json, additionalData in
|
||||
var additionalData = additionalData
|
||||
|
||||
if model.background != true {
|
||||
MVMCoreLoadingOverlayHandler.sharedLoadingOverlay()?.startLoading()
|
||||
}
|
||||
defer {
|
||||
if model.background != true {
|
||||
MVMCoreLoadingOverlayHandler.sharedLoadingOverlay()?.stopLoading(true)
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
// Allows the delegate a chance to create and modify request parameters.
|
||||
var requestParameters: MVMCoreRequestParameters
|
||||
if let _ = (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.getRequestParameters {
|
||||
let value = try (delegateObject!.actionDelegate! as! ActionDelegateProtocol).getRequestParameters(for: model, delegateObject: delegateObject, additionalData: additionalData)
|
||||
var additionalData = additionalData
|
||||
if let value = try (delegateObject?.actionDelegate as? ActionOpenPageDelegateProtocol)?.getRequestParameters(for: model, delegateObject: delegateObject, additionalData: additionalData) {
|
||||
requestParameters = value.0
|
||||
additionalData = value.1
|
||||
} else {
|
||||
requestParameters = MVMCoreRequestParameters(actionMap: json)!
|
||||
requestParameters = MVMCoreRequestParameters(actionMap: JSON)!
|
||||
}
|
||||
|
||||
|
||||
if let closure = delegateObject?.actionDelegate?.handleOpenPage {
|
||||
// Legacy code will use the old handler function and break the task chain here.
|
||||
closure(requestParameters, json, additionalData)
|
||||
closure(requestParameters, JSON, additionalData)
|
||||
} else {
|
||||
try await performRequestAddingClientParameters(with: requestParameters, model: model, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
} catch {
|
||||
try handle(error: error, model: model, delegateObject: delegateObject)
|
||||
}
|
||||
}
|
||||
|
||||
open func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
guard let model = model as? ActionOpenPageModel else { return }
|
||||
do {
|
||||
let json = try MVMCoreActionHandler.convertActionToJSON(model)
|
||||
try await performAction(with: json, model: model, delegateObject: delegateObject, additionalData: additionalData)
|
||||
} catch {
|
||||
try handle(error: error, model: model, delegateObject: delegateObject)
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,6 +70,19 @@ open class ActionOpenPageHandler: MVMCoreActionHandlerProtocol {
|
||||
// Makes the request and waits for it.
|
||||
try await MVMCoreLoadHandler.sharedGlobal()?.performRequest(with: requestParameters, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
|
||||
/// Ensures background requests do not have showing errors.
|
||||
private func handle(error: Error, model: ActionOpenPageModel, delegateObject: DelegateObject?) throws {
|
||||
switch error {
|
||||
case MVMCoreError.errorObject(let errorObject):
|
||||
errorObject.silentError = model.background == true
|
||||
throw MVMCoreError.errorObject(errorObject)
|
||||
default:
|
||||
let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: model.actionType))!
|
||||
errorObject.silentError = model.background == true
|
||||
throw MVMCoreError.errorObject(errorObject)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public extension ClientParameterHandler {
|
||||
@ -63,7 +100,6 @@ public extension ClientParameterHandler {
|
||||
return try await withCheckedThrowingContinuation({ continuation in
|
||||
do {
|
||||
try getParameters(with: model, requestParameters: requestParameters) { parameters in
|
||||
MVMCoreLoadingOverlayHandler.sharedLoadingOverlay()?.stopLoading(true)
|
||||
continuation.resume(returning: parameters)
|
||||
}
|
||||
} catch {
|
||||
|
||||
@ -7,24 +7,24 @@
|
||||
//
|
||||
|
||||
|
||||
@objcMembers open class ActionOpenPageModel: ActionModelProtocol, ActionOpenPageProtocol, ClientParameterActionProtocol {
|
||||
open class ActionOpenPageModel: ActionModelProtocol, ActionOpenPageProtocol, ClientParameterActionProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public class var identifier: String { "openPage" }
|
||||
public var actionType: String = identifier
|
||||
public var pageType: String
|
||||
public var modules: [String]?
|
||||
public var baseURL: String?
|
||||
public var appContext: String?
|
||||
public var requestURL: String?
|
||||
public var extraParameters: JSONValueDictionary?
|
||||
public var analyticsData: JSONValueDictionary?
|
||||
public var presentationStyle: String?
|
||||
public var tabBarIndex: Int?
|
||||
public var background: Bool?
|
||||
public var clientParameters: ClientParameterModel?
|
||||
open class var identifier: String { "openPage" }
|
||||
open var actionType: String = identifier
|
||||
open var pageType: String
|
||||
open var modules: [String]?
|
||||
open var baseURL: String?
|
||||
open var appContext: String?
|
||||
open var requestURL: String?
|
||||
open var extraParameters: JSONValueDictionary?
|
||||
open var analyticsData: JSONValueDictionary?
|
||||
open var presentationStyle: String?
|
||||
open var tabBarIndex: Int?
|
||||
open var background: Bool?
|
||||
open var clientParameters: ClientParameterModel?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initialzier
|
||||
|
||||
@ -24,7 +24,7 @@ extension String {
|
||||
open class ActionOpenSMSHandler: MVMCoreActionHandlerProtocol {
|
||||
required public init() {}
|
||||
|
||||
public func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
open func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
guard let model = model as? ActionOpenSMSModel else { return }
|
||||
// https://developer.apple.com/library/archive/featuredarticles/iPhoneURLScheme_Reference/SMSLinks/SMSLinks.html#:~:text=Note%3A%20SMS%20text%20links%20are,number%20of%20the%20SMS%20message.
|
||||
let string = try "sms:\(model.phoneNumber)&body=\(model.message ?? "")".addingPercentEncodingThrowable(withAllowedCharacters: CharacterSet.urlQueryAllowed)
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
|
||||
@objcMembers public class ActionOpenSMSModel: ActionModelProtocol {
|
||||
public struct ActionOpenSMSModel: ActionModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
import Foundation
|
||||
|
||||
public extension URL {
|
||||
private enum URLError: MVMError, CustomStringConvertible {
|
||||
enum URLError: MVMError, CustomStringConvertible {
|
||||
case invalid(string: String)
|
||||
|
||||
public var description: String {
|
||||
@ -27,40 +27,8 @@ public extension URL {
|
||||
return url
|
||||
}
|
||||
}
|
||||
|
||||
public enum MVMCoreError: MVMError {
|
||||
case error(code: Int, messageToDisplay: String, location: String)
|
||||
case errorObject(_ object: MVMCoreErrorObject)
|
||||
|
||||
public var errorCode: Int {
|
||||
switch self {
|
||||
case MVMCoreError.error(let code, _, _):
|
||||
return code
|
||||
case MVMCoreError.errorObject(let object):
|
||||
return object.code
|
||||
}
|
||||
}
|
||||
|
||||
public var description: String {
|
||||
switch self {
|
||||
case MVMCoreError.error(_, let message, _):
|
||||
return message
|
||||
case MVMCoreError.errorObject(let object):
|
||||
return object.messageToDisplay ?? "Error"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protocol MVMError: LocalizedError, CustomNSError {}
|
||||
extension MVMError {
|
||||
public var errorDescription: String? { return MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess) }
|
||||
|
||||
public static var errorDomain: String {
|
||||
return ErrorDomainNative
|
||||
}
|
||||
}
|
||||
|
||||
open class ActionOpenUrlHandler: MVMCoreActionHandlerProtocol {
|
||||
open class ActionOpenUrlHandler: MVMCoreJSONActionHandlerProtocol {
|
||||
required public init() {}
|
||||
|
||||
public enum URLError: MVMError, CustomStringConvertible {
|
||||
@ -74,11 +42,13 @@ open class ActionOpenUrlHandler: MVMCoreActionHandlerProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a url and calls open(url: URL)
|
||||
public static func openURL(with string: String) async throws {
|
||||
let url = try URL.createURL(with: string)
|
||||
try await ActionOpenUrlHandler.open(url: url)
|
||||
}
|
||||
|
||||
/// Opens the url using UIApplication open(url:). Throws URLError.failedToOpen if it fails.
|
||||
@MainActor public static func open(url: URL) async throws {
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
UIApplication.shared.open(url, options: [:]) { successful in
|
||||
@ -91,6 +61,10 @@ open class ActionOpenUrlHandler: MVMCoreActionHandlerProtocol {
|
||||
} as Void
|
||||
}
|
||||
|
||||
open func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
try await performAction(model, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
|
||||
open func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
guard let model = model as? ActionOpenUrlModel else { return }
|
||||
|
||||
@ -102,7 +76,7 @@ open class ActionOpenUrlHandler: MVMCoreActionHandlerProtocol {
|
||||
} catch {
|
||||
// Log error and continue
|
||||
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Failed to open app url: \(appURL)")
|
||||
if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: model.actionType)) {
|
||||
if let errorObject = MVMCoreActionHandler.shared()?.getActionErrorObject(for: error, actionType: model.actionType, delegateObject: delegateObject) {
|
||||
MVMCoreLoggingHandler.addError(toLog: errorObject)
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,18 +8,18 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers open class ActionOpenUrlModel: ActionModelProtocol {
|
||||
open class ActionOpenUrlModel: ActionModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier: String = "openURL"
|
||||
public var actionType: String = ActionOpenUrlModel.identifier
|
||||
public var browserUrl: URL
|
||||
public var appURL: URL?
|
||||
public var appURLOptions: OpenUrlOptionsModel?
|
||||
public var extraParameters: JSONValueDictionary?
|
||||
public var analyticsData: JSONValueDictionary?
|
||||
open class var identifier: String { "openURL" }
|
||||
open var actionType: String = ActionOpenUrlModel.identifier
|
||||
open var browserUrl: URL
|
||||
open var appURL: URL?
|
||||
open var appURLOptions: OpenUrlOptionsModel?
|
||||
open var extraParameters: JSONValueDictionary?
|
||||
open var analyticsData: JSONValueDictionary?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initialzier
|
||||
|
||||
@ -9,10 +9,18 @@
|
||||
import Foundation
|
||||
|
||||
/// Makes the previous request, needs the delegate for this
|
||||
open class ActionPreviousSubmitHandler: MVMCoreActionHandlerProtocol {
|
||||
open class ActionPreviousSubmitHandler: MVMCoreJSONActionHandlerProtocol {
|
||||
required public init() {}
|
||||
|
||||
public func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
private var json: [AnyHashable: Any]?
|
||||
|
||||
// Conform to MVMCoreJSONActionHandlerProtocol To allow for legacy handleOpenPage delegate
|
||||
open func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
json = JSON
|
||||
try await performAction(model, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
|
||||
open func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
guard let loadObject = (delegateObject?.actionDelegate as? MVMCoreViewControllerProtocol)?.loadObject,
|
||||
let previousRequest = loadObject?.requestParameters else { return }
|
||||
|
||||
@ -25,7 +33,7 @@ open class ActionPreviousSubmitHandler: MVMCoreActionHandlerProtocol {
|
||||
|
||||
if let _ = delegateObject?.actionDelegate?.handleOpenPage {
|
||||
// Legacy handling. Will lose the task.
|
||||
let json = try MVMCoreActionHandler.convertActionToJSON(model)
|
||||
let json = try json ?? MVMCoreActionHandler.convertActionToJSON(model)
|
||||
delegateObject?.actionDelegate?.handleOpenPage?(for: previousRequest, actionInformation: json, additionalData: additionalData)
|
||||
} else {
|
||||
try await MVMCoreLoadHandler.sharedGlobal()?.performRequest(with: previousRequest, delegateObject: delegateObject, additionalData: additionalData)
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
|
||||
@objcMembers public class ActionPreviousSubmitModel: ActionModelProtocol {
|
||||
public struct ActionPreviousSubmitModel: ActionModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -11,23 +11,23 @@ import Foundation
|
||||
open class ActionRestartHandler: MVMCoreActionHandlerProtocol {
|
||||
required public init() {}
|
||||
|
||||
public func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
open func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
guard let model = model as? ActionRestartModel else { return }
|
||||
|
||||
let _: Bool = try await withCheckedThrowingContinuation { continuation in
|
||||
let _: Void = try await withCheckedThrowingContinuation { continuation in
|
||||
|
||||
// Invalidates the session before restarting.
|
||||
MVMCoreSessionTimeHandler.sharedSession()?.invalidateSession({ error in
|
||||
if let error = error {
|
||||
guard error.code != NSURLErrorCancelled else {
|
||||
continuation.resume(returning: false)
|
||||
continuation.resume()
|
||||
return
|
||||
}
|
||||
continuation.resume(throwing: MVMCoreError.errorObject(error))
|
||||
} else {
|
||||
// Restarts the app (forcing any passed in page types).
|
||||
MVMCoreSessionObject.sharedGlobal()?.restartSession(withPageType: model.pageType, parameters: model.extraParameters, clearAllVariables: true)
|
||||
continuation.resume(returning: true)
|
||||
MVMCoreSessionObject.sharedGlobal()?.restartSession(withPageType: model.pageType, parameters: model.extraParameters.toJSON(), clearAllVariables: true)
|
||||
continuation.resume()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
|
||||
@objcMembers public class ActionRestartModel: ActionModelProtocol {
|
||||
public struct ActionRestartModel: ActionModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -11,7 +11,7 @@ import Foundation
|
||||
open class ActionSettingHandler: MVMCoreActionHandlerProtocol {
|
||||
required public init() {}
|
||||
|
||||
public func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
open func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
try await ActionOpenUrlHandler.openURL(with: await UIApplication.openSettingsURLString)
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
|
||||
@objcMembers public class ActionSettingModel: ActionModelProtocol {
|
||||
public struct ActionSettingModel: ActionModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
@ -24,7 +24,7 @@ open class ActionShareHandler: MVMCoreActionHandlerProtocol {
|
||||
try await shareWith(activityItems: shareData, model: model)
|
||||
}
|
||||
|
||||
@MainActor public func shareWith(activityItems: [Any], model: ActionShareModel) async throws {
|
||||
@MainActor open func shareWith(activityItems: [Any], model: ActionShareModel, delegateObject: DelegateObject? = nil) async throws {
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
let controller = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
|
||||
controller.popoverPresentationController?.sourceView = MVMCoreNavigationHandler.shared()?.viewControllerToPresentOn?.view
|
||||
@ -39,7 +39,7 @@ open class ActionShareHandler: MVMCoreActionHandlerProtocol {
|
||||
} else if let _ = activityType {
|
||||
// If a specific type of activity failed, the activity controller is still presented, cannot continue yet.
|
||||
if let error = error,
|
||||
let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: #function) {
|
||||
let errorObject = MVMCoreActionHandler.shared()?.getActionErrorObject(for: error, actionType: model.actionType, delegateObject: delegateObject) {
|
||||
MVMCoreLoggingHandler.addError(toLog: errorObject)
|
||||
}
|
||||
} else if let error = error {
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
|
||||
@objcMembers public class ActionShareModel: ActionModelProtocol {
|
||||
public struct ActionShareModel: ActionModelProtocol {
|
||||
|
||||
public enum SharedType: String, Codable {
|
||||
case text
|
||||
|
||||
@ -13,9 +13,16 @@ public protocol MVMCoreActionHandlerProtocol: ModelHandlerProtocol {
|
||||
init()
|
||||
/// Legacy function to handle actions.
|
||||
func handleAction(_ model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?)
|
||||
|
||||
func performAction(_ model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws
|
||||
}
|
||||
|
||||
/// Protocol used to bridge legacy, non model based code. Allows us to keep the original json intact and not lose key values during decode/encode.
|
||||
public protocol MVMCoreJSONActionHandlerProtocol: MVMCoreActionHandlerProtocol {
|
||||
/// Perform the function using the original json and model.
|
||||
func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws
|
||||
}
|
||||
|
||||
extension MVMCoreActionHandlerProtocol {
|
||||
|
||||
public func handleAction(_ model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) {
|
||||
@ -27,11 +34,8 @@ extension MVMCoreActionHandlerProtocol {
|
||||
}
|
||||
|
||||
@objc open class MVMCoreActionHandler: NSObject {
|
||||
|
||||
/// The key used to pass along the json for the legacy handlers in additionalData
|
||||
public static let originalJSONKey: String = "ORIGINAL_JSON"
|
||||
|
||||
enum ActionError: MVMError {
|
||||
enum ActionError: MVMError, CustomStringConvertible {
|
||||
case unknownAction(type: String)
|
||||
|
||||
public var description: String {
|
||||
@ -104,29 +108,34 @@ extension MVMCoreActionHandlerProtocol {
|
||||
/// Handle an action with the given model.
|
||||
open func handleAction(with model: ActionModelProtocol, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) async throws {
|
||||
try Task.checkCancellation()
|
||||
|
||||
let additionalData = MVMCoreActionHandler.setUUID(additionalData: additionalData)
|
||||
|
||||
// Allow the delegate to intercept.
|
||||
guard (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.shouldPerform(action: model, additionalData: additionalData, delegateObject: delegateObject) ?? true else { return }
|
||||
|
||||
defer {
|
||||
MVMCoreActionHandler.log(string: "End Action: \(model.actionType)", additionalData: additionalData)
|
||||
}
|
||||
|
||||
// Log the action
|
||||
logAction(with: model, additionalData: additionalData, delegateObject: delegateObject)
|
||||
let uuid = UUID()
|
||||
do {
|
||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ActionHandler: Begin Action \(model.actionType) \(uuid)")
|
||||
MVMCoreActionHandler.log(string: "Begin Action: \(model.actionType)", additionalData: additionalData)
|
||||
let handlerType = try ModelRegistry.getHandler(model) as! MVMCoreActionHandlerProtocol.Type
|
||||
let handler = handlerType.init()
|
||||
try await handler.performAction(model, delegateObject: delegateObject, additionalData: additionalData)
|
||||
} catch ModelRegistry.Error.handlerNotMapped {
|
||||
try Task.checkCancellation()
|
||||
// Allows custom handling if there no handler for the action.
|
||||
guard try await handleUnregisteredAction(with: model, additionalData: additionalData, delegateObject: delegateObject) else {
|
||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ActionHandler: Finished Failed Action Unknown \(model.actionType) \(uuid)")
|
||||
guard try await handleUnregisteredAction(with: model, json: model.toJSON()!, additionalData: additionalData, delegateObject: delegateObject) else {
|
||||
MVMCoreActionHandler.log(string: "Failed Action Unknown", additionalData: additionalData)
|
||||
throw ActionError.unknownAction(type: model.actionType)
|
||||
}
|
||||
} catch {
|
||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ActionHandler: Finished Failed Action \(error) \(model.actionType) \(uuid)")
|
||||
MVMCoreActionHandler.log(string: "Failed Action \(error)", additionalData: additionalData)
|
||||
throw error
|
||||
}
|
||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ActionHandler: Finished Successful Action \(model.actionType) \(uuid)")
|
||||
}
|
||||
|
||||
/// Performs the action as a task and returns immediately.
|
||||
@ -134,7 +143,8 @@ extension MVMCoreActionHandlerProtocol {
|
||||
let task = Task(priority: .userInitiated) {
|
||||
try Task.checkCancellation()
|
||||
do {
|
||||
try await handleAction(with: model, additionalData: additionalData, delegateObject: delegateObject)
|
||||
let json = try MVMCoreActionHandler.convertActionToJSON(model)
|
||||
try await handleAction(with: model, json: json, additionalData: additionalData, delegateObject: delegateObject)
|
||||
} catch {
|
||||
try Task.checkCancellation()
|
||||
let errorObject = getActionErrorObject(for: error, actionType: model.actionType, delegateObject: delegateObject)
|
||||
@ -164,25 +174,7 @@ extension MVMCoreActionHandlerProtocol {
|
||||
open func logAction(with model: ActionModelProtocol, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
|
||||
// Calls legacy log action function.
|
||||
Task {
|
||||
try await MVMCoreActionHandler.getOriginalJSON(with: model, additionalData: additionalData) { json, additionalData in
|
||||
delegateObject?.actionDelegate?.logAction?(withActionInformation: json, additionalData: additionalData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Subclass to handle and any actions where a handler was not registered. Checks with the delegate handlesUnknownAction function
|
||||
open func handleUnregisteredAction(with model: ActionModelProtocol, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) async throws -> Bool {
|
||||
// Check if the delegate handles the action.
|
||||
if try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.handlesUnknownAction(for: model, delegateObject: delegateObject, additionalData: additionalData) == true {
|
||||
return true
|
||||
} else if let closure = delegateObject?.actionDelegate?.handleUnknownActionType {
|
||||
// Check if the legacy delegate handles the action.
|
||||
try await MVMCoreActionHandler.getOriginalJSON(with: model, additionalData: additionalData) { json, additionalData in
|
||||
closure(model.actionType, json, additionalData)
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
delegateObject?.actionDelegate?.logAction?(withActionInformation: model.toJSON(), additionalData: additionalData)
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,43 +186,118 @@ extension MVMCoreActionHandlerProtocol {
|
||||
|
||||
// MARK: - Legacy Holdovers
|
||||
|
||||
public static func getOriginalJSON(with model: ActionModelProtocol, additionalData: [AnyHashable: Any]?, closure: ([AnyHashable: Any], [AnyHashable: Any]?) async throws -> Void) async throws {
|
||||
var additionalData = additionalData
|
||||
let json = try additionalData?[MVMCoreActionHandler.originalJSONKey] as? [AnyHashable: Any] ?? MVMCoreActionHandler.convertActionToJSON(model)
|
||||
additionalData?.removeValue(forKey: MVMCoreActionHandler.originalJSONKey)
|
||||
try await closure(json, additionalData)
|
||||
static public func setUUID(additionalData: [AnyHashable: Any]?) -> [AnyHashable: Any]? {
|
||||
var additionalData = additionalData ?? [:]
|
||||
if additionalData.optionalStringForKey("Action-UUID") == nil {
|
||||
additionalData["Action-UUID"] = UUID().uuidString
|
||||
}
|
||||
return additionalData
|
||||
}
|
||||
|
||||
static public func getUUID(additionalData: [AnyHashable: Any]?) -> String? {
|
||||
return additionalData?.optionalStringForKey("Action-UUID")
|
||||
}
|
||||
|
||||
static public func log(string: String, additionalData: [AnyHashable: Any]?) {
|
||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ActionHandler: UUID: \(String(describing: getUUID(additionalData: additionalData))), \(string)")
|
||||
}
|
||||
|
||||
/// Legacy handle action with json.
|
||||
@objc(handleActionWithDictionary:additionalData:delegateObject:)
|
||||
open func handleAction(with json: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
|
||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ActionHandler: json \(String(describing: json))")
|
||||
Task(priority: .userInitiated) {
|
||||
var additionalData = additionalData ?? [:]
|
||||
additionalData[MVMCoreActionHandler.originalJSONKey] = json
|
||||
let additionalData = MVMCoreActionHandler.setUUID(additionalData: additionalData)
|
||||
let task = Task(priority: .userInitiated) {
|
||||
try Task.checkCancellation()
|
||||
do {
|
||||
guard let json = json else {
|
||||
throw ModelRegistry.Error.keyNotFound
|
||||
}
|
||||
let model = try MVMCoreActionHandler.createModel(with: json, delegateObject: delegateObject)
|
||||
_ = asyncHandleAction(with: model, additionalData: additionalData, delegateObject: delegateObject)
|
||||
try await handleAction(with: model, json: json, additionalData: additionalData, delegateObject: delegateObject)
|
||||
} catch {
|
||||
let actionType = json?.optionalStringForKey(KeyActionType)
|
||||
switch error {
|
||||
case ModelRegistry.Error.decoderErrorModelNotMapped:
|
||||
// If the model is not mapped, give the legacy classes a chance to handle it.
|
||||
let actionType = json?.optionalStringForKey(KeyActionType)
|
||||
if let closure = delegateObject?.actionDelegate?.handleUnknownActionType {
|
||||
additionalData.removeValue(forKey: MVMCoreActionHandler.originalJSONKey)
|
||||
MVMCoreActionHandler.log(string: "Unknown handled (Model not registered): \(String(describing: actionType)) \(String(describing: delegateObject?.actionDelegate))", additionalData: additionalData)
|
||||
closure(actionType, json, additionalData)
|
||||
} else {
|
||||
fallthrough
|
||||
}
|
||||
default:
|
||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "ActionHandler: Error \(error)")
|
||||
let errorObject = getActionErrorObject(for: error, actionType: json?.stringForkey(KeyActionType) ?? "noAction", delegateObject: delegateObject)
|
||||
MVMCoreActionHandler.log(string: "Failed Action: Error \(error)", additionalData: additionalData)
|
||||
let errorObject = getActionErrorObject(for: error, actionType: actionType ?? "noAction", delegateObject: delegateObject)
|
||||
handle(errorObject: errorObject, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
}
|
||||
}
|
||||
Task {
|
||||
let result = await task.result
|
||||
do {
|
||||
try result.get()
|
||||
print("ActionHandler: task done")
|
||||
} catch {
|
||||
print("ActionHandler: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Bridges the legacy json using functions and the new model using functions.
|
||||
open func handleAction(with model: ActionModelProtocol, json: [AnyHashable: Any], additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) async throws {
|
||||
try Task.checkCancellation()
|
||||
let additionalData = MVMCoreActionHandler.setUUID(additionalData: additionalData)
|
||||
|
||||
MVMCoreActionHandler.log(string: "Begin Action: type: \(model.actionType) json: \(String(describing: json))", additionalData: additionalData)
|
||||
defer {
|
||||
MVMCoreActionHandler.log(string: "End Action: \(model.actionType)", additionalData: additionalData)
|
||||
}
|
||||
|
||||
// Allow the delegate to intercept.
|
||||
guard (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.shouldPerform(action: model, additionalData: additionalData, delegateObject: delegateObject) ?? true else {
|
||||
MVMCoreActionHandler.log(string: "Action should not be performed: \(model.actionType)", additionalData: additionalData)
|
||||
return
|
||||
}
|
||||
try Task.checkCancellation()
|
||||
|
||||
// Log the action
|
||||
delegateObject?.actionDelegate?.logAction?(withActionInformation: json, additionalData: additionalData)
|
||||
|
||||
do {
|
||||
MVMCoreActionHandler.log(string: "Begin Action: \(model.actionType)", additionalData: additionalData)
|
||||
let handlerType = try ModelRegistry.getHandler(model) as! MVMCoreActionHandlerProtocol.Type
|
||||
let handler = handlerType.init()
|
||||
if let handler = handler as? MVMCoreJSONActionHandlerProtocol {
|
||||
try await handler.performAction(with: json, model: model, delegateObject: delegateObject, additionalData: additionalData)
|
||||
} else {
|
||||
try await handler.performAction(model, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
} catch ModelRegistry.Error.handlerNotMapped {
|
||||
try Task.checkCancellation()
|
||||
// Allows custom handling if there no handler for the action.
|
||||
guard try await handleUnregisteredAction(with: model, json: json, additionalData: additionalData, delegateObject: delegateObject) else {
|
||||
MVMCoreActionHandler.log(string: "Failed Action Unknown", additionalData: additionalData)
|
||||
throw ActionError.unknownAction(type: model.actionType)
|
||||
}
|
||||
} catch {
|
||||
MVMCoreActionHandler.log(string: "Failed Action \(error)", additionalData: additionalData)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/// Subclass to handle and any actions where a handler was not registered. Checks with the delegate handlesUnknownAction function
|
||||
open func handleUnregisteredAction(with model: ActionModelProtocol, json: [AnyHashable: Any], additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) async throws -> Bool {
|
||||
// Check if the delegate handles the action.
|
||||
if try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.handlesUnknownAction(for: model, delegateObject: delegateObject, additionalData: additionalData) == true {
|
||||
MVMCoreActionHandler.log(string: "Unknown handled (Handler not registered): \(model.actionType) \(String(describing: delegateObject?.actionDelegate))", additionalData: additionalData)
|
||||
return true
|
||||
} else if let closure = delegateObject?.actionDelegate?.handleUnknownActionType {
|
||||
MVMCoreActionHandler.log(string: "Unknown handled (Handler not registered): \(model.actionType) \(String(describing: delegateObject?.actionDelegate))", additionalData: additionalData)
|
||||
// Check if the legacy delegate handles the action.
|
||||
closure(model.actionType, json, additionalData)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
41
MVMCore/MVMCore/Utility/MVMCoreError.swift
Normal file
41
MVMCore/MVMCore/Utility/MVMCoreError.swift
Normal file
@ -0,0 +1,41 @@
|
||||
//
|
||||
// MVMCoreError.swift
|
||||
// MVMCore
|
||||
//
|
||||
// Created by Scott Pfeil on 7/27/22.
|
||||
// Copyright © 2022 myverizon. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public enum MVMCoreError: MVMError, CustomStringConvertible {
|
||||
case error(code: Int, messageToDisplay: String? = nil, messageToLog: String)
|
||||
case errorObject(_ object: MVMCoreErrorObject)
|
||||
|
||||
public var errorCode: Int {
|
||||
switch self {
|
||||
case MVMCoreError.error(let code, _, _):
|
||||
return code
|
||||
case MVMCoreError.errorObject(let object):
|
||||
return object.code
|
||||
}
|
||||
}
|
||||
|
||||
public var description: String {
|
||||
switch self {
|
||||
case MVMCoreError.error(_, _, let messageToLog):
|
||||
return messageToLog
|
||||
case MVMCoreError.errorObject(let object):
|
||||
return object.messageToLog ?? "Error"
|
||||
}
|
||||
}
|
||||
|
||||
public var errorDescription: String? {
|
||||
switch self {
|
||||
case MVMCoreError.error(_, let message, _):
|
||||
return message ?? MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess)
|
||||
case MVMCoreError.errorObject(let object):
|
||||
return object.messageToDisplay ?? MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess)
|
||||
}
|
||||
}
|
||||
}
|
||||
18
MVMCore/MVMCore/Utility/MVMError.swift
Normal file
18
MVMCore/MVMCore/Utility/MVMError.swift
Normal file
@ -0,0 +1,18 @@
|
||||
//
|
||||
// MVMError.swift
|
||||
// MVMCore
|
||||
//
|
||||
// Created by Scott Pfeil on 7/27/22.
|
||||
// Copyright © 2022 myverizon. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
protocol MVMError: LocalizedError, CustomNSError {}
|
||||
extension MVMError {
|
||||
public var errorDescription: String? { return MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess) }
|
||||
|
||||
public static var errorDomain: String {
|
||||
return ErrorDomainNative
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user