diff --git a/Package.swift b/Package.swift index 8a11bcdc..63305190 100644 --- a/Package.swift +++ b/Package.swift @@ -56,7 +56,7 @@ let package = Package( // MARK: - UIKit .target(name: "TIUIKitCore", dependencies: ["TISwiftUtils"], path: "TIUIKitCore/Sources"), .target(name: "TIUIElements", dependencies: ["TIUIKitCore", "TISwiftUtils"], path: "TIUIElements/Sources"), - .target(name: "TIWebView", dependencies: ["TIUIKitCore", "TISwiftUtils", "TILogging"], path: "TIWebView/Sources"), + .target(name: "TIWebView", dependencies: ["TIUIKitCore", "TISwiftUtils"], path: "TIWebView/Sources"), // MARK: - SwiftUI .target(name: "TISwiftUICore", dependencies: ["TIUIKitCore", "TISwiftUtils"], path: "TISwiftUICore/Sources"), diff --git a/TIWebView/Sources/ErrorHandler/BaseWebViewErrorHandler.swift b/TIWebView/Sources/ErrorHandler/BaseWebViewErrorHandler.swift index 696b860d..cbe68ac9 100644 --- a/TIWebView/Sources/ErrorHandler/BaseWebViewErrorHandler.swift +++ b/TIWebView/Sources/ErrorHandler/BaseWebViewErrorHandler.swift @@ -20,15 +20,9 @@ // THE SOFTWARE. // -import TILogging - -open class BaseWebViewErrorHandler { +open class BaseWebViewErrorHandler: WebViewErrorHandler { public init() { } - - open func didRecievedError(_ error: WebViewError) { - // override in subviews - } } diff --git a/TIWebView/Sources/ErrorHandler/WebViewErrorModel.swift b/TIWebView/Sources/ErrorHandler/WebViewError/WebViewError.swift similarity index 91% rename from TIWebView/Sources/ErrorHandler/WebViewErrorModel.swift rename to TIWebView/Sources/ErrorHandler/WebViewError/WebViewError.swift index 9de11b09..1cc49cd1 100644 --- a/TIWebView/Sources/ErrorHandler/WebViewErrorModel.swift +++ b/TIWebView/Sources/ErrorHandler/WebViewError/WebViewError.swift @@ -22,7 +22,6 @@ import Foundation -public enum WebViewError: Error { - case standardError(URL?, Error) - case jsError(URL?, String) +public protocol WebViewError: Error { + var contentURL: URL? { get } } diff --git a/TIWebView/Sources/ErrorHandler/WebViewError/WebViewJSError.swift b/TIWebView/Sources/ErrorHandler/WebViewError/WebViewJSError.swift new file mode 100644 index 00000000..d30c673a --- /dev/null +++ b/TIWebView/Sources/ErrorHandler/WebViewError/WebViewJSError.swift @@ -0,0 +1,41 @@ +// +// Copyright (c) 2022 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation + +public struct WebViewJSError: WebViewError, Codable { + public let contentURL: URL? + public let name: String? + public let message: String? + public let stackTrace: String? + + public init(contentURL: URL?, + name: String?, + message: String?, + stackTrace: String?) { + + self.contentURL = contentURL + self.name = name + self.message = message + self.stackTrace = stackTrace + } +} diff --git a/TIWebView/Sources/ErrorHandler/WebViewError/WebViewLoadingError.swift b/TIWebView/Sources/ErrorHandler/WebViewError/WebViewLoadingError.swift new file mode 100644 index 00000000..5f8a10c9 --- /dev/null +++ b/TIWebView/Sources/ErrorHandler/WebViewError/WebViewLoadingError.swift @@ -0,0 +1,33 @@ +// +// Copyright (c) 2022 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation + +public struct WebViewLoadingError: WebViewError { + public let contentURL: URL? + public let innerError: Error + + public init(contentURL: URL?, innerError: Error) { + self.contentURL = contentURL + self.innerError = innerError + } +} diff --git a/TIWebView/Sources/ErrorHandler/WebViewErrorConstants.swift b/TIWebView/Sources/ErrorHandler/WebViewErrorConstants.swift index 5309a45e..07d266e0 100644 --- a/TIWebView/Sources/ErrorHandler/WebViewErrorConstants.swift +++ b/TIWebView/Sources/ErrorHandler/WebViewErrorConstants.swift @@ -25,7 +25,19 @@ public enum WebViewErrorConstants { "error" } - static var errorPropertyName: String { + static var errorMessage: String { "message" } + + static var errorName: String { + "name" + } + + static var errorUrl: String { + "url" + } + + static var errorStack: String { + "stack" + } } diff --git a/TIWebView/Sources/ErrorHandler/WebViewErrorHandler.swift b/TIWebView/Sources/ErrorHandler/WebViewErrorHandler.swift new file mode 100644 index 00000000..97ace4df --- /dev/null +++ b/TIWebView/Sources/ErrorHandler/WebViewErrorHandler.swift @@ -0,0 +1,31 @@ +// +// Copyright (c) 2022 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +public protocol WebViewErrorHandler { + func didRecievedError(_ error: WebViewError) +} + +public extension WebViewErrorHandler { + func didRecievedError(_ error: WebViewError) { + // override in subclasses + } +} diff --git a/TIWebView/Sources/NavigationHandler/BaseWebViewNavigator.swift b/TIWebView/Sources/NavigationHandler/BaseWebViewNavigator.swift index 154763b0..57095021 100644 --- a/TIWebView/Sources/NavigationHandler/BaseWebViewNavigator.swift +++ b/TIWebView/Sources/NavigationHandler/BaseWebViewNavigator.swift @@ -20,12 +20,9 @@ // THE SOFTWARE. // -import Foundation -import enum WebKit.WKNavigationActionPolicy +open class BaseWebViewNavigator: WebViewNavigator { -open class BaseWebViewNavigator { - - public let navigationMap: [NavigationPolicy] + public var navigationMap: [NavigationPolicy] public init(navigationMap: [NavigationPolicy]) { self.navigationMap = navigationMap @@ -34,13 +31,4 @@ open class BaseWebViewNavigator { public convenience init() { self.init(navigationMap: []) } - - open func shouldNavigate(toUrl url: URL) -> WKNavigationActionPolicy { - guard !navigationMap.isEmpty else { - return .cancel - } - - let allowPolicy = navigationMap.filter { $0.policy(for: url) == .allow } - return allowPolicy.isEmpty ? .cancel : .allow - } } diff --git a/TIWebView/Sources/NavigationHandler/Helpers/URL+Validation.swift b/TIWebView/Sources/NavigationHandler/Helpers/URL+Validation.swift index 844160ce..bcbe76ca 100644 --- a/TIWebView/Sources/NavigationHandler/Helpers/URL+Validation.swift +++ b/TIWebView/Sources/NavigationHandler/Helpers/URL+Validation.swift @@ -23,9 +23,8 @@ import Foundation extension URL { - func validate(with regex: NSRegularExpression) -> Bool { + func matches(_ regex: NSRegularExpression) -> Bool { let range = NSRange(location: 0, length: absoluteString.utf16.count) - return regex.firstMatch(in: absoluteString, range: range) != nil } @@ -38,7 +37,10 @@ extension URL { return absoluteString == path case let .query(query): - return (self.query ?? "").contains(query) + if let urlQuery = self.query { + return urlQuery.contains(query) + } + return false } } } diff --git a/TIWebView/Sources/NavigationHandler/NavigationPolicy/AnyNavigationPolicy.swift b/TIWebView/Sources/NavigationHandler/NavigationPolicy/AlwaysAllowNavigationPolicy.swift similarity index 95% rename from TIWebView/Sources/NavigationHandler/NavigationPolicy/AnyNavigationPolicy.swift rename to TIWebView/Sources/NavigationHandler/NavigationPolicy/AlwaysAllowNavigationPolicy.swift index 4d57c7f8..4916580b 100644 --- a/TIWebView/Sources/NavigationHandler/NavigationPolicy/AnyNavigationPolicy.swift +++ b/TIWebView/Sources/NavigationHandler/NavigationPolicy/AlwaysAllowNavigationPolicy.swift @@ -23,7 +23,7 @@ import Foundation import enum WebKit.WKNavigationActionPolicy -open class AnyNavigationPolicy: NavigationPolicy { +open class AlwaysAllowNavigationPolicy: NavigationPolicy { public init() { diff --git a/TIWebView/Sources/NavigationHandler/NavigationPolicy/RegexNavigationPolicy.swift b/TIWebView/Sources/NavigationHandler/NavigationPolicy/RegexNavigationPolicy.swift index 4c51c362..40d9a8c7 100644 --- a/TIWebView/Sources/NavigationHandler/NavigationPolicy/RegexNavigationPolicy.swift +++ b/TIWebView/Sources/NavigationHandler/NavigationPolicy/RegexNavigationPolicy.swift @@ -23,7 +23,7 @@ import Foundation import enum WebKit.WKNavigationActionPolicy -open class RegexNavigationPolicy: AnyNavigationPolicy { +open class RegexNavigationPolicy: AlwaysAllowNavigationPolicy { public var regex: NSRegularExpression @@ -46,6 +46,6 @@ open class RegexNavigationPolicy: AnyNavigationPolicy { // MARK: - NavigationPolicy open override func policy(for url: URL) -> WKNavigationActionPolicy { - url.validate(with: regex) ? .allow : .cancel + url.matches(regex) ? .allow : .cancel } } diff --git a/TIWebView/Sources/NavigationHandler/NavigationPolicy/URLComponentsNavigationPolicy.swift b/TIWebView/Sources/NavigationHandler/NavigationPolicy/URLComponentsNavigationPolicy.swift index 4a207ff4..568ddb11 100644 --- a/TIWebView/Sources/NavigationHandler/NavigationPolicy/URLComponentsNavigationPolicy.swift +++ b/TIWebView/Sources/NavigationHandler/NavigationPolicy/URLComponentsNavigationPolicy.swift @@ -24,7 +24,7 @@ import Foundation import enum WebKit.WKNavigationActionPolicy /// Compares URL with combination of URL components. -open class URLComponentsNavigationPolicy: AnyNavigationPolicy { +open class URLComponentsNavigationPolicy: AlwaysAllowNavigationPolicy { public var components: [URLComponent] diff --git a/TIWebView/Sources/NavigationHandler/WebViewNavigator.swift b/TIWebView/Sources/NavigationHandler/WebViewNavigator.swift new file mode 100644 index 00000000..303f7782 --- /dev/null +++ b/TIWebView/Sources/NavigationHandler/WebViewNavigator.swift @@ -0,0 +1,41 @@ +// +// Copyright (c) 2022 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import enum WebKit.WKNavigationActionPolicy + +public protocol WebViewNavigator { + var navigationMap: [NavigationPolicy] { get set } + + func shouldNavigate(to url: URL) -> WKNavigationActionPolicy +} + +public extension WebViewNavigator { + func shouldNavigate(to url: URL) -> WKNavigationActionPolicy { + guard !navigationMap.isEmpty else { + return .cancel + } + + let allowPolicy = navigationMap.filter { $0.policy(for: url) == .allow } + return allowPolicy.isEmpty ? .cancel : .allow + } +} diff --git a/TIWebView/Sources/StateDelegate/BaseWebViewStateHandler.swift b/TIWebView/Sources/StateDelegate/BaseWebViewStateHandler.swift index 2c661817..6cd66fae 100644 --- a/TIWebView/Sources/StateDelegate/BaseWebViewStateHandler.swift +++ b/TIWebView/Sources/StateDelegate/BaseWebViewStateHandler.swift @@ -36,16 +36,16 @@ open class BaseWebViewStateHandler: NSObject, WebViewStateHandler { return decisionHandler(.cancel) } - let decision = viewModel?.shouldNavigate(toUrl: url) ?? .cancel + let decision = viewModel?.shouldNavigate(to: url) ?? .cancel decisionHandler(decision) } open func webView(_ webView: WKWebView, didCommit navigation: WKNavigation?) { - // override in subviews + // override in subclasses } open func webView(_ webView: WKWebView, didFinish navigation: WKNavigation?) { - viewModel?.makeUrlInjection(forWebView: webView) + viewModel?.makeUrlInjection(into: webView) } open func webView(_ webView: WKWebView, diff --git a/TIWebView/Sources/URLInjector/BaseWebViewUrlInjector.swift b/TIWebView/Sources/URLInjector/BaseWebViewUrlInjector.swift index 097fb171..2429a2d7 100644 --- a/TIWebView/Sources/URLInjector/BaseWebViewUrlInjector.swift +++ b/TIWebView/Sources/URLInjector/BaseWebViewUrlInjector.swift @@ -23,9 +23,7 @@ import Foundation import class WebKit.WKWebView -open class BaseWebViewUrlInjector { - - public typealias URLInjection = [WebViewUrlComparator: [WebViewUrlInjection]] +open class BaseWebViewUrlInjector: WebViewUrlInjector { public var injection: URLInjection @@ -36,57 +34,4 @@ open class BaseWebViewUrlInjector { public convenience init() { self.init(injection: [:]) } - - // MARK: - Open methods - - open func inject(on webView: WKWebView) { - guard !injection.isEmpty, let url = webView.url else { - return - } - - injection.forEach { (comparator, injections) in - guard url.compare(by: comparator) else { - return - } - - injections.forEach { evaluteInjection(onWebView: webView, injection: $0) } - } - } - - // MARK: - Private methods - - private func evaluteInjection(onWebView webView: WKWebView, injection: WebViewUrlInjection) { - let jsScript = makeJsScript(fromInjection: injection) - - guard !jsScript.isEmpty else { - return - } - - webView.evaluateJavaScript(jsScript, completionHandler: nil) - } - - private func makeJsScript(fromInjection injection: WebViewUrlInjection) -> String { - switch injection { - case let .css(css): - return cssJsScript(css: css) - - case let .cssForFile(url): - let css = try? String(contentsOf: url) - .components(separatedBy: .newlines) - .joined() - - return cssJsScript(css: css ?? "") - - case let .javaScript(script): - return script - } - } - - private func cssJsScript(css: String) -> String { - """ - var style = document.createElement('style'); - style.innerHTML = '\(css)'; - document.head.appendChild(style); - """ - } } diff --git a/TIWebView/Sources/URLInjector/Helpers/URL+Comparator.swift b/TIWebView/Sources/URLInjector/Helpers/URL+Comparator.swift index e0968ca9..6c32c718 100644 --- a/TIWebView/Sources/URLInjector/Helpers/URL+Comparator.swift +++ b/TIWebView/Sources/URLInjector/Helpers/URL+Comparator.swift @@ -37,11 +37,8 @@ public extension URL { case let .query(query): return compare(by: .query(query)) - case let .regex(stringRegex): - guard let regex = try? NSRegularExpression(pattern: stringRegex) else { - return false - } - return validate(with: regex) + case let .regex(nsRegex): + return matches(nsRegex) } } } diff --git a/TIWebView/Sources/URLInjector/WebViewUrlComparator.swift b/TIWebView/Sources/URLInjector/WebViewUrlComparator.swift index 192c04f8..39545913 100644 --- a/TIWebView/Sources/URLInjector/WebViewUrlComparator.swift +++ b/TIWebView/Sources/URLInjector/WebViewUrlComparator.swift @@ -20,10 +20,12 @@ // THE SOFTWARE. // +import Foundation + public enum WebViewUrlComparator: Hashable { case any case absolutePath(String) case host(String) case query(String) - case regex(String) + case regex(NSRegularExpression) } diff --git a/TIWebView/Sources/URLInjector/WebViewUrlInjector.swift b/TIWebView/Sources/URLInjector/WebViewUrlInjector.swift new file mode 100644 index 00000000..89409e49 --- /dev/null +++ b/TIWebView/Sources/URLInjector/WebViewUrlInjector.swift @@ -0,0 +1,86 @@ +// +// Copyright (c) 2022 Touch Instinct +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the Software), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +import Foundation +import class WebKit.WKWebView + +public typealias URLInjection = [WebViewUrlComparator: [WebViewUrlInjection]] + +public protocol WebViewUrlInjector { + var injection: URLInjection { get set } + + func inject(into webView: WKWebView) +} + +public extension WebViewUrlInjector { + + func inject(into webView: WKWebView) { + guard !injection.isEmpty, let url = webView.url else { + return + } + + injection.forEach { (comparator, injections) in + guard url.compare(by: comparator) else { + return + } + + injections.forEach { evaluteInjection(onWebView: webView, injection: $0) } + } + } + + // MARK: - Helper methods + + private func evaluteInjection(onWebView webView: WKWebView, injection: WebViewUrlInjection) { + let jsScript = makeJsScript(fromInjection: injection) + + guard !jsScript.isEmpty else { + return + } + + webView.evaluateJavaScript(jsScript, completionHandler: nil) + } + + private func makeJsScript(fromInjection injection: WebViewUrlInjection) -> String { + switch injection { + case let .css(css): + return cssJsScript(css: css) + + case let .cssForFile(url): + let css = try? String(contentsOf: url) + .components(separatedBy: .newlines) + .joined() + + return cssJsScript(css: css ?? "") + + case let .javaScript(script): + return script + } + } + + private func cssJsScript(css: String) -> String { + """ + var style = document.createElement('style'); + style.innerHTML = '\(css)'; + document.head.appendChild(style); + """ + } +} diff --git a/TIWebView/Sources/Views/ViewModels/DefaultWebViewModel.swift b/TIWebView/Sources/Views/ViewModels/DefaultWebViewModel.swift index 4d62c64a..2883611a 100644 --- a/TIWebView/Sources/Views/ViewModels/DefaultWebViewModel.swift +++ b/TIWebView/Sources/Views/ViewModels/DefaultWebViewModel.swift @@ -24,15 +24,15 @@ import WebKit open class DefaultWebViewModel: NSObject, WebViewModel { - public var injector: BaseWebViewUrlInjector - public var navigator: BaseWebViewNavigator - public var errorHandler: BaseWebViewErrorHandler + public var injector: WebViewUrlInjector + public var navigator: WebViewNavigator + public var errorHandler: WebViewErrorHandler // MARK: - Init - public init(injector: BaseWebViewUrlInjector = .init(), - navigator: BaseWebViewNavigator = .init(), - errorHandler: BaseWebViewErrorHandler = .init()) { + public init(injector: WebViewUrlInjector = BaseWebViewUrlInjector(), + navigator: WebViewNavigator = BaseWebViewNavigator(), + errorHandler: WebViewErrorHandler = BaseWebViewErrorHandler()) { self.injector = injector self.navigator = navigator @@ -56,7 +56,9 @@ open class DefaultWebViewModel: NSObject, WebViewModel { private func parseError(_ message: WKScriptMessage) -> WebViewError { let body = message.body as? [String: Any] - let error = body?[WebViewErrorConstants.errorPropertyName] as? String - return .jsError(message.webView?.url, error ?? "") + return WebViewJSError(contentURL: body?[WebViewErrorConstants.errorUrl] as? URL, + name: body?[WebViewErrorConstants.errorName] as? String, + message: body?[WebViewErrorConstants.errorMessage] as? String, + stackTrace: body?[WebViewErrorConstants.errorStack] as? String) } } diff --git a/TIWebView/Sources/Views/ViewModels/WebViewModel.swift b/TIWebView/Sources/Views/ViewModels/WebViewModel.swift index 5250bc69..7894c78b 100644 --- a/TIWebView/Sources/Views/ViewModels/WebViewModel.swift +++ b/TIWebView/Sources/Views/ViewModels/WebViewModel.swift @@ -23,26 +23,27 @@ import WebKit public protocol WebViewModel: WKScriptMessageHandler { - var injector: BaseWebViewUrlInjector { get } - var navigator: BaseWebViewNavigator { get } - var errorHandler: BaseWebViewErrorHandler { get } + var injector: WebViewUrlInjector { get } + var navigator: WebViewNavigator { get } + var errorHandler: WebViewErrorHandler { get } - func makeUrlInjection(forWebView webView: WKWebView) - func shouldNavigate(toUrl url: URL) -> WKNavigationActionPolicy + func makeUrlInjection(into webView: WKWebView) + func shouldNavigate(to url: URL) -> WKNavigationActionPolicy func handleError(_ error: Error, url: URL?) } public extension WebViewModel { - func makeUrlInjection(forWebView webView: WKWebView) { - injector.inject(on: webView) + func makeUrlInjection(into webView: WKWebView) { + injector.inject(into: webView) } - func shouldNavigate(toUrl url: URL) -> WKNavigationActionPolicy { - navigator.shouldNavigate(toUrl: url) + func shouldNavigate(to url: URL) -> WKNavigationActionPolicy { + navigator.shouldNavigate(to: url) } func handleError(_ error: Error, url: URL?) { - errorHandler.didRecievedError(.standardError(url, error)) + let errorModel = WebViewLoadingError(contentURL: url, innerError: error) + errorHandler.didRecievedError(errorModel) } }