Merge branch 'feature/open_url_options' into 'develop'
Feature/open url options See merge request BPHV_MIPS/mvm_core!190
This commit is contained in:
commit
e89c10daae
@ -69,6 +69,7 @@
|
|||||||
94C014D924212360005811A9 /* ActionSettingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C014D824212360005811A9 /* ActionSettingModel.swift */; };
|
94C014D924212360005811A9 /* ActionSettingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C014D824212360005811A9 /* ActionSettingModel.swift */; };
|
||||||
A332F33F20C7231700DCD9D9 /* MVMCoreViewControllerAnimatedTransitioning.h in Headers */ = {isa = PBXBuildFile; fileRef = A332F33E20C7231600DCD9D9 /* MVMCoreViewControllerAnimatedTransitioning.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
A332F33F20C7231700DCD9D9 /* MVMCoreViewControllerAnimatedTransitioning.h in Headers */ = {isa = PBXBuildFile; fileRef = A332F33E20C7231600DCD9D9 /* MVMCoreViewControllerAnimatedTransitioning.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
AF1201832108C9B400E2F592 /* MVMCoreViewManagerViewControllerProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = AF1201812108C9B400E2F592 /* MVMCoreViewManagerViewControllerProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
AF1201832108C9B400E2F592 /* MVMCoreViewManagerViewControllerProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = AF1201812108C9B400E2F592 /* MVMCoreViewManagerViewControllerProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
|
AF130B8E2788DF6E00C6C03C /* OpenURLOptionsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF130B8D2788DF6E00C6C03C /* OpenURLOptionsModel.swift */; };
|
||||||
AF26DDAE1FCE6A37004E8F65 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = AF26DDB01FCE6A37004E8F65 /* Localizable.strings */; };
|
AF26DDAE1FCE6A37004E8F65 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = AF26DDB01FCE6A37004E8F65 /* Localizable.strings */; };
|
||||||
AF43A5771FBA5B7C008E9347 /* MVMCoreJSONConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = AF43A5751FBA5B7C008E9347 /* MVMCoreJSONConstants.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
AF43A5771FBA5B7C008E9347 /* MVMCoreJSONConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = AF43A5751FBA5B7C008E9347 /* MVMCoreJSONConstants.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
AF43A5781FBA5B7C008E9347 /* MVMCoreJSONConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = AF43A5761FBA5B7C008E9347 /* MVMCoreJSONConstants.m */; };
|
AF43A5781FBA5B7C008E9347 /* MVMCoreJSONConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = AF43A5761FBA5B7C008E9347 /* MVMCoreJSONConstants.m */; };
|
||||||
@ -91,6 +92,7 @@
|
|||||||
AF43A7411FC5FA6F008E9347 /* MVMCoreViewProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = AF43A7401FC5FA6F008E9347 /* MVMCoreViewProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
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, ); }; };
|
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 */; };
|
AF43A74D1FC6109F008E9347 /* MVMCoreSessionObject.m in Sources */ = {isa = PBXBuildFile; fileRef = AF43A74B1FC6109F008E9347 /* MVMCoreSessionObject.m */; };
|
||||||
|
AF8D13392774EA1D008AF4A9 /* ActionOpenUrlHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF8D13382774EA1D008AF4A9 /* ActionOpenUrlHandler.swift */; };
|
||||||
AFBB96341FBA34310008D868 /* MVMCoreErrorConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB96321FBA34310008D868 /* MVMCoreErrorConstants.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
AFBB96341FBA34310008D868 /* MVMCoreErrorConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB96321FBA34310008D868 /* MVMCoreErrorConstants.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
AFBB96351FBA34310008D868 /* MVMCoreErrorConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB96331FBA34310008D868 /* MVMCoreErrorConstants.m */; };
|
AFBB96351FBA34310008D868 /* MVMCoreErrorConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = AFBB96331FBA34310008D868 /* MVMCoreErrorConstants.m */; };
|
||||||
AFBB96381FBA39E70008D868 /* MVMCoreLoadDelegateProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB96371FBA39E70008D868 /* MVMCoreLoadDelegateProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
AFBB96381FBA39E70008D868 /* MVMCoreLoadDelegateProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = AFBB96371FBA39E70008D868 /* MVMCoreLoadDelegateProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
@ -212,6 +214,7 @@
|
|||||||
94C014D824212360005811A9 /* ActionSettingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionSettingModel.swift; sourceTree = "<group>"; };
|
94C014D824212360005811A9 /* ActionSettingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionSettingModel.swift; sourceTree = "<group>"; };
|
||||||
A332F33E20C7231600DCD9D9 /* MVMCoreViewControllerAnimatedTransitioning.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreViewControllerAnimatedTransitioning.h; sourceTree = "<group>"; };
|
A332F33E20C7231600DCD9D9 /* MVMCoreViewControllerAnimatedTransitioning.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreViewControllerAnimatedTransitioning.h; sourceTree = "<group>"; };
|
||||||
AF1201812108C9B400E2F592 /* MVMCoreViewManagerViewControllerProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreViewManagerViewControllerProtocol.h; sourceTree = "<group>"; };
|
AF1201812108C9B400E2F592 /* MVMCoreViewManagerViewControllerProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreViewManagerViewControllerProtocol.h; sourceTree = "<group>"; };
|
||||||
|
AF130B8D2788DF6E00C6C03C /* OpenURLOptionsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenURLOptionsModel.swift; sourceTree = "<group>"; };
|
||||||
AF26DDAF1FCE6A37004E8F65 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
AF26DDAF1FCE6A37004E8F65 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
AF43A5751FBA5B7C008E9347 /* MVMCoreJSONConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreJSONConstants.h; sourceTree = "<group>"; };
|
AF43A5751FBA5B7C008E9347 /* MVMCoreJSONConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreJSONConstants.h; sourceTree = "<group>"; };
|
||||||
AF43A5761FBA5B7C008E9347 /* MVMCoreJSONConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreJSONConstants.m; sourceTree = "<group>"; };
|
AF43A5761FBA5B7C008E9347 /* MVMCoreJSONConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreJSONConstants.m; sourceTree = "<group>"; };
|
||||||
@ -237,6 +240,7 @@
|
|||||||
AF43A7401FC5FA6F008E9347 /* MVMCoreViewProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreViewProtocol.h; sourceTree = "<group>"; };
|
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>"; };
|
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>"; };
|
AF43A74B1FC6109F008E9347 /* MVMCoreSessionObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreSessionObject.m; sourceTree = "<group>"; };
|
||||||
|
AF8D13382774EA1D008AF4A9 /* ActionOpenUrlHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionOpenUrlHandler.swift; sourceTree = "<group>"; };
|
||||||
AFBB96321FBA34310008D868 /* MVMCoreErrorConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreErrorConstants.h; sourceTree = "<group>"; };
|
AFBB96321FBA34310008D868 /* MVMCoreErrorConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreErrorConstants.h; sourceTree = "<group>"; };
|
||||||
AFBB96331FBA34310008D868 /* MVMCoreErrorConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreErrorConstants.m; sourceTree = "<group>"; };
|
AFBB96331FBA34310008D868 /* MVMCoreErrorConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreErrorConstants.m; sourceTree = "<group>"; };
|
||||||
AFBB96371FBA39E70008D868 /* MVMCoreLoadDelegateProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreLoadDelegateProtocol.h; sourceTree = "<group>"; };
|
AFBB96371FBA39E70008D868 /* MVMCoreLoadDelegateProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreLoadDelegateProtocol.h; sourceTree = "<group>"; };
|
||||||
@ -455,7 +459,6 @@
|
|||||||
01F2A03523A80A7300D954D8 /* ActionModelProtocol.swift */,
|
01F2A03523A80A7300D954D8 /* ActionModelProtocol.swift */,
|
||||||
946EE1BB237B691A0036751F /* ActionOpenPageModel.swift */,
|
946EE1BB237B691A0036751F /* ActionOpenPageModel.swift */,
|
||||||
01DB1F2A26444F7F000F1AF4 /* ActionOpenPageProtocol.swift */,
|
01DB1F2A26444F7F000F1AF4 /* ActionOpenPageProtocol.swift */,
|
||||||
01F2A03823A812DD00D954D8 /* ActionOpenUrlModel.swift */,
|
|
||||||
01F2A04B23A82B1B00D954D8 /* ActionCallModel.swift */,
|
01F2A04B23A82B1B00D954D8 /* ActionCallModel.swift */,
|
||||||
01C851D023CF97FE0021F976 /* ActionBackModel.swift */,
|
01C851D023CF97FE0021F976 /* ActionBackModel.swift */,
|
||||||
0AFF597923FC6E60005C24E8 /* ActionShareModel.swift */,
|
0AFF597923FC6E60005C24E8 /* ActionShareModel.swift */,
|
||||||
@ -615,6 +618,9 @@
|
|||||||
AFBB96B61FBA3CEC0008D868 /* MVMCoreActionHandler.h */,
|
AFBB96B61FBA3CEC0008D868 /* MVMCoreActionHandler.h */,
|
||||||
AFBB96B71FBA3CEC0008D868 /* MVMCoreActionHandler.m */,
|
AFBB96B71FBA3CEC0008D868 /* MVMCoreActionHandler.m */,
|
||||||
D27073CC25BB4CEF001C7246 /* MVMCoreActionHandler+Extension.swift */,
|
D27073CC25BB4CEF001C7246 /* MVMCoreActionHandler+Extension.swift */,
|
||||||
|
AF130B8D2788DF6E00C6C03C /* OpenURLOptionsModel.swift */,
|
||||||
|
01F2A03823A812DD00D954D8 /* ActionOpenUrlModel.swift */,
|
||||||
|
AF8D13382774EA1D008AF4A9 /* ActionOpenUrlHandler.swift */,
|
||||||
);
|
);
|
||||||
path = ActionHandling;
|
path = ActionHandling;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -844,6 +850,8 @@
|
|||||||
946EE1A7237B5B1C0036751F /* ModelRegistry.swift in Sources */,
|
946EE1A7237B5B1C0036751F /* ModelRegistry.swift in Sources */,
|
||||||
AFBB96641FBA3A570008D868 /* MVMCoreLoadHandler.m in Sources */,
|
AFBB96641FBA3A570008D868 /* MVMCoreLoadHandler.m in Sources */,
|
||||||
AFFCFA671FCCC0D700FD0730 /* MVMCoreLoadingOverlayHandler.m in Sources */,
|
AFFCFA671FCCC0D700FD0730 /* MVMCoreLoadingOverlayHandler.m in Sources */,
|
||||||
|
AF8D13392774EA1D008AF4A9 /* ActionOpenUrlHandler.swift in Sources */,
|
||||||
|
AF130B8E2788DF6E00C6C03C /* OpenURLOptionsModel.swift in Sources */,
|
||||||
AFBB968E1FBA3A9A0008D868 /* MVMCoreNavigationHandler.m in Sources */,
|
AFBB968E1FBA3A9A0008D868 /* MVMCoreNavigationHandler.m in Sources */,
|
||||||
BB780ADF250F8C890030BD2F /* ActionNoopModel.swift in Sources */,
|
BB780ADF250F8C890030BD2F /* ActionNoopModel.swift in Sources */,
|
||||||
D2E1FAD92260C3E400AEFD8C /* DelegateObject.swift in Sources */,
|
D2E1FAD92260C3E400AEFD8C /* DelegateObject.swift in Sources */,
|
||||||
|
|||||||
50
MVMCore/MVMCore/ActionHandling/ActionOpenUrlHandler.swift
Normal file
50
MVMCore/MVMCore/ActionHandling/ActionOpenUrlHandler.swift
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
//
|
||||||
|
// ActionOpenUrlHandler.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 12/23/21.
|
||||||
|
// Copyright © 2021 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
open class ActionOpenUrlHandler: MVMCoreActionHandlerProtocol {
|
||||||
|
required public init() {}
|
||||||
|
|
||||||
|
open func handleAction(_ model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) {
|
||||||
|
guard let model = model as? ActionOpenUrlModel else { return }
|
||||||
|
MVMCoreDispatchUtility.performBlock(onMainThread: { [self] in
|
||||||
|
// Try loading the app url first, otherwise fall back to browser url.
|
||||||
|
guard let appURL = model.appURL else {
|
||||||
|
openURL(model: model, additionalData: additionalData, delegateObject: delegateObject)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
UIApplication.shared.open(appURL, options: model.appURLOptions?.options ?? [:]) { loaded in
|
||||||
|
guard !loaded else { return }
|
||||||
|
MVMCoreLoggingHandler.shared()?.handleDebugMessage("Failed to open app url: \(appURL)")
|
||||||
|
openURL(model: model, additionalData: additionalData, delegateObject: delegateObject)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Opens the url.
|
||||||
|
open func openURL(model: ActionOpenUrlModel, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) {
|
||||||
|
UIApplication.shared.open(model.browserUrl, options: [:]) { [self] loaded in
|
||||||
|
guard !loaded else { return }
|
||||||
|
handleError(model: model, additionalData: additionalData, delegateObject: delegateObject)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Handles any url loading errors.
|
||||||
|
open func handleError(model: ActionOpenUrlModel, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) {
|
||||||
|
if let error = MVMCoreErrorObject(title: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorTitle),
|
||||||
|
message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess),
|
||||||
|
messageToLog: "Unable to load URL: \(String(describing: model.browserUrl))", code: ErrorCode.linkawayFailed.rawValue,
|
||||||
|
domain: ErrorDomainNative,
|
||||||
|
location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: ActionOpenUrlModel.identifier)) {
|
||||||
|
MVMCoreDispatchUtility.performBlock(inBackground: {
|
||||||
|
MVMCoreActionHandler.shared()?.handleActionError(error, actionInformation: model.toJSON(), additionalData: additionalData, delegateObject: delegateObject)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
63
MVMCore/MVMCore/ActionHandling/ActionOpenUrlModel.swift
Normal file
63
MVMCore/MVMCore/ActionHandling/ActionOpenUrlModel.swift
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
//
|
||||||
|
// ActionOpenUrlModel.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Suresh, Kamlesh on 12/16/19.
|
||||||
|
// Copyright © 2019 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@objcMembers 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?
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Initialzier
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public init(browserUrl: URL) {
|
||||||
|
self.browserUrl = browserUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Codable
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case actionType
|
||||||
|
case browserUrl
|
||||||
|
case appURL
|
||||||
|
case appURLOptions
|
||||||
|
case extraParameters
|
||||||
|
case analyticsData
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
browserUrl = try typeContainer.decode(URL.self, forKey: .browserUrl)
|
||||||
|
appURL = try typeContainer.decodeIfPresent(URL.self, forKey: .appURL)
|
||||||
|
appURLOptions = try typeContainer.decodeIfPresent(OpenUrlOptionsModel.self, forKey: .appURLOptions)
|
||||||
|
extraParameters = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .extraParameters)
|
||||||
|
analyticsData = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .analyticsData)
|
||||||
|
}
|
||||||
|
|
||||||
|
open func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encode(actionType, forKey: .actionType)
|
||||||
|
try container.encode(browserUrl, forKey: .browserUrl)
|
||||||
|
try container.encodeIfPresent(appURL, forKey: .appURL)
|
||||||
|
try container.encodeIfPresent(appURLOptions, forKey: .appURLOptions)
|
||||||
|
try container.encodeIfPresent(extraParameters, forKey: .extraParameters)
|
||||||
|
try container.encodeIfPresent(analyticsData, forKey: .analyticsData)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -77,4 +77,8 @@ public extension MVMCoreActionHandler {
|
|||||||
guard let json = convertActionToJSON(model, delegateObject: delegateObject) else { return }
|
guard let json = convertActionToJSON(model, delegateObject: delegateObject) else { return }
|
||||||
handleAction(model.actionType, actionInformation: json, additionalData: additionalData, delegateObject: delegateObject)
|
handleAction(model.actionType, actionInformation: json, additionalData: additionalData, delegateObject: delegateObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc static func getErrorLocation(with delegate: MVMCoreActionDelegateProtocol?, actionType: String) -> String {
|
||||||
|
return "\(String(describing: delegate))_\(actionType)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -80,20 +80,6 @@ extern NSString * _Nonnull const KeyActionTypeOpen;
|
|||||||
/// Handles action errors.
|
/// Handles action errors.
|
||||||
- (void)handleActionError:(nullable MVMCoreErrorObject *)error actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
- (void)handleActionError:(nullable MVMCoreErrorObject *)error actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
||||||
|
|
||||||
#pragma mark - Link away action
|
|
||||||
|
|
||||||
/// Links away to app or browser
|
|
||||||
- (void)linkAwayAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// Can subclass to add to urls if needed at global level (delegate is also called)
|
|
||||||
- (void)prepareLinkAwayWithURL:(nullable NSURL *)url appURL:(nullable NSURL *)appURL actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// Opens the url
|
|
||||||
- (void)openURL:(nullable NSURL *)url appURL:(nullable NSURL *)appURL actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
/// opens the url in a webview.
|
|
||||||
- (void)openURLInWebView:(nullable NSURL *)url actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject;
|
|
||||||
|
|
||||||
#pragma mark - Default Action Protocol Functions
|
#pragma mark - Default Action Protocol Functions
|
||||||
|
|
||||||
/// Currently no default log action but this will eventually be server driven.
|
/// Currently no default log action but this will eventually be server driven.
|
||||||
|
|||||||
@ -60,9 +60,6 @@ NSString * const KeyActionTypeOpen = @"openPage";
|
|||||||
if ([actionType isEqualToString:KeyActionTypeOpen]) {
|
if ([actionType isEqualToString:KeyActionTypeOpen]) {
|
||||||
[self openPageAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
[self openPageAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
||||||
|
|
||||||
} else if ([actionType isEqualToString:KeyActionTypeLinkAway]) {
|
|
||||||
[self linkAwayAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
|
|
||||||
} else if ([actionType isEqualToString:KeyActionTypeRestart]) {
|
} else if ([actionType isEqualToString:KeyActionTypeRestart]) {
|
||||||
[self restartAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
[self restartAction:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
||||||
|
|
||||||
@ -450,92 +447,6 @@ NSString * const KeyActionTypeOpen = @"openPage";
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Open URL
|
|
||||||
|
|
||||||
- (void)linkAwayAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
|
|
||||||
__weak typeof(self) weakSelf = self;
|
|
||||||
void (^performAction)(NSDictionary*) = ^(NSDictionary* extraParamters) {
|
|
||||||
|
|
||||||
NSMutableDictionary *actionWithClientParameters = [actionInformation mutableCopy];
|
|
||||||
NSMutableDictionary *extraParametersT = [extraParamters mutableCopy];
|
|
||||||
[extraParametersT addEntriesFromDictionary:[actionWithClientParameters dictionaryForKey:KeyExtraParameters]];
|
|
||||||
actionWithClientParameters[KeyExtraParameters] = extraParametersT;
|
|
||||||
|
|
||||||
// Gets the app url
|
|
||||||
NSURL *appURL = nil;
|
|
||||||
NSString *appURLString = [actionWithClientParameters string:KeyLinkAwayAppURL];
|
|
||||||
if (appURLString.length > 0) {
|
|
||||||
appURL = [NSURL URLWithString:appURLString];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gets the browser url
|
|
||||||
NSURL *otherURL = nil;
|
|
||||||
NSString *otherURLString = [actionWithClientParameters string:KeyLinkAwayURL];
|
|
||||||
if (otherURLString.length > 0) {
|
|
||||||
otherURL = [NSURL URLWithString:otherURLString];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provide the URL and App URL to be modified if needed by a subclass or delegate.
|
|
||||||
[weakSelf prepareLinkAwayWithURL:otherURL appURL:appURL actionInformation:actionWithClientParameters additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
};
|
|
||||||
|
|
||||||
[self getClientParameter:[actionInformation dict:KeyClientParameters]
|
|
||||||
requestParameters:nil
|
|
||||||
showLoadingOverlay:true
|
|
||||||
completionHandler:performAction];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)prepareLinkAwayWithURL:(nullable NSURL *)url appURL:(nullable NSURL *)appURL actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
|
|
||||||
void(^openURL)(NSURL *, NSURL *, NSDictionary *, NSDictionary *) = ^(NSURL *appURL, NSURL *URL, NSDictionary *actionInformation, NSDictionary *additionalData) {
|
|
||||||
[self openURL:url appURL:appURL actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Allow delegate to modify before opening the url.
|
|
||||||
if ([delegateObject.actionDelegate respondsToSelector:@selector(shouldLinkAwayWithURL:appURL:actionInformation:additionalData:linkAwayBlock:)]) {
|
|
||||||
[delegateObject.actionDelegate shouldLinkAwayWithURL:url appURL:appURL actionInformation:actionInformation additionalData:additionalData linkAwayBlock:openURL];
|
|
||||||
} else {
|
|
||||||
openURL(appURL,url,actionInformation,additionalData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)openURL:(nullable NSURL *)url appURL:(nullable NSURL *)appURL actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
|
|
||||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
|
||||||
|
|
||||||
// First try to open the application.
|
|
||||||
if (appURL && [[UIApplication sharedApplication] canOpenURL:appURL]) {
|
|
||||||
[[UIApplication sharedApplication] openURL:appURL options:@{} completionHandler:NULL];
|
|
||||||
} else if (url && [[UIApplication sharedApplication] canOpenURL:url]) {
|
|
||||||
|
|
||||||
// Check if we should load in webview
|
|
||||||
BOOL openInWebview = [actionInformation boolForKey:@"openInWebview"];
|
|
||||||
if (openInWebview) {
|
|
||||||
[self openURLInWebView:url actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
} else {
|
|
||||||
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:NULL];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
[MVMCoreDispatchUtility performBlockInBackground:^{
|
|
||||||
// Cannot linkaway, show error.
|
|
||||||
MVMCoreErrorObject *error = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorUnableToProcess] code:ErrorCodeLinkawayFailed domain:ErrorDomainNative location:[NSString stringWithFormat:@"%@_%@",NSStringFromClass([delegateObject.actionDelegate class]),KeyActionTypeLinkAway]];
|
|
||||||
[self handleActionError:error actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)openURLInWebView:(nullable NSURL *)url actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject {
|
|
||||||
|
|
||||||
// Presents standard webview.
|
|
||||||
SFSafariViewController *safariViewController = [[SFSafariViewController alloc] initWithURL:url];
|
|
||||||
//safariViewController.delegate = self;
|
|
||||||
safariViewController.preferredBarTintColor = [UIColor whiteColor];
|
|
||||||
safariViewController.preferredControlTintColor = [UIColor blackColor];
|
|
||||||
[[MVMCoreNavigationHandler sharedNavigationHandler] presentViewController:safariViewController animated:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Default Action Protocol
|
#pragma mark - Default Action Protocol
|
||||||
|
|
||||||
+ (void)defaultLogAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject{
|
+ (void)defaultLogAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject{
|
||||||
|
|||||||
38
MVMCore/MVMCore/ActionHandling/OpenURLOptionsModel.swift
Normal file
38
MVMCore/MVMCore/ActionHandling/OpenURLOptionsModel.swift
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// OpenURLOptionsModel.swift
|
||||||
|
// MVMCore
|
||||||
|
//
|
||||||
|
// Created by Scott Pfeil on 1/7/22.
|
||||||
|
// Copyright © 2022 myverizon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// A model for UIApplication.OpenExternalURLOptionsKey
|
||||||
|
open class OpenUrlOptionsModel: Codable {
|
||||||
|
public var options: [UIApplication.OpenExternalURLOptionsKey: Any]
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Codable
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
// TODO: add eventAttribution
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case universalLinksOnly // UIApplicationOpenURLOptionUniversalLinksOnly
|
||||||
|
}
|
||||||
|
|
||||||
|
public required init(from decoder: Decoder) throws {
|
||||||
|
options = [:]
|
||||||
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
if let universalLinksValue = try container.decodeIfPresent(Bool.self, forKey: .universalLinksOnly) {
|
||||||
|
options[.universalLinksOnly] = universalLinksValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
if let universalLinksValue = options[.universalLinksOnly] as? Bool {
|
||||||
|
try container.encode(universalLinksValue, forKey: .universalLinksOnly)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,44 +0,0 @@
|
|||||||
//
|
|
||||||
// ActionOpenUrlModel.swift
|
|
||||||
// MVMCore
|
|
||||||
//
|
|
||||||
// Created by Suresh, Kamlesh on 12/16/19.
|
|
||||||
// Copyright © 2019 myverizon. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
@objcMembers public class ActionOpenUrlModel: ActionModelProtocol, ClientParameterActionProtocol {
|
|
||||||
//--------------------------------------------------
|
|
||||||
// MARK: - Properties
|
|
||||||
//--------------------------------------------------
|
|
||||||
|
|
||||||
public static var identifier: String = "openURL"
|
|
||||||
public var actionType: String = ActionOpenUrlModel.identifier
|
|
||||||
// TODO: decode into url once action handler is re-written
|
|
||||||
public var browserUrl: String
|
|
||||||
public var extraParameters: JSONValueDictionary?
|
|
||||||
public var analyticsData: JSONValueDictionary?
|
|
||||||
public var clientParameters: ClientParameterModel?
|
|
||||||
public var appURL: String?
|
|
||||||
|
|
||||||
//TODO: Should be removed in future releases. This should be MF specific.
|
|
||||||
//Missing params
|
|
||||||
public var openOauthWebView: Bool?
|
|
||||||
public var showNativeNavigation: Bool?
|
|
||||||
public var openInWebview: Bool?
|
|
||||||
public var customUserAgent: String?
|
|
||||||
public var postRequest: Bool?
|
|
||||||
public var dontShowProgress: Bool?
|
|
||||||
public var headerParameters: JSONValueDictionary?
|
|
||||||
public var enableNativeScroll: Bool?
|
|
||||||
public var hideUrl: Bool?
|
|
||||||
public var pageType: String?
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
|
||||||
// MARK: - Initialzier
|
|
||||||
//--------------------------------------------------
|
|
||||||
|
|
||||||
public init(browserUrl: String) {
|
|
||||||
self.browserUrl = browserUrl
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -40,9 +40,9 @@ public struct ModelRegistry {
|
|||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - handler: The handling class taking an object of ModelHandlerProtocol.self which is used to register
|
/// - handler: The handling class taking an object of ModelHandlerProtocol.self which is used to register
|
||||||
/// - model: The data object of ModelProtocol.self which is used to register
|
/// - model: The data object of ModelProtocol.self which is used to register
|
||||||
public static func register<H: ModelHandlerProtocol, M: ModelProtocol>(handler: H.Type, for model: M.Type) {
|
public static func register<H: ModelHandlerProtocol, M: ModelProtocol>(handler: H.Type, for model: M.Type, allowsReplace: Bool = false) {
|
||||||
do {
|
do {
|
||||||
try throwable_register(handler: handler, model: model)
|
try throwable_register(handler: handler, model: model, allowsReplace: allowsReplace)
|
||||||
} catch {
|
} catch {
|
||||||
handleError(error)
|
handleError(error)
|
||||||
}
|
}
|
||||||
@ -124,9 +124,9 @@ public struct ModelRegistry {
|
|||||||
/// - handler: The handling class taking an object of ModelHandlerProtocol.self which is used to register
|
/// - handler: The handling class taking an object of ModelHandlerProtocol.self which is used to register
|
||||||
/// - model: The data object of ModelProtocol.self which is used to register
|
/// - model: The data object of ModelProtocol.self which is used to register
|
||||||
/// - Throws: An Error object of `ModelRegistry.Error`
|
/// - Throws: An Error object of `ModelRegistry.Error`
|
||||||
public static func throwable_register<H: ModelHandlerProtocol, M: ModelProtocol>(handler: H.Type, model: M.Type) throws {
|
public static func throwable_register<H: ModelHandlerProtocol, M: ModelProtocol>(handler: H.Type, model: M.Type, allowsReplace: Bool = false) throws {
|
||||||
// Register the type
|
// Register the type
|
||||||
try self.throwable_register(type: model)
|
try self.throwable_register(type: model, allowsReplace: allowsReplace)
|
||||||
|
|
||||||
// Get the key for the handler
|
// Get the key for the handler
|
||||||
let key = model.identifier
|
let key = model.identifier
|
||||||
@ -136,24 +136,31 @@ public struct ModelRegistry {
|
|||||||
|
|
||||||
// Check to ensure the Category/Container combination doesn't exist.
|
// Check to ensure the Category/Container combination doesn't exist.
|
||||||
if category.handlerTypes[key] != nil {
|
if category.handlerTypes[key] != nil {
|
||||||
throw ModelRegistry.Error.duplicateRegistration(message: "ModelHandlerProtocol: \(String(describing: handler)) already exists in Category: \(category.name)")
|
if allowsReplace {
|
||||||
} else {
|
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "Duplicate Registration: writing over \(category.handlerTypes[key]!) with \(handler)")
|
||||||
category.handlerTypes[key] = handler
|
} else {
|
||||||
|
throw ModelRegistry.Error.duplicateRegistration(message: "ModelHandlerProtocol: \(String(describing: handler)) already exists in Category: \(category.name)")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
category.handlerTypes[key] = handler
|
||||||
categories[category.name] = category
|
categories[category.name] = category
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Registers models for Atomic use.
|
/// Registers models for Atomic use.
|
||||||
/// - Parameter type: Takes an object of ModelProtocol.self which is used to register
|
/// - Parameter type: Takes an object of ModelProtocol.self which is used to register
|
||||||
/// - Throws: An Error object of `ModelRegistry.Error`
|
/// - Throws: An Error object of `ModelRegistry.Error`
|
||||||
public static func throwable_register<M: ModelProtocol>(type: M.Type) throws {
|
public static func throwable_register<M: ModelProtocol>(type: M.Type, allowsReplace: Bool = false) throws {
|
||||||
// Get the category for the ModelProtocol
|
// Get the category for the ModelProtocol
|
||||||
var category = getCategory(for: type)
|
var category = getCategory(for: type)
|
||||||
|
|
||||||
// Check to ensure the Category/Type combination doesn't exist.
|
// Check to ensure the Category/Type combination doesn't exist.
|
||||||
if category.instanceTypes[M.identifier] != nil {
|
if category.instanceTypes[M.identifier] != nil {
|
||||||
throw ModelRegistry.Error.duplicateRegistration(message: "ModelProtocol: \(M.identifier) already exists in Category: \(M.categoryName)")
|
if allowsReplace {
|
||||||
|
MVMCoreLoggingHandler.logDebugMessage(withDelegate: "Duplicate Registration: writing over \(category.instanceTypes[M.identifier]!) with \(type)")
|
||||||
|
} else {
|
||||||
|
throw ModelRegistry.Error.duplicateRegistration(message: "ModelProtocol: \(M.identifier) already exists in Category: \(M.categoryName)")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
category.instanceTypes[M.identifier] = type
|
category.instanceTypes[M.identifier] = type
|
||||||
|
|||||||
@ -13,7 +13,7 @@
|
|||||||
open class func registerActions() {
|
open class func registerActions() {
|
||||||
ModelRegistry.register(ActionRunJavaScriptModel.self)
|
ModelRegistry.register(ActionRunJavaScriptModel.self)
|
||||||
ModelRegistry.register(ActionOpenPageModel.self)
|
ModelRegistry.register(ActionOpenPageModel.self)
|
||||||
ModelRegistry.register(ActionOpenUrlModel.self)
|
ModelRegistry.register(handler: ActionOpenUrlHandler.self, for: ActionOpenUrlModel.self)
|
||||||
ModelRegistry.register(ActionCallModel.self)
|
ModelRegistry.register(ActionCallModel.self)
|
||||||
ModelRegistry.register(ActionBackModel.self)
|
ModelRegistry.register(ActionBackModel.self)
|
||||||
ModelRegistry.register(ActionShareModel.self)
|
ModelRegistry.register(ActionShareModel.self)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user