From 908fc0287e55f6c90049f18fb4e22fc2e504698d Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 18 Feb 2020 15:17:57 -0500 Subject: [PATCH] adding a new action type. updated action map flow. --- MVMCore/MVMCore.xcodeproj/project.pbxproj | 4 ++ .../ActionHandling/MVMCoreActionHandler.m | 52 ++++++++++++++++++- .../MVMCore/Constants/MVMCoreJSONConstants.h | 3 ++ .../MVMCore/Constants/MVMCoreJSONConstants.m | 3 ++ .../Models/ActionType/ActionShareModel.swift | 28 ++++++++++ MVMCore/MVMCore/Models/ModelMapping.swift | 2 + .../MVMCore/Session/MVMCoreSessionObject.h | 33 ++++++++---- .../MVMCore/Session/MVMCoreSessionObject.m | 10 ++++ 8 files changed, 122 insertions(+), 13 deletions(-) create mode 100644 MVMCore/MVMCore/Models/ActionType/ActionShareModel.swift diff --git a/MVMCore/MVMCore.xcodeproj/project.pbxproj b/MVMCore/MVMCore.xcodeproj/project.pbxproj index 9f5937b..68d29d5 100644 --- a/MVMCore/MVMCore.xcodeproj/project.pbxproj +++ b/MVMCore/MVMCore.xcodeproj/project.pbxproj @@ -32,6 +32,7 @@ 01F2A05023A82D0800D954D8 /* ActionTopAlertModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F2A04F23A82D0800D954D8 /* ActionTopAlertModel.swift */; }; 01F2A05223A8325100D954D8 /* ModelMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F2A05123A8325100D954D8 /* ModelMapping.swift */; }; 0A42538F23F3414800554656 /* Codable+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A42538E23F3414800554656 /* Codable+Helpers.swift */; }; + 0AFF597A23FC6E60005C24E8 /* ActionShareModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AFF597923FC6E60005C24E8 /* ActionShareModel.swift */; }; 30349BF11FCCA78A00546A1E /* MVMCoreSessionTimeHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 30349BEF1FCCA78A00546A1E /* MVMCoreSessionTimeHandler.h */; settings = {ATTRIBUTES = (Public, ); }; }; 30349BF21FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 30349BF01FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m */; }; 881D26931FCC9D180079C521 /* MVMCoreErrorObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 881D268F1FCC9D180079C521 /* MVMCoreErrorObject.m */; }; @@ -180,6 +181,7 @@ 0A11030B20864F94008ADD90 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; 0A11030C20864F9A008ADD90 /* es-MX */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-MX"; path = "es-MX.lproj/Localizable.strings"; sourceTree = ""; }; 0A42538E23F3414800554656 /* Codable+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Codable+Helpers.swift"; sourceTree = ""; }; + 0AFF597923FC6E60005C24E8 /* ActionShareModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionShareModel.swift; sourceTree = ""; }; 30349BEF1FCCA78A00546A1E /* MVMCoreSessionTimeHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreSessionTimeHandler.h; sourceTree = ""; }; 30349BF01FCCA78A00546A1E /* MVMCoreSessionTimeHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreSessionTimeHandler.m; sourceTree = ""; }; 881D268F1FCC9D180079C521 /* MVMCoreErrorObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreErrorObject.m; sourceTree = ""; }; @@ -460,6 +462,7 @@ 01F2A04F23A82D0800D954D8 /* ActionTopAlertModel.swift */, 01C851D023CF97FE0021F976 /* ActionBackModel.swift */, EAE09C5D23F4389600765089 /* ActionOpenPanelModel.swift */, + 0AFF597923FC6E60005C24E8 /* ActionShareModel.swift */, ); path = ActionType; sourceTree = ""; @@ -923,6 +926,7 @@ AFED77A61FCCA29400BAE689 /* MVMCoreViewControllerStoryBoardMappingObject.m in Sources */, AF43A57C1FBA5E6A008E9347 /* MVMCoreHardcodedStringsConstants.m in Sources */, AFBB965D1FBA3A570008D868 /* MFFreebeeHandler.m in Sources */, + 0AFF597A23FC6E60005C24E8 /* ActionShareModel.swift in Sources */, AFEEE81F1FCDF3CA00B5EDD0 /* MVMCoreLoggingHandler.m in Sources */, 01F2A05223A8325100D954D8 /* ModelMapping.swift in Sources */, AFBB969E1FBA3A9A0008D868 /* MVMCoreAlertObject.m in Sources */, diff --git a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m index 46cb18d..5252b3e 100644 --- a/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m +++ b/MVMCore/MVMCore/ActionHandling/MVMCoreActionHandler.m @@ -47,7 +47,7 @@ NSString * const KeyActionTypeOpen = @"openPage"; } - (void)handleAction:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { - + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // Logs the action. @@ -55,28 +55,43 @@ NSString * const KeyActionTypeOpen = @"openPage"; if ([actionType isEqualToString:KeyActionTypeOpen]) { [self openPageAction:actionInformation additionalData:additionalData delegateObject:delegateObject]; + } else if ([actionType isEqualToString:KeyActionTypeLinkAway]) { [self linkAwayAction:actionInformation additionalData:additionalData delegateObject:delegateObject]; + } else if ([actionType isEqualToString:KeyActionTypeRestart]) { [self restartAction:actionInformation additionalData:additionalData delegateObject:delegateObject]; + } else if ([actionType isEqualToString:KeyActionTypeBack]) { [self backAction:actionInformation additionalData:additionalData delegateObject:delegateObject]; + } else if ([actionType isEqualToString:KeyActionTypeCall]) { [self callAction:actionInformation additionalData:additionalData delegateObject:delegateObject]; + + } else if ([actionType isEqualToString:KeyActionTypeShare]) { + [self shareAction:actionInformation additionalData:additionalData delegateObject:delegateObject]; + } else if ([actionType isEqualToString:KeyActionTypePreviousSubmit]) { [self previousSubmitAction:actionInformation additionalData:additionalData delegateObject:delegateObject]; + } else if ([actionType isEqualToString:KeyActionTypePopup]) { [self popupAction:actionInformation additionalData:additionalData delegateObject:delegateObject]; + } else if ([actionType isEqualToString:KeyActionTypeTopAlert]) { [self topAlertAction:actionInformation additionalData:additionalData delegateObject:delegateObject]; + } else if ([actionType isEqualToString:KeyActionTypeRedirect]) { [self redirectAction:actionInformation additionalData:additionalData delegateObject:delegateObject]; + } else if ([actionType isEqualToString:KeyActionTypeCancel]) { [self cancelAction:actionInformation additionalData:additionalData delegateObject:delegateObject]; + } else if ([actionType isEqualToString:KeyActionTypeSettings]) { [self settingsAction:actionInformation additionalData:additionalData delegateObject:delegateObject]; + } else if ([actionType isEqualToString:KeyActionTypeCollapseNotification]) { [self collapseNotificationAction:actionInformation additionalData:additionalData delegateObject:delegateObject]; + } else if (![self handleOtherActions:actionType actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject]) { // not a known action type. [self unknownAction:actionType actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject]; @@ -137,6 +152,39 @@ NSString * const KeyActionTypeOpen = @"openPage"; } } +- (void)shareAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { + + NSString *shareType = [actionInformation stringForKey:KeyShareType]; + NSString *shareText = [actionInformation stringForKey:KeyShareText]; + NSArray* shareData; + + if ([shareType isEqualToString:@"text"]) { + shareData = @[shareText]; + + } else if ([shareType isEqualToString:@"url"]) { + if (shareText.length > 0) { + shareData = @[shareText, [NSURL URLWithString:shareText]]; + } + } else if ([shareType isEqualToString:@"image"]) { + // TODO: Implement image parsing. 🏂 + + } else if ([shareType isEqualToString:@"file"]) { + // TODO: Implement file parsing. 🌋 + } + + if (shareData.count > 0) { + [MVMCoreDispatchUtility performBlockOnMainThread:^{ + UIActivityViewController* activityViewController = [[UIActivityViewController alloc] initWithActivityItems:shareData applicationActivities:nil]; + activityViewController.excludedActivityTypes = @[UIActivityTypeAirDrop, UIActivityT]; + if (activityViewController == nil) { + return; + } + activityViewController.popoverPresentationController.sourceView = [MVMCoreNavigationHandler sharedNavigationHandler].viewControllerToPresentOn.view; + [[MVMCoreNavigationHandler sharedNavigationHandler] presentViewController:activityViewController animated:YES]; + }]; + } +} + - (void)restartAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { // Invalidates the session before restarting. @@ -244,7 +292,7 @@ NSString * const KeyActionTypeOpen = @"openPage"; NSString *type = [actionInformation string:KeyPageType]; if ([@"location" isEqualToString:type] || [@"push" isEqualToString:type]) { [MVMCoreActionUtility linkAway:UIApplicationOpenSettingsURLString appURLString:nil]; - } else { + } else { // No known settings type MVMCoreErrorObject *error = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorUnableToProcess] code:ErrorCodeInvalidSettingType domain:ErrorDomainNative location:[NSString stringWithFormat:@"%@_%@",NSStringFromClass([delegateObject.actionDelegate class]),KeyActionTypeSettings]]; [self handleActionError:error actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject]; diff --git a/MVMCore/MVMCore/Constants/MVMCoreJSONConstants.h b/MVMCore/MVMCore/Constants/MVMCoreJSONConstants.h index 7be0d11..902ee78 100644 --- a/MVMCore/MVMCore/Constants/MVMCoreJSONConstants.h +++ b/MVMCore/MVMCore/Constants/MVMCoreJSONConstants.h @@ -30,6 +30,9 @@ extern NSString * const KeyTitle; extern NSString * const KeyMessage; extern NSString * const KeyActionTypeRestart; extern NSString * const KeyActionTypeBack; +extern NSString * const KeyActionTypeShare; +extern NSString * const KeyShareType; +extern NSString * const KeyShareText; extern NSString * const KeyActionTypeCall; extern NSString * const KeyActionTypePreviousSubmit; extern NSString * const KeyActionTypePopup; diff --git a/MVMCore/MVMCore/Constants/MVMCoreJSONConstants.m b/MVMCore/MVMCore/Constants/MVMCoreJSONConstants.m index 4945096..b30d03c 100644 --- a/MVMCore/MVMCore/Constants/MVMCoreJSONConstants.m +++ b/MVMCore/MVMCore/Constants/MVMCoreJSONConstants.m @@ -18,6 +18,8 @@ NSString * const KeyErrorHeading = @"errorHdg"; NSString * const KeyPage = @"Page"; NSString * const KeyPageType = @"pageType"; +NSString * const KeyShareText = @"shareText"; +NSString * const KeyShareType = @"shareType"; NSString * const KeyModuleMap = @"ModuleMap"; NSString * const KeyModuleList = @"modules"; NSString * const KeyPageMap = @"PageMap"; @@ -30,6 +32,7 @@ NSString * const KeyTitle = @"title"; NSString * const KeyMessage = @"message"; NSString * const KeyActionTypeRestart = @"restart"; NSString * const KeyActionTypeBack = @"back"; +NSString * const KeyActionTypeShare = @"share"; NSString * const KeyActionTypeCall = @"call"; NSString * const KeyActionTypePreviousSubmit = @"previousSubmit"; NSString * const KeyActionTypePopup = @"popup"; diff --git a/MVMCore/MVMCore/Models/ActionType/ActionShareModel.swift b/MVMCore/MVMCore/Models/ActionType/ActionShareModel.swift new file mode 100644 index 0000000..a9bee03 --- /dev/null +++ b/MVMCore/MVMCore/Models/ActionType/ActionShareModel.swift @@ -0,0 +1,28 @@ +// +// ActionShareModel.swift +// MVMCore +// +// Created by Kevin Christiano on 2/18/20. +// Copyright © 2020 myverizon. All rights reserved. +// + +import UIKit + +class ActionShareModel: ActionModelProtocol { + + public static var identifier: String = "share" + + public var actionType: String? + public var title: String? + public var pageType: String + public var shareType: String + public var shareText: String + public var extraParameters: JSONValueDictionary? + public var analyticsData: JSONValueDictionary? + + public init(pageType: String,shareText: String,shareType: String) { + self.pageType = pageType + self.shareType = shareType + self.shareText = shareText + } +} diff --git a/MVMCore/MVMCore/Models/ModelMapping.swift b/MVMCore/MVMCore/Models/ModelMapping.swift index 9464576..4209a3b 100644 --- a/MVMCore/MVMCore/Models/ModelMapping.swift +++ b/MVMCore/MVMCore/Models/ModelMapping.swift @@ -9,6 +9,7 @@ import Foundation @objcMembers public class ModelMapping: NSObject { + public static func registerObjects() { try? ModelRegistry.register(ActionOpenPageModel.self) try? ModelRegistry.register(ActionOpenUrlModel.self) @@ -18,5 +19,6 @@ import Foundation try? ModelRegistry.register(ActionTopAlertModel.self) try? ModelRegistry.register(ActionBackModel.self) try? ModelRegistry.register(ActionOpenPanelModel.self) + try? ModelRegistry.register(ActionShareModel.self) } } diff --git a/MVMCore/MVMCore/Session/MVMCoreSessionObject.h b/MVMCore/MVMCore/Session/MVMCoreSessionObject.h index ceb4e23..27b9475 100644 --- a/MVMCore/MVMCore/Session/MVMCoreSessionObject.h +++ b/MVMCore/MVMCore/Session/MVMCoreSessionObject.h @@ -10,37 +10,48 @@ @interface MVMCoreSessionObject : NSObject -// the session used for all requests. +/// the session used for all requests. @property (nullable, strong, nonatomic) NSURLSession *session; -// the session used for all Freebee requests. +/// the session used for all Freebee requests. @property (nullable, strong, nonatomic) NSURLSession *freeBeeSession; -// The server base url (Until prepay is native, this will always be postpay). +/// The server base url (Until prepay is native, this will always be postpay). @property (nullable, strong, nonatomic) NSURL *baseURL; -// The context root to use on the base url. +/// The context root to use on the base url. @property (nullable, strong, nonatomic) NSString *contextRoot; +/// Last string copied to clipboard. Used for clearing clipboard check when app goes into backgroud. +@property (strong, nonatomic, nullable) NSString *clipboardString; -// Returns the shared instance of this singleton + +/// Returns the shared instance of this singleton + (nullable instancetype)sharedGlobal; -// Creates the nsurlsession with default configuration and no delegate. Can subclass for different session. +/// Creates the nsurlsession with default configuration and no delegate. Can subclass for different session. - (nonnull NSURLSession *)createNSURLSession; -// Gets inital parameters for request parameters. +/// Gets inital parameters for request parameters. - (nullable NSDictionary *)getInitialParameters; -// Gets inital parameters for request parameters excluding any items given a list of key names. + +/// Gets inital parameters for request parameters excluding any items given a list of key names. - (nullable NSDictionary *)getInitialParametersExcludingSections:(nullable NSSet *)excludeSections; -// Restarts the application session state. Can clear variables and pass a page type if needed. +/// Restarts the application session state. Can clear variables and pass a page type if needed. - (void)restartSessionWithPageType:(nullable NSString *)pageType parameters:(nullable NSDictionary *)parameters clearAllVariables:(BOOL)clearAllVariables; -// Redirect, leaving the current app experience. +/// Redirect, leaving the current app experience. - (void)redirectWithInfo:(nullable NSDictionary *)dictionary; -// Clears the session singleton. Creates a new session NSURLSession also. +/// Clears the session singleton. Creates a new session NSURLSession also. - (void)clearSessionObject; +/// Copys string to clipboard and assigns self.clipboardString for validation +/// Should only be used when expected string is a secure string +-(void)copyStringToClipboard :(nullable NSString *)clipboardString; + +/// validates if clip board should or should no be cleared. Returns YES if string is safe to go into background. +-(BOOL)clipboadStringIsValid:(nullable NSString *)clipboardString; + @end diff --git a/MVMCore/MVMCore/Session/MVMCoreSessionObject.m b/MVMCore/MVMCore/Session/MVMCoreSessionObject.m index 52a8355..eea367f 100644 --- a/MVMCore/MVMCore/Session/MVMCoreSessionObject.m +++ b/MVMCore/MVMCore/Session/MVMCoreSessionObject.m @@ -48,6 +48,16 @@ } +-(void)copyStringToClipboard :(nullable NSString *)clipboardString { + self.clipboardString = clipboardString; + UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; + pasteboard.string = clipboardString; +} + +-(BOOL)clipboadStringIsValid:(nullable NSString *)clipboardString { + return [clipboardString isEqualToString:self.clipboardString]; +} + - (void)clearSessionObject { [self.session invalidateAndCancel]; self.session = [self createNSURLSession];