parent
d46cc50a33
commit
429b6a699c
|
|
@ -1,8 +1,8 @@
|
|||
PODS:
|
||||
- AppSwizzle (1.2)
|
||||
- ReCaptcha/Core (1.0.0):
|
||||
- ReCaptcha/Core (1.0.1):
|
||||
- Result (~> 3.0)
|
||||
- ReCaptcha/RxSwift (1.0.0):
|
||||
- ReCaptcha/RxSwift (1.0.1):
|
||||
- ReCaptcha/Core
|
||||
- RxSwift (~> 4.0)
|
||||
- Result (3.2.4)
|
||||
|
|
@ -31,7 +31,7 @@ CHECKOUT OPTIONS:
|
|||
|
||||
SPEC CHECKSUMS:
|
||||
AppSwizzle: bbd3782652fc426ce59c045a92ec61d36f261984
|
||||
ReCaptcha: ea35d3bdbb2098eb3c89d1cf3b5cdbdd4d77f4b8
|
||||
ReCaptcha: f281cd074be9b282f528c6dda9337476f13bd776
|
||||
Result: d2d07204ce72856f1fd9130bbe42c35a7b0fea10
|
||||
RxCocoa: d62846ca96495d862fa4c59ea7d87e5031d7340e
|
||||
RxSwift: fd680d75283beb5e2559486f3c0ff852f0d35334
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
BD850CB2DF4C9C94FC51226C /* Pods_ReCaptcha_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 62BEEA62161F672468CCFD64 /* Pods_ReCaptcha_Example.framework */; };
|
||||
D091B6E053FD250B4757E34C /* Pods_ReCaptcha_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A28DC340FF0BC1627B3F /* Pods_ReCaptcha_Tests.framework */; };
|
||||
F206BAD51F8D3FEB00A25807 /* Cartfile in Resources */ = {isa = PBXBuildFile; fileRef = F206BAD41F8D3FEB00A25807 /* Cartfile */; };
|
||||
F231B3971FEC325A00F82943 /* DispatchQueue__Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F231B3961FEC325A00F82943 /* DispatchQueue__Tests.swift */; };
|
||||
F288E9451F9537760018688D /* ReCaptchaError+Equatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F288E9441F9537760018688D /* ReCaptchaError+Equatable.swift */; };
|
||||
F2E2685E1F7AEE3400CD876D /* ReCaptcha__Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2E2685D1F7AEE3400CD876D /* ReCaptcha__Tests.swift */; };
|
||||
F2ECCF8A1E9FCEFE0097B199 /* ReCaptchaDecoder__Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2ECCF891E9FCEFE0097B199 /* ReCaptchaDecoder__Tests.swift */; };
|
||||
|
|
@ -54,6 +55,7 @@
|
|||
C8537003ECC47117AF54DCA9 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; };
|
||||
F206BAD41F8D3FEB00A25807 /* Cartfile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Cartfile; path = ../Cartfile; sourceTree = "<group>"; };
|
||||
F21901D91F98D62F00D8E2C9 /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = CHANGELOG.md; path = ../CHANGELOG.md; sourceTree = "<group>"; };
|
||||
F231B3961FEC325A00F82943 /* DispatchQueue__Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DispatchQueue__Tests.swift; sourceTree = "<group>"; };
|
||||
F288E9441F9537760018688D /* ReCaptchaError+Equatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ReCaptchaError+Equatable.swift"; sourceTree = "<group>"; };
|
||||
F2E2685D1F7AEE3400CD876D /* ReCaptcha__Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReCaptcha__Tests.swift; sourceTree = "<group>"; };
|
||||
F2ECCF761E9FC47B0097B199 /* ReCaptcha_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ReCaptcha_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
|
|
@ -170,6 +172,7 @@
|
|||
F2ECCF891E9FCEFE0097B199 /* ReCaptchaDecoder__Tests.swift */,
|
||||
F2ECCF8D1E9FE68C0097B199 /* ReCaptchaWebViewManager__Tests.swift */,
|
||||
F2E2685D1F7AEE3400CD876D /* ReCaptcha__Tests.swift */,
|
||||
F231B3961FEC325A00F82943 /* DispatchQueue__Tests.swift */,
|
||||
);
|
||||
path = Core;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -214,6 +217,7 @@
|
|||
607FACCE1AFB9204008FA782 /* Resources */,
|
||||
8F03FFB3F5C55E873C23C682 /* [CP] Embed Pods Frameworks */,
|
||||
ED1C0E07490C9C4B4A401061 /* [CP] Copy Pods Resources */,
|
||||
F231B3981FEC3B7F00F82943 /* SwiftLint */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
|
@ -418,6 +422,20 @@
|
|||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ReCaptcha_Example/Pods-ReCaptcha_Example-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
F231B3981FEC3B7F00F82943 /* SwiftLint */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = SwiftLint;
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/SwiftLint/swiftlint\" --path \"${PROJECT_DIR}/..\"";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
|
|
@ -437,6 +455,7 @@
|
|||
F2ECCF961EA00A5B0097B199 /* ReCaptchaWebViewManager+Helpers.swift in Sources */,
|
||||
F2ECCF8E1E9FE68C0097B199 /* ReCaptchaWebViewManager__Tests.swift in Sources */,
|
||||
F2ECCF981EA011370097B199 /* Result+Helpers.swift in Sources */,
|
||||
F231B3971FEC325A00F82943 /* DispatchQueue__Tests.swift in Sources */,
|
||||
F2E2685E1F7AEE3400CD876D /* ReCaptcha__Tests.swift in Sources */,
|
||||
F2ECCF931EA009360097B199 /* ReCaptcha+Rx__Tests.swift in Sources */,
|
||||
F288E9451F9537760018688D /* ReCaptchaError+Equatable.swift in Sources */,
|
||||
|
|
@ -620,7 +639,7 @@
|
|||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.flaviocaetano.ReCaptcha-Tests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG UNIT_TESTS";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ReCaptcha_Example.app/ReCaptcha_Example";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
//
|
||||
// DispatchQueue__Tests.swift
|
||||
// ReCaptcha
|
||||
//
|
||||
// Created by Flávio Caetano on 21/12/17.
|
||||
// Copyright © 2017 ReCaptcha. All rights reserved.
|
||||
//
|
||||
|
||||
@testable import ReCaptcha
|
||||
import XCTest
|
||||
|
||||
class DispatchQueue__Tests: XCTestCase {
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
func test__Throttle() {
|
||||
// Execute closure called once
|
||||
let exp0 = expectation(description: "did call single closure")
|
||||
|
||||
DispatchQueue.main.throttle(deadline: .now() + 0.1) {
|
||||
exp0.fulfill()
|
||||
}
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
|
||||
// Does not execute first closure
|
||||
let exp1 = expectation(description: "")
|
||||
DispatchQueue.main.throttle(deadline: .now() + 0.1) {
|
||||
XCTFail("Shouldn't be called")
|
||||
}
|
||||
|
||||
DispatchQueue.main.throttle(deadline: .now() + 0.1) {
|
||||
exp1.fulfill()
|
||||
}
|
||||
|
||||
waitForExpectations(timeout: 1)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +1,20 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<script type="text/javascript">
|
||||
var key = "${apiKey}";
|
||||
var execute = function() {
|
||||
window.webkit.messageHandlers.recaptcha.postMessage(${message});
|
||||
}
|
||||
var endpoint = "${endpoint}";
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<span id="submit" style="visibility: hidden;"></span>
|
||||
</body>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<script type="text/javascript">
|
||||
var key = "${apiKey}";
|
||||
var endpoint = "${endpoint}";
|
||||
|
||||
var execute = function() {
|
||||
window.webkit.messageHandlers.recaptcha.postMessage(${message});
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
window.webkit.messageHandlers.recaptcha.postMessage({action: "didLoad"});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<span id="submit" style="visibility: hidden;"></span>
|
||||
</body>
|
||||
</html>
|
||||
cartha
|
||||
|
|
|
|||
2
Gemfile
2
Gemfile
|
|
@ -1,4 +1,4 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gem 'fastlane', '~> 2.62.1'
|
||||
gem 'fastlane', '~> 2.69.2'
|
||||
gem 'cocoapods', '~> 1.3.1'
|
||||
|
|
|
|||
18
Gemfile.lock
18
Gemfile.lock
|
|
@ -64,7 +64,7 @@ GEM
|
|||
faraday_middleware (0.12.2)
|
||||
faraday (>= 0.7.4, < 1.0)
|
||||
fastimage (2.1.0)
|
||||
fastlane (2.62.1)
|
||||
fastlane (2.69.2)
|
||||
CFPropertyList (>= 2.3, < 3.0.0)
|
||||
addressable (>= 2.3, < 3.0.0)
|
||||
babosa (>= 1.0.2, < 2.0.0)
|
||||
|
|
@ -92,9 +92,9 @@ GEM
|
|||
slack-notifier (>= 1.3, < 2.0.0)
|
||||
terminal-notifier (>= 1.6.2, < 2.0.0)
|
||||
terminal-table (>= 1.4.5, < 2.0.0)
|
||||
tty-screen (~> 0.5.0)
|
||||
tty-screen (~> 0.6.3)
|
||||
word_wrap (~> 1.0.0)
|
||||
xcodeproj (>= 1.5.0, < 2.0.0)
|
||||
xcodeproj (>= 1.5.2, < 2.0.0)
|
||||
xcpretty (>= 0.2.4, < 1.0.0)
|
||||
xcpretty-travis-formatter (>= 0.0.3)
|
||||
fourflusher (2.0.1)
|
||||
|
|
@ -107,7 +107,7 @@ GEM
|
|||
mime-types (~> 3.0)
|
||||
representable (~> 3.0)
|
||||
retriable (>= 2.0, < 4.0)
|
||||
googleauth (0.6.1)
|
||||
googleauth (0.6.2)
|
||||
faraday (~> 0.12)
|
||||
jwt (>= 1.4, < 3.0)
|
||||
logging (~> 2.0)
|
||||
|
|
@ -115,7 +115,7 @@ GEM
|
|||
multi_json (~> 1.11)
|
||||
os (~> 0.9)
|
||||
signet (~> 0.7)
|
||||
highline (1.7.8)
|
||||
highline (1.7.10)
|
||||
http-cookie (1.0.3)
|
||||
domain_name (~> 0.5)
|
||||
httpclient (2.8.3)
|
||||
|
|
@ -141,7 +141,7 @@ GEM
|
|||
nap (1.1.0)
|
||||
netrc (0.11.0)
|
||||
os (0.9.6)
|
||||
plist (3.3.0)
|
||||
plist (3.4.0)
|
||||
public_suffix (2.0.5)
|
||||
representable (3.0.4)
|
||||
declarative (< 0.1.0)
|
||||
|
|
@ -162,7 +162,7 @@ GEM
|
|||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
thread_safe (0.3.6)
|
||||
tty-screen (0.5.1)
|
||||
tty-screen (0.6.3)
|
||||
tzinfo (1.2.4)
|
||||
thread_safe (~> 0.1)
|
||||
uber (0.1.0)
|
||||
|
|
@ -186,7 +186,7 @@ PLATFORMS
|
|||
|
||||
DEPENDENCIES
|
||||
cocoapods (~> 1.3.1)
|
||||
fastlane (~> 2.62.1)
|
||||
fastlane (~> 2.69.2)
|
||||
|
||||
BUNDLED WITH
|
||||
1.15.4
|
||||
1.16.0
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
F206BAD31F8D3E7600A25807 /* Result.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F206BAD21F8D3E7600A25807 /* Result.framework */; };
|
||||
F206BB1D1F8D4DBC00A25807 /* ReCaptcha_RxSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = F206BB1B1F8D4DBC00A25807 /* ReCaptcha_RxSwift.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
F206BB221F8D4DDF00A25807 /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F206BB121F8D4D1400A25807 /* RxSwift.framework */; };
|
||||
F231B39A1FEC51C800F82943 /* DispatchQueue+Throttle.swift in Sources */ = {isa = PBXBuildFile; fileRef = F231B3991FEC51C800F82943 /* DispatchQueue+Throttle.swift */; };
|
||||
F24EA1E11F9683FB001DEC17 /* ReCaptcha+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = F24EA1DD1F9683F5001DEC17 /* ReCaptcha+Rx.swift */; };
|
||||
F24EA1E21F968403001DEC17 /* ReCaptchaDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = F24EA1D81F9683F5001DEC17 /* ReCaptchaDecoder.swift */; };
|
||||
F24EA1E31F968403001DEC17 /* ReCaptchaWebViewManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F24EA1D91F9683F5001DEC17 /* ReCaptchaWebViewManager.swift */; };
|
||||
|
|
@ -41,6 +42,7 @@
|
|||
F206BB191F8D4DBC00A25807 /* ReCaptcha_RxSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ReCaptcha_RxSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F206BB1B1F8D4DBC00A25807 /* ReCaptcha_RxSwift.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReCaptcha_RxSwift.h; sourceTree = "<group>"; };
|
||||
F206BB1C1F8D4DBC00A25807 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
F231B3991FEC51C800F82943 /* DispatchQueue+Throttle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DispatchQueue+Throttle.swift"; sourceTree = "<group>"; };
|
||||
F24EA1D81F9683F5001DEC17 /* ReCaptchaDecoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReCaptchaDecoder.swift; sourceTree = "<group>"; };
|
||||
F24EA1D91F9683F5001DEC17 /* ReCaptchaWebViewManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReCaptchaWebViewManager.swift; sourceTree = "<group>"; };
|
||||
F24EA1DA1F9683F5001DEC17 /* String+Dict.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Dict.swift"; sourceTree = "<group>"; };
|
||||
|
|
@ -145,6 +147,7 @@
|
|||
F24EA1D91F9683F5001DEC17 /* ReCaptchaWebViewManager.swift */,
|
||||
F24EA1DA1F9683F5001DEC17 /* String+Dict.swift */,
|
||||
F24EA1DB1F9683F5001DEC17 /* ReCaptchaError.swift */,
|
||||
F231B3991FEC51C800F82943 /* DispatchQueue+Throttle.swift */,
|
||||
F24EA1DC1F9683F5001DEC17 /* Rx */,
|
||||
F24EA1DE1F9683F5001DEC17 /* ReCaptcha.swift */,
|
||||
);
|
||||
|
|
@ -291,6 +294,7 @@
|
|||
F24EA1E61F968403001DEC17 /* ReCaptcha.swift in Sources */,
|
||||
F24EA1E31F968403001DEC17 /* ReCaptchaWebViewManager.swift in Sources */,
|
||||
F24EA1E41F968403001DEC17 /* String+Dict.swift in Sources */,
|
||||
F231B39A1FEC51C800F82943 /* DispatchQueue+Throttle.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,7 +13,11 @@
|
|||
|
||||
var execute = function() {
|
||||
// Removes ReCaptcha dismissal when clicking outside div area
|
||||
document.getElementsByTagName("div")[4].outerHTML = ""
|
||||
try {
|
||||
document.getElementsByTagName("div")[4].outerHTML = ""
|
||||
}
|
||||
catch(e) {
|
||||
}
|
||||
|
||||
// Listens to changes on the div element that presents the ReCaptcha challenge
|
||||
observeDOM(document.getElementsByTagName("div")[3], function() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
//
|
||||
// DispatchQueue+Throttle.swift
|
||||
// ReCaptcha
|
||||
//
|
||||
// Created by Flávio Caetano on 21/12/17.
|
||||
// Copyright © 2017 ReCaptcha. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
private var workItem: DispatchWorkItem?
|
||||
|
||||
extension DispatchQueue {
|
||||
/**
|
||||
- parameters:
|
||||
- deadline: The timespan to delay a closure execution
|
||||
- action: The closure to be executed
|
||||
|
||||
Delays a closure execution and ensures no other executions are made during deadline
|
||||
*/
|
||||
func throttle(deadline: DispatchTime, action: @escaping () -> Void) {
|
||||
let worker = DispatchWorkItem {
|
||||
defer { workItem = nil }
|
||||
action()
|
||||
}
|
||||
|
||||
asyncAfter(deadline: deadline, execute: worker)
|
||||
|
||||
workItem?.cancel()
|
||||
workItem = worker
|
||||
}
|
||||
}
|
||||
|
|
@ -24,6 +24,9 @@ internal class ReCaptchaDecoder: NSObject {
|
|||
|
||||
/// Any errors
|
||||
case error(ReCaptchaError)
|
||||
|
||||
/// Did finish loading resources
|
||||
case didLoad
|
||||
}
|
||||
|
||||
/// The closure that receives messages
|
||||
|
|
@ -84,8 +87,17 @@ fileprivate extension ReCaptchaDecoder.Result {
|
|||
return .token(token)
|
||||
}
|
||||
|
||||
if let action = response["action"] as? String, action == "showReCaptcha" {
|
||||
return .showReCaptcha
|
||||
if let action = response["action"] as? String {
|
||||
switch action {
|
||||
case "showReCaptcha":
|
||||
return .showReCaptcha
|
||||
|
||||
case "didLoad":
|
||||
return .didLoad
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return .error(.wrongMessageFormat)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ open class ReCaptchaWebViewManager {
|
|||
/// The parent manager
|
||||
private weak var manager: ReCaptchaWebViewManager?
|
||||
|
||||
/// The active requests' urls
|
||||
private var activeRequests = Set<String>(minimumCapacity: 0)
|
||||
|
||||
/// - parameter manager: The parent manager
|
||||
init(manager: ReCaptchaWebViewManager) {
|
||||
self.manager = manager
|
||||
|
|
@ -30,16 +33,55 @@ open class ReCaptchaWebViewManager {
|
|||
/**
|
||||
- parameters:
|
||||
- webView: The web view invoking the delegate method.
|
||||
- navigation: The navigation object that finished.
|
||||
|
||||
Called when the navigation is complete.
|
||||
*/
|
||||
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
||||
manager?.didFinishLoading = true
|
||||
- navigationAction: Descriptive information about the action triggering the navigation request.
|
||||
- decisionHandler: The decision handler to call to allow or cancel the navigation. The argument is one of
|
||||
the constants of the enumerated type WKNavigationActionPolicy.
|
||||
|
||||
if manager?.completion != nil {
|
||||
// User has requested for validation
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
|
||||
Decides whether to allow or cancel a navigation.
|
||||
*/
|
||||
func webView(
|
||||
_ webView: WKWebView,
|
||||
decidePolicyFor navigationAction: WKNavigationAction,
|
||||
decisionHandler: @escaping (WKNavigationActionPolicy
|
||||
) -> Void) {
|
||||
defer { decisionHandler(.allow) }
|
||||
|
||||
if let url = navigationAction.request.url, let host = url.host, let endpoint = manager?.endpoint,
|
||||
endpoint.range(of: host) != nil {
|
||||
activeRequests.insert(url.absoluteString)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
- parameters:
|
||||
- webView: The web view invoking the delegate method.
|
||||
- navigationResponse: Descriptive information about the navigation response.
|
||||
- decisionHandler: A block to be called when your app has decided whether to allow or cancel the navigation
|
||||
|
||||
Decides whether to allow or cancel a navigation after its response is known.
|
||||
*/
|
||||
func webView(
|
||||
_ webView: WKWebView,
|
||||
decidePolicyFor navigationResponse: WKNavigationResponse,
|
||||
decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void
|
||||
) {
|
||||
defer { decisionHandler(.allow) }
|
||||
guard let url = navigationResponse.response.url?.absoluteString,
|
||||
activeRequests.remove(url) != nil, activeRequests.isEmpty else {
|
||||
return
|
||||
}
|
||||
|
||||
execute()
|
||||
}
|
||||
|
||||
/// Flag the requests as finished and call ReCaptcha execution if necessary
|
||||
func execute() {
|
||||
DispatchQueue.main.throttle(deadline: .now() + 1) { [weak self] in
|
||||
// Did finish loading the ReCaptcha JS source
|
||||
self?.manager?.didFinishLoading = true
|
||||
|
||||
if self?.manager?.completion != nil {
|
||||
// User has requested for validation
|
||||
self?.manager?.execute()
|
||||
}
|
||||
}
|
||||
|
|
@ -65,6 +107,9 @@ open class ReCaptchaWebViewManager {
|
|||
/// The observer for `.UIWindowDidBecomeVisible`
|
||||
fileprivate var observer: NSObjectProtocol?
|
||||
|
||||
/// The endpoint url being used
|
||||
fileprivate var endpoint: String
|
||||
|
||||
/// The `webView` delegate implementation
|
||||
fileprivate lazy var webviewDelegate: WebViewDelegate = {
|
||||
WebViewDelegate(manager: self)
|
||||
|
|
@ -90,7 +135,8 @@ open class ReCaptchaWebViewManager {
|
|||
- endpoint: The JS API endpoint to be loaded onto the HTML file.
|
||||
*/
|
||||
init(html: String, apiKey: String, baseURL: URL, endpoint: String) {
|
||||
decoder = ReCaptchaDecoder { [weak self] result in
|
||||
self.endpoint = endpoint
|
||||
self.decoder = ReCaptchaDecoder { [weak self] result in
|
||||
self?.handle(result: result)
|
||||
}
|
||||
|
||||
|
|
@ -201,6 +247,10 @@ fileprivate extension ReCaptchaWebViewManager {
|
|||
|
||||
case .showReCaptcha:
|
||||
configureWebView?(webView)
|
||||
|
||||
case .didLoad:
|
||||
// For testing purposes
|
||||
webviewDelegate.execute()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue