From d44235bd036894d23d4f7c9eb7d497606bb579f2 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Thu, 19 Oct 2023 12:30:13 -0400 Subject: [PATCH 1/2] Action Share update --- .../ActionHandling/ActionShareHandler.swift | 14 +--- .../ActionHandling/ActionShareModel.swift | 84 +++++++++++++++++-- 2 files changed, 78 insertions(+), 20 deletions(-) diff --git a/MVMCore/MVMCore/ActionHandling/ActionShareHandler.swift b/MVMCore/MVMCore/ActionHandling/ActionShareHandler.swift index e82baa2..c6e699a 100644 --- a/MVMCore/MVMCore/ActionHandling/ActionShareHandler.swift +++ b/MVMCore/MVMCore/ActionHandling/ActionShareHandler.swift @@ -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,10 +25,6 @@ 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. diff --git a/MVMCore/MVMCore/ActionHandling/ActionShareModel.swift b/MVMCore/MVMCore/ActionHandling/ActionShareModel.swift index 2203a8c..7895c68 100644 --- a/MVMCore/MVMCore/ActionHandling/ActionShareModel.swift +++ b/MVMCore/MVMCore/ActionHandling/ActionShareModel.swift @@ -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,44 @@ 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(sharedText: String, sharedType: ActionShareItemModel.SharedType, _ extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) { + items = [ActionShareItemModel(type: sharedType, value: sharedText)] self.extraParameters = extraParameters self.analyticsData = analyticsData } + + //-------------------------------------------------- + // MARK: - Codable + //-------------------------------------------------- + + private enum CodingKeys: String, CodingKey { + case actionType + case items + 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.items = items + } else { + // Legacy + 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) + } } From def76778e52dc0ddbfb81e2a43506c966f268f7b Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Fri, 20 Oct 2023 11:51:14 -0400 Subject: [PATCH 2/2] Code review updates for scoping of functions. Fix continuation leak. --- .../ActionHandling/ActionShareHandler.swift | 6 ---- .../ActionHandling/ActionShareModel.swift | 34 ++++++++++++------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/MVMCore/MVMCore/ActionHandling/ActionShareHandler.swift b/MVMCore/MVMCore/ActionHandling/ActionShareHandler.swift index c6e699a..3634c11 100644 --- a/MVMCore/MVMCore/ActionHandling/ActionShareHandler.swift +++ b/MVMCore/MVMCore/ActionHandling/ActionShareHandler.swift @@ -26,12 +26,6 @@ open class ActionShareHandler: MVMCoreActionHandlerProtocol { if completed { // Activity was completed, considered finished. 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 { diff --git a/MVMCore/MVMCore/ActionHandling/ActionShareModel.swift b/MVMCore/MVMCore/ActionHandling/ActionShareModel.swift index 7895c68..ddeb7d8 100644 --- a/MVMCore/MVMCore/ActionHandling/ActionShareModel.swift +++ b/MVMCore/MVMCore/ActionHandling/ActionShareModel.swift @@ -66,8 +66,8 @@ public struct ActionShareModel: ActionModelProtocol { // MARK: - Initializer //-------------------------------------------------- - public init(sharedText: String, sharedType: ActionShareItemModel.SharedType, _ extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) { - items = [ActionShareItemModel(type: sharedType, value: sharedText)] + public init(items: [ActionShareItemModel], _ extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) { + self.items = items self.extraParameters = extraParameters self.analyticsData = analyticsData } @@ -83,24 +83,34 @@ public struct ActionShareModel: ActionModelProtocol { 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.items = items + self.init(items: items) } else { // Legacy - 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)] + 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)