Merge branch 'develop' of https://gitlab.verizon.com/BPHV_MIPS/mvm_core into feature/LoadingOverlay-Text
This commit is contained in:
commit
3cab2464be
@ -11,9 +11,19 @@ import Foundation
|
||||
open class ActionOpenPageHandler: MVMCoreJSONActionHandlerProtocol {
|
||||
required public init() {}
|
||||
|
||||
func requestParamaters(for model: ActionOpenPageModel) -> MVMCoreRequestParameters {
|
||||
let requestParameters = model.requestParameters.copy() as! MVMCoreRequestParameters
|
||||
if let pageType = requestParameters.pageType {
|
||||
// Re-evaluate required & optional modules as action models might have been generated prior to recent additions to the mapping.
|
||||
requestParameters.modules = MVMCoreViewControllerMappingObject.shared()?.modulesRequired(forPageType: pageType) as? [String]
|
||||
requestParameters.optionalModules = MVMCoreViewControllerMappingObject.shared()?.modulesOptional(forPageType: pageType) as? [String]
|
||||
}
|
||||
return requestParameters
|
||||
}
|
||||
|
||||
open func performAction(with JSON: [AnyHashable : Any], model: ActionModelProtocol, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) async throws {
|
||||
guard let model = model as? ActionOpenPageModel else { return }
|
||||
let requestParameters: MVMCoreRequestParameters = model.requestParameters.copy() as! MVMCoreRequestParameters
|
||||
let requestParameters = requestParamaters(for: model)
|
||||
do {
|
||||
if let closure = delegateObject?.actionDelegate?.handleOpenPage {
|
||||
// Legacy code will use the old handler function and break the task chain here.
|
||||
|
||||
@ -14,15 +14,7 @@ open class ActionShareHandler: MVMCoreActionHandlerProtocol {
|
||||
|
||||
open func execute(with model: ActionModelProtocol, delegateObject: DelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) async throws {
|
||||
guard let model = model as? ActionShareModel else { return }
|
||||
var shareData: [Any]
|
||||
switch model.sharedType {
|
||||
case .text:
|
||||
shareData = [model.sharedText]
|
||||
case .url:
|
||||
let url = try URL.createURL(with: model.sharedText)
|
||||
shareData = [url]
|
||||
}
|
||||
try await shareWith(activityItems: shareData, model: model)
|
||||
try await shareWith(activityItems: model.items.map { $0.value }, model: model)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@ -33,17 +25,7 @@ open class ActionShareHandler: MVMCoreActionHandlerProtocol {
|
||||
controller.completionWithItemsHandler = {(activityType: UIActivity.ActivityType?, completed: Bool, returnedItems: [Any]?, error: Error?) in
|
||||
if completed {
|
||||
// Activity was completed, considered finished.
|
||||
if activityType == .copyToPasteboard {
|
||||
// Allow copy
|
||||
MVMCoreSessionObject.sharedGlobal()?.copyString(toClipboard: model.sharedText)
|
||||
}
|
||||
continuation.resume()
|
||||
} 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: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: model.actionType)) {
|
||||
MVMCoreLoggingHandler.addError(toLog: errorObject)
|
||||
}
|
||||
} else if let error = error {
|
||||
continuation.resume(throwing: error)
|
||||
} else {
|
||||
|
||||
@ -6,14 +6,51 @@
|
||||
// Copyright © 2020 myverizon. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
public struct ActionShareModel: ActionModelProtocol {
|
||||
public struct ActionShareItemModel: Codable {
|
||||
|
||||
public enum SharedType: String, Codable {
|
||||
case text
|
||||
case url
|
||||
}
|
||||
|
||||
public var type: SharedType
|
||||
public var value: Any
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case type
|
||||
case value
|
||||
}
|
||||
|
||||
public init(type: SharedType, value: Any) {
|
||||
self.type = type
|
||||
self.value = value
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
type = try typeContainer.decode(SharedType.self, forKey: .type)
|
||||
switch type {
|
||||
case .text:
|
||||
value = try typeContainer.decode(String.self, forKey: .value)
|
||||
case .url:
|
||||
value = try typeContainer.decode(URL.self, forKey: .value)
|
||||
}
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(type, forKey: .type)
|
||||
switch type {
|
||||
case .text:
|
||||
try container.encode(value as! String, forKey: .value)
|
||||
case .url:
|
||||
try container.encode(value as! URL, forKey: .value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct ActionShareModel: ActionModelProtocol {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
@ -21,8 +58,7 @@ public struct ActionShareModel: ActionModelProtocol {
|
||||
public static var identifier: String = "share"
|
||||
|
||||
public var actionType: String = ActionShareModel.identifier
|
||||
public var sharedType: SharedType
|
||||
public var sharedText: String
|
||||
public var items: [ActionShareItemModel]
|
||||
public var extraParameters: JSONValueDictionary?
|
||||
public var analyticsData: JSONValueDictionary?
|
||||
|
||||
@ -30,10 +66,54 @@ public struct ActionShareModel: ActionModelProtocol {
|
||||
// MARK: - Initializer
|
||||
//--------------------------------------------------
|
||||
|
||||
public init(sharedText: String, sharedType: SharedType, _ extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) {
|
||||
self.sharedType = sharedType
|
||||
self.sharedText = sharedText
|
||||
public init(items: [ActionShareItemModel], _ extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) {
|
||||
self.items = items
|
||||
self.extraParameters = extraParameters
|
||||
self.analyticsData = analyticsData
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codable
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case actionType
|
||||
case items
|
||||
case sharedType
|
||||
case sharedText
|
||||
}
|
||||
|
||||
private enum DeprecatedCodingKeys: String, CodingKey {
|
||||
case sharedType
|
||||
case sharedText
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
if let items = try typeContainer.decodeIfPresent([ActionShareItemModel].self, forKey: .items) {
|
||||
self.init(items: items)
|
||||
} else {
|
||||
// Legacy
|
||||
try self.init(deprecatedFrom: decoder)
|
||||
}
|
||||
}
|
||||
|
||||
private init(deprecatedFrom decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: DeprecatedCodingKeys.self)
|
||||
let type = try typeContainer.decode(ActionShareItemModel.SharedType.self, forKey: .sharedType)
|
||||
var value: Any
|
||||
switch type {
|
||||
case .url:
|
||||
value = try typeContainer.decode(URL.self, forKey: .sharedText)
|
||||
default:
|
||||
value = try typeContainer.decode(String.self, forKey: .sharedText)
|
||||
}
|
||||
items = [ActionShareItemModel(type: type, value: value)]
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(actionType, forKey: .actionType)
|
||||
try container.encode(items, forKey: .items)
|
||||
}
|
||||
}
|
||||
|
||||
@ -299,6 +299,9 @@
|
||||
if ([[MVMCoreObject sharedInstance].globalLoadDelegate respondsToSelector:@selector(getJSONForRequestParameters:)]) {
|
||||
NSDictionary *json = [[MVMCoreObject sharedInstance].globalLoadDelegate getJSONForRequestParameters:requestParameters];
|
||||
if (json) {
|
||||
#if HARD_CODED_RESPONSE_DELAY > 0
|
||||
[NSThread sleepForTimeInterval:HARD_CODED_RESPONSE_DELAY];
|
||||
#endif
|
||||
completionHandler(json);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -104,13 +104,17 @@
|
||||
timingOutIn: timeout) { (receivedParameter) in
|
||||
// Queue the results for merge.
|
||||
parametersWorkQueue.async {
|
||||
if (returnedList[index] != nil) {
|
||||
MVMCoreLoggingHandler.addError(toLog: MVMCoreErrorObject(title: nil, message: "Client parameter \(parameterType) has already executed. The completion handler should only be called once!", code: ErrorCode.default.rawValue, domain: ErrorDomainNative, location: String(describing: ClientParameterHandler.self))!)
|
||||
} else {
|
||||
MVMCoreLoggingHandler.shared()?.logCoreEvent(.clientParameterFetchComplete(name: parameterType, uuid: requestUUID[index], actionId: actionId))
|
||||
returnedList[index] = receivedParameter
|
||||
group.leave() // Leaving is only done after setup (barriered).
|
||||
guard !complete else {
|
||||
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "Client \(parameterType) responded after task completion.")
|
||||
return
|
||||
}
|
||||
guard returnedList[index] == nil else {
|
||||
MVMCoreLoggingHandler.addError(toLog: MVMCoreErrorObject(title: nil, message: "Client parameter \(parameterType) has already executed. The completion handler should only be called once!", code: ErrorCode.default.rawValue, domain: ErrorDomainNative, location: String(describing: ClientParameterHandler.self))!)
|
||||
return
|
||||
}
|
||||
MVMCoreLoggingHandler.shared()?.logCoreEvent(.clientParameterFetchComplete(name: parameterType, uuid: requestUUID[index], actionId: actionId))
|
||||
returnedList[index] = receivedParameter
|
||||
group.leave() // Leaving is only done after setup (barriered).
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ public protocol ClientParameterProtocol: ModelHandlerProtocol {
|
||||
|
||||
var clientParameterModel: ClientParameterModelProtocol { get set }
|
||||
|
||||
func fetchClientParameters(requestParameters: [String: Any], timingOutIn timeout: Double, completionHandler:@escaping ([String: AnyHashable]?) -> ())
|
||||
func fetchClientParameters(requestParameters: [String: Any], timingOutIn timeout: TimeInterval, completionHandler:@escaping ([String: AnyHashable]?) -> ())
|
||||
|
||||
/// Default parameter for timeout scenarios. It will use the protocol extension method bydefault. Can override to send custom values.
|
||||
func valueOnTimeout() -> [String: AnyHashable]
|
||||
@ -28,10 +28,8 @@ public extension ClientParameterProtocol {
|
||||
}
|
||||
|
||||
/// The handler should call this method to pass the parameter back to the caller.
|
||||
func returnParameters(_ isFlatMap: Bool, _ parameter: [String: AnyHashable]?, completionHandler: @escaping ([String: AnyHashable]?) -> ()) {
|
||||
guard let parameter = parameter else {
|
||||
return completionHandler(nil)
|
||||
}
|
||||
/// If using isFlatMap, you must provide at least 1 element in parameters or it will result in triggering a timeout.
|
||||
func returnParameters(_ isFlatMap: Bool, _ parameter: [String: AnyHashable], completionHandler: @escaping ([String: AnyHashable]?) -> ()) {
|
||||
if isFlatMap {
|
||||
completionHandler(parameter)
|
||||
} else {
|
||||
|
||||
@ -27,7 +27,7 @@ public extension MVMCoreActionUtility {
|
||||
- Parameter timemout: the time the operation has to finish before throwing a timeout error.
|
||||
- Parameter operation: the operation to perform.
|
||||
*/
|
||||
static func perform<T>(with timeout: Int = 1, operation: @escaping @Sendable () async throws -> T) async throws -> T {
|
||||
static func perform<T>(withTimeout timeout: TimeInterval, operation: @escaping @Sendable () async throws -> T) async throws -> T {
|
||||
return try await withCheckedThrowingContinuation { continuation in
|
||||
Task {
|
||||
await withThrowingTaskGroup(of: T.self) { group in
|
||||
@ -40,7 +40,7 @@ public extension MVMCoreActionUtility {
|
||||
// Task for time out.
|
||||
group.addTask {
|
||||
try Task.checkCancellation()
|
||||
try await Task.sleep(nanoseconds: UInt64(timeout) * NSEC_PER_SEC)
|
||||
try await Task.sleep(nanoseconds: UInt64(timeout * TimeInterval(NSEC_PER_SEC)))
|
||||
throw MVMCoreActionUtilityError.timeOut
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user