diff --git a/MVMCore/MVMCore/ActionHandling/ActionActionsHandler.swift b/MVMCore/MVMCore/ActionHandling/ActionActionsHandler.swift index 67a6a9b..6a0d34c 100644 --- a/MVMCore/MVMCore/ActionHandling/ActionActionsHandler.swift +++ b/MVMCore/MVMCore/ActionHandling/ActionActionsHandler.swift @@ -37,14 +37,14 @@ open class ActionActionsHandler: MVMCoreJSONActionHandlerProtocol { await withThrowingTaskGroup(of: Void.self) { group in for action in model.actions { group.addTask{ - try await MVMCoreActionHandler.handleActionCheckingDelegate(with: action, additionalData: additionalData, delegateObject: delegateObject) + try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: action, additionalData: additionalData, delegateObject: delegateObject) } } } } else { for action in model.actions { try Task.checkCancellation() - try await MVMCoreActionHandler.handleActionCheckingDelegate(with: action, additionalData: additionalData, delegateObject: delegateObject) + try await (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction(with: action, additionalData: additionalData, delegateObject: delegateObject) } } } diff --git a/MVMCore/MVMCore/ActionHandling/ActionContactHandler.swift b/MVMCore/MVMCore/ActionHandling/ActionContactHandler.swift index 5e73ba3..513bd2d 100644 --- a/MVMCore/MVMCore/ActionHandling/ActionContactHandler.swift +++ b/MVMCore/MVMCore/ActionHandling/ActionContactHandler.swift @@ -106,11 +106,11 @@ open class ActionContactHandler: NSObject, MVMCoreActionHandlerProtocol, CNConta var phoneNumbers = [labelValue] phoneNumbers.append(contentsOf: existingContact.phoneNumbers) existingContact.phoneNumbers = phoneNumbers - MVMCoreDispatchUtility.performBlock(onMainThread: { + Task { @MainActor in let controller = CNContactViewController(forNewContact: existingContact) controller.contactStore = store controller.delegate = self MVMCoreNavigationHandler.shared()?.push(controller, animated: true) - }) + } } } diff --git a/MVMCore/MVMCore/ActionHandling/ActionDelegateProtocol.swift b/MVMCore/MVMCore/ActionHandling/ActionDelegateProtocol.swift index fd9ad8c..6788d08 100644 --- a/MVMCore/MVMCore/ActionHandling/ActionDelegateProtocol.swift +++ b/MVMCore/MVMCore/ActionHandling/ActionDelegateProtocol.swift @@ -11,9 +11,6 @@ import Foundation public protocol ActionDelegateProtocol: MVMCoreActionDelegateProtocol { /// Asks the delegate to perform the action. func performAction(with model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) async throws - - /// 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 } public extension ActionDelegateProtocol { @@ -21,8 +18,4 @@ public extension ActionDelegateProtocol { func performAction(with model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) async throws { try await MVMCoreActionHandler.shared()?.handleAction(with: model, additionalData: additionalData, delegateObject: delegateObject) } - - func handlesUnknownAction(for model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws -> Bool { - return false - } } diff --git a/MVMCore/MVMCore/ActionHandling/ActionOpenPageHandler.swift b/MVMCore/MVMCore/ActionHandling/ActionOpenPageHandler.swift index 8c747c9..7011008 100644 --- a/MVMCore/MVMCore/ActionHandling/ActionOpenPageHandler.swift +++ b/MVMCore/MVMCore/ActionHandling/ActionOpenPageHandler.swift @@ -8,41 +8,17 @@ import Foundation -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(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws { guard let model = model as? ActionOpenPageModel else { return } - 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 - 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)! - } - 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(model.requestParameters, JSON, additionalData) } else { - try await performRequestAddingClientParameters(with: requestParameters, model: model, delegateObject: delegateObject, additionalData: additionalData) + try await performRequestAddingClientParameters(with: model.requestParameters, model: model, delegateObject: delegateObject, additionalData: additionalData) } } catch { try handle(error: error, model: model, delegateObject: delegateObject) @@ -52,6 +28,7 @@ open class ActionOpenPageHandler: MVMCoreJSONActionHandlerProtocol { open func execute(with model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws { guard let model = model as? ActionOpenPageModel else { return } do { + // Pass through the old function for legacy open page. let json = try MVMCoreActionHandler.convertActionToJSON(model) try await performAction(with: json, model: model, delegateObject: delegateObject, additionalData: additionalData) } catch { @@ -66,8 +43,7 @@ open class ActionOpenPageHandler: MVMCoreJSONActionHandlerProtocol { let fetchedParameters = try await ClientParameterHandler().getClientParameters(with: parametersToFetch, requestParameters: requestParameters.parameters as? [String : Any] ?? [:], showLoadingOverlay: !requestParameters.backgroundRequest) { requestParameters.add(fetchedParameters) } - - // Makes the request and waits for it. + try Task.checkCancellation() try await MVMCoreLoadHandler.sharedGlobal()?.performRequest(with: requestParameters, delegateObject: delegateObject, additionalData: additionalData) } diff --git a/MVMCore/MVMCore/ActionHandling/ActionOpenPageModel.swift b/MVMCore/MVMCore/ActionHandling/ActionOpenPageModel.swift index 9a17245..c6a2b9a 100644 --- a/MVMCore/MVMCore/ActionHandling/ActionOpenPageModel.swift +++ b/MVMCore/MVMCore/ActionHandling/ActionOpenPageModel.swift @@ -6,6 +6,7 @@ // Copyright © 2019 Suresh, Kamlesh. All rights reserved. // +import Foundation open class ActionOpenPageModel: ActionModelProtocol, ActionOpenPageProtocol, ClientParameterActionProtocol { //-------------------------------------------------- @@ -16,15 +17,18 @@ open class ActionOpenPageModel: ActionModelProtocol, ActionOpenPageProtocol, Cli open var actionType: String = identifier open var pageType: String open var modules: [String]? - open var baseURL: String? + open var baseURL: URL? open var appContext: String? - open var requestURL: String? + open var requestURL: URL? open var extraParameters: JSONValueDictionary? open var analyticsData: JSONValueDictionary? open var presentationStyle: String? open var tabBarIndex: Int? open var background: Bool? open var clientParameters: ClientParameterModel? + open var customTimeoutTime: TimeInterval? + + open var requestParameters: MVMCoreRequestParameters //-------------------------------------------------- // MARK: - Initialzier @@ -37,5 +41,73 @@ open class ActionOpenPageModel: ActionModelProtocol, ActionOpenPageProtocol, Cli self.analyticsData = analyticsData self.tabBarIndex = tabBarIndex self.background = background + + requestParameters = MVMCoreRequestParameters(pageType: pageType, extraParameters: extraParameters.toJSON())! + if let background = background { + requestParameters.backgroundRequest = background + } + requestParameters.actionMap = toJSON() + } + + //-------------------------------------------------- + // MARK: - Codable + //-------------------------------------------------- + + private enum CodingKeys: String, CodingKey { + case actionType + case pageType + case modules + case baseURL + case appContext + case requestURL + case extraParameters + case analyticsData + case presentationStyle + case tabBarIndex + case background + case clientParameters + case customTimeoutTime + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + pageType = try typeContainer.decode(String.self, forKey: .pageType) + baseURL = try typeContainer.decodeIfPresent(URL.self, forKey: .baseURL) + appContext = try typeContainer.decodeIfPresent(String.self, forKey: .appContext) + requestURL = try typeContainer.decodeIfPresent(URL.self, forKey: .requestURL) + modules = try typeContainer.decodeIfPresent([String].self, forKey: .modules) + presentationStyle = try typeContainer.decodeIfPresent(String.self, forKey: .presentationStyle) + tabBarIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .tabBarIndex) + background = try typeContainer.decodeIfPresent(Bool.self, forKey: .background) + clientParameters = try typeContainer.decodeIfPresent(ClientParameterModel.self, forKey: .clientParameters) + customTimeoutTime = try typeContainer.decodeIfPresent(TimeInterval.self, forKey: .customTimeoutTime) + extraParameters = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .extraParameters) + analyticsData = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .analyticsData) + + requestParameters = MVMCoreRequestParameters(pageType: pageType, additionalModules: modules ?? [], extraParameters: extraParameters.toJSON())! + requestParameters.contextRoot = appContext + requestParameters.alternateBaseURL = baseURL + requestParameters.url = requestURL + requestParameters.customTimeoutTime = customTimeoutTime as NSNumber? + if let background = background { + requestParameters.backgroundRequest = background + } + requestParameters.actionMap = toJSON() + } + + open func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(pageType, forKey: .pageType) + try container.encodeIfPresent(baseURL, forKey: .baseURL) + try container.encodeIfPresent(appContext, forKey: .appContext) + try container.encodeIfPresent(requestURL, forKey: .requestURL) + try container.encodeIfPresent(modules, forKey: .modules) + try container.encodeIfPresent(presentationStyle, forKey: .presentationStyle) + try container.encodeIfPresent(tabBarIndex, forKey: .tabBarIndex) + try container.encodeIfPresent(background, forKey: .background) + try container.encodeIfPresent(clientParameters, forKey: .clientParameters) + try container.encodeIfPresent(customTimeoutTime, forKey: .customTimeoutTime) + try container.encodeIfPresent(extraParameters, forKey: .extraParameters) + try container.encodeIfPresent(analyticsData, forKey: .analyticsData) } } diff --git a/MVMCore/MVMCore/ActionHandling/ActionOpenUrlHandler.swift b/MVMCore/MVMCore/ActionHandling/ActionOpenUrlHandler.swift index b38de51..4961fa3 100644 --- a/MVMCore/MVMCore/ActionHandling/ActionOpenUrlHandler.swift +++ b/MVMCore/MVMCore/ActionHandling/ActionOpenUrlHandler.swift @@ -77,7 +77,7 @@ open class ActionOpenUrlHandler: MVMCoreJSONActionHandlerProtocol { } catch { // Log error and continue MVMCoreLoggingHandler.shared()?.handleDebugMessage("Failed to open app url: \(appURL)") - if let errorObject = MVMCoreActionHandler.shared()?.getActionErrorObject(for: error, actionType: model.actionType, delegateObject: delegateObject) { + if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: model.actionType)) { MVMCoreLoggingHandler.addError(toLog: errorObject) } } diff --git a/MVMCore/MVMCore/ActionHandling/ActionShareHandler.swift b/MVMCore/MVMCore/ActionHandling/ActionShareHandler.swift index 9ae2c94..3f8cb11 100644 --- a/MVMCore/MVMCore/ActionHandling/ActionShareHandler.swift +++ b/MVMCore/MVMCore/ActionHandling/ActionShareHandler.swift @@ -40,7 +40,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 = MVMCoreActionHandler.shared()?.getActionErrorObject(for: error, actionType: model.actionType, delegateObject: delegateObject) { + let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: model.actionType)) { MVMCoreLoggingHandler.addError(toLog: errorObject) } } else if let error = error { diff --git a/MVMCore/MVMCore/ActionHandling/MVMCoreActionDelegateProtocol.h b/MVMCore/MVMCore/ActionHandling/MVMCoreActionDelegateProtocol.h index e29a184..53cde7f 100644 --- a/MVMCore/MVMCore/ActionHandling/MVMCoreActionDelegateProtocol.h +++ b/MVMCore/MVMCore/ActionHandling/MVMCoreActionDelegateProtocol.h @@ -33,9 +33,6 @@ // Handles any unknown action types. Can overwrite for more specific handling. - (void)handleUnknownActionType:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData; -// Handles any action errors. Can overwrite for more specific handling. -- (void)handleActionError:(nonnull MVMCoreErrorObject *)error additionalData:(nullable NSDictionary *)additionalData; - // Lets the delegate know that another internal module app is about to be launched - (void)prepareForOpenOtherAppModule:(nullable NSString *)module; diff --git a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.swift b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.swift index 2dae006..a64d4f6 100644 --- a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.swift +++ b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.swift @@ -15,7 +15,7 @@ public protocol MVMCoreActionHandlerProtocol: ModelHandlerProtocol { func execute(with 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. +/// 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. Should not be used for new actions. 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 @@ -38,6 +38,7 @@ public protocol MVMCoreJSONActionHandlerProtocol: MVMCoreActionHandlerProtocol { } } + /// Used to temporarily store the json in additionalData. private let jsonKey = "MVMCore.JSON" /// Returns the action handler stored in the MVMCoreObject @@ -73,16 +74,6 @@ public protocol MVMCoreJSONActionHandlerProtocol: MVMCoreActionHandlerProtocol { // MARK: - Error Handling - /// Converts the Error into an ErrorObject. - open func getActionErrorObject(for error: Error, actionType: String, delegateObject: DelegateObject? = nil) -> MVMCoreErrorObject { - switch error { - case MVMCoreError.errorObject(let object): - return object - default: - return MVMCoreErrorObject.createErrorObject(for: error, location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: actionType))! - } - } - /// Returns a common description for the error location. @objc public static func getErrorLocation(with delegate: MVMCoreActionDelegateProtocol?, actionType: String) -> String { return "\(String(describing: delegate))_\(actionType)" @@ -90,36 +81,19 @@ public protocol MVMCoreJSONActionHandlerProtocol: MVMCoreActionHandlerProtocol { // MARK: - Action Handling - /// Convenience function for letting the actionDelegate handle the action, else the handler handles the action. - public static func handleActionCheckingDelegate(with model: ActionModelProtocol, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) async throws { - if let closure = (delegateObject?.actionDelegate as? ActionDelegateProtocol)?.performAction { - try await closure(model, additionalData, delegateObject) - } else { - try await MVMCoreActionHandler.shared()?.handleAction(with: model, additionalData: additionalData, delegateObject: delegateObject) - } - } - - /// Convenience function for letting the actionDelegate handle the action, else the handler handles the action. - @discardableResult - public static func asyncHandleActionCheckingDelegate(with model: ActionModelProtocol, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) -> Task { - return Task(priority: .userInitiated) { - try await handleActionCheckingDelegate(with: model, additionalData: additionalData, delegateObject: delegateObject) - } - } - /// Handle an action with the given model. open func handleAction(with model: ActionModelProtocol, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) async throws { try Task.checkCancellation() var additionalData = MVMCoreActionHandler.setUUID(additionalData: additionalData) + MVMCoreActionHandler.log(string: "Begin Action: \(model.actionType)", additionalData: additionalData) + defer { + MVMCoreActionHandler.log(string: "End Action: \(model.actionType)", additionalData: additionalData) + } let json = try additionalData?.removeValue(forKey: jsonKey) as? [AnyHashable : Any] ?? MVMCoreActionHandler.convertActionToJSON(model) // Log the action delegateObject?.actionDelegate?.logAction?(withActionInformation: json, additionalData: additionalData) - MVMCoreActionHandler.log(string: "Begin Action: \(model.actionType)", additionalData: additionalData) - defer { - MVMCoreActionHandler.log(string: "End Action: \(model.actionType)", additionalData: additionalData) - } do { let handlerType = try ModelRegistry.getHandler(model) as! MVMCoreActionHandlerProtocol.Type let handler = handlerType.init() @@ -150,11 +124,6 @@ public protocol MVMCoreJSONActionHandlerProtocol: MVMCoreActionHandlerProtocol { delegateObject?.actionDelegate?.logAction?(withActionInformation: model.toJSON(), additionalData: additionalData) } - open func defaultHandle(error: Error, model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) { - let errorObject = getActionErrorObject(for: error, actionType: model.actionType, delegateObject: delegateObject) - defaultHandleActionError(errorObject, additionalData: additionalData) - } - /// Logs the error. @objc open func defaultHandleActionError(_ error: MVMCoreErrorObject, additionalData: [AnyHashable: Any]?) { guard error.logError else { return } @@ -198,16 +167,14 @@ public protocol MVMCoreJSONActionHandlerProtocol: MVMCoreActionHandlerProtocol { switch error { case ModelRegistry.Error.decoderErrorModelNotMapped: // If the model is not mapped, give the legacy classes a chance to handle it. - if let closure = delegateObject?.actionDelegate?.handleUnknownActionType { - MVMCoreActionHandler.log(string: "Unknown handled (Model not registered): \(String(describing: actionType)) \(String(describing: delegateObject?.actionDelegate))", additionalData: additionalData) - closure(actionType, json, additionalData) - } else { + if try await handleUnregisteredAction(with: nil, json: json!, additionalData: additionalData, delegateObject: delegateObject) == false { fallthrough } default: MVMCoreActionHandler.log(string: "Failed Action: Error \(error)", additionalData: additionalData) - let errorObject = getActionErrorObject(for: error, actionType: actionType ?? "noAction", delegateObject: delegateObject) - delegateObject?.actionDelegate?.handleActionError?(errorObject, additionalData: additionalData) ?? defaultHandleActionError(errorObject, additionalData: additionalData) + if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: actionType ?? "noAction")) { + defaultHandleActionError(errorObject, additionalData: additionalData) + } } } } @@ -230,15 +197,13 @@ public protocol MVMCoreJSONActionHandlerProtocol: MVMCoreActionHandlerProtocol { } /// 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 { + 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) + let actionType = json.optionalStringForKey(KeyActionType) + if let closure = delegateObject?.actionDelegate?.handleUnknownActionType { + MVMCoreActionHandler.log(string: "Unknown handled (Handler not registered): \(String(describing: actionType)) \(String(describing: delegateObject?.actionDelegate))", additionalData: additionalData) // Check if the legacy delegate handles the action. - closure(model.actionType, json, additionalData) + closure(actionType, json, additionalData) return true } else { return false diff --git a/MVMCore/MVMCore/Utility/MVMCoreError.swift b/MVMCore/MVMCore/Utility/MVMCoreError.swift index 61c1034..31fe2f8 100644 --- a/MVMCore/MVMCore/Utility/MVMCoreError.swift +++ b/MVMCore/MVMCore/Utility/MVMCoreError.swift @@ -39,3 +39,14 @@ public enum MVMCoreError: MVMError, CustomStringConvertible { } } } + +@objc public extension NSError { + @objc func checkForMVMCoreError() -> MVMCoreErrorObject? { + switch self as Error { + case MVMCoreError.errorObject(let object): + return object + default: + return nil + } + } +} diff --git a/MVMCore/MVMCore/Utility/MVMCoreErrorObject.m b/MVMCore/MVMCore/Utility/MVMCoreErrorObject.m index d61075b..09f76b4 100644 --- a/MVMCore/MVMCore/Utility/MVMCoreErrorObject.m +++ b/MVMCore/MVMCore/Utility/MVMCoreErrorObject.m @@ -14,6 +14,7 @@ #import "MVMCoreJSONConstants.h" #import "MVMCoreHardcodedStringsConstants.h" #import "MVMCoreDispatchUtility.h" +#import @implementation MVMCoreErrorObject @@ -106,8 +107,11 @@ } + (nullable instancetype)createErrorObjectForNSError:(nonnull NSError *)error location:(nullable NSString *)location { - - MVMCoreErrorObject *errorObject = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[error localizedDescription] messageToLog:[error description] code:[error code] domain:ErrorDomainSystem location:location]; + MVMCoreErrorObject *errorObject = [error checkForMVMCoreError]; + if (errorObject) { + return errorObject; + } + errorObject = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[error localizedDescription] messageToLog:[error description] code:[error code] domain:ErrorDomainSystem location:location]; if ([error.domain isEqualToString:NSURLErrorDomain]) { errorObject.systemDomain = error.domain; if ([[MVMCoreObject sharedInstance].globalLoadDelegate respondsToSelector:@selector(getNativeScreenForRequestError:requestObject:)]) {