parent
24ba434e6d
commit
11818ab473
|
|
@ -1,8 +1,8 @@
|
|||
PODS:
|
||||
- AppSwizzle (1.2)
|
||||
- ReCaptcha/Core (1.0.1):
|
||||
- ReCaptcha/Core (1.0.2):
|
||||
- Result (~> 3.0)
|
||||
- ReCaptcha/RxSwift (1.0.1):
|
||||
- ReCaptcha/RxSwift (1.0.2):
|
||||
- ReCaptcha/Core
|
||||
- RxSwift (~> 4.0)
|
||||
- Result (3.2.4)
|
||||
|
|
@ -31,7 +31,7 @@ CHECKOUT OPTIONS:
|
|||
|
||||
SPEC CHECKSUMS:
|
||||
AppSwizzle: bbd3782652fc426ce59c045a92ec61d36f261984
|
||||
ReCaptcha: f281cd074be9b282f528c6dda9337476f13bd776
|
||||
ReCaptcha: f1d10fd37e8f219c00521790aa9124ca12b65e16
|
||||
Result: d2d07204ce72856f1fd9130bbe42c35a7b0fea10
|
||||
RxCocoa: fd0862fd2df95fa55562ad28ffd2522c25eb4a85
|
||||
RxSwift: c6e3b1c7b325c7d121cd4327e9d98b7ed746b570
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ class ReCaptcha__Tests: XCTestCase {
|
|||
toAlterSelector: #selector(Bundle.failHTMLLoad(_:type:))
|
||||
)
|
||||
|
||||
|
||||
do {
|
||||
_ = try ReCaptcha()
|
||||
XCTFail("Should have failed")
|
||||
|
|
@ -57,16 +56,28 @@ class ReCaptcha__Tests: XCTestCase {
|
|||
}
|
||||
|
||||
// Ensures plist url if nil key
|
||||
let plistURL = URL(string: "bar")!
|
||||
let plistURL = URL(string: "https://bar")!
|
||||
let config1 = try? ReCaptcha.Config(apiKey: "", infoPlistKey: nil, baseURL: nil, infoPlistURL: plistURL)
|
||||
XCTAssertEqual(config1?.baseURL, plistURL)
|
||||
|
||||
// Ensures preference of given url over plist entry
|
||||
let url = URL(string: "foo")!
|
||||
let url = URL(string: "ftp://foo")!
|
||||
let config2 = try? ReCaptcha.Config(apiKey: "", infoPlistKey: nil, baseURL: url, infoPlistURL: plistURL)
|
||||
XCTAssertEqual(config2?.baseURL, url)
|
||||
}
|
||||
|
||||
func test__Base_URL_Without_Scheme() {
|
||||
// Ignores URL with scheme
|
||||
let goodURL = URL(string: "https://foo.bar")!
|
||||
let config0 = try? ReCaptcha.Config(apiKey: "", infoPlistKey: nil, baseURL: goodURL, infoPlistURL: nil)
|
||||
XCTAssertEqual(config0?.baseURL, goodURL)
|
||||
|
||||
// Fixes URL without scheme
|
||||
let badURL = URL(string: "foo")!
|
||||
let config = try? ReCaptcha.Config(apiKey: "", infoPlistKey: nil, baseURL: badURL, infoPlistURL: nil)
|
||||
XCTAssertEqual(config?.baseURL.absoluteString, "http://" + badURL.absoluteString)
|
||||
}
|
||||
|
||||
func test__API_Key() {
|
||||
// Ensures key failure when nil
|
||||
do {
|
||||
|
|
|
|||
2
Gemfile
2
Gemfile
|
|
@ -1,4 +1,4 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gem 'fastlane', '~> 2.75'
|
||||
gem 'cocoapods', '~> 1.3.1'
|
||||
gem 'cocoapods', '~> 1.4'
|
||||
|
|
|
|||
24
Gemfile.lock
24
Gemfile.lock
|
|
@ -11,30 +11,30 @@ GEM
|
|||
public_suffix (>= 2.0.2, < 4.0)
|
||||
babosa (1.0.2)
|
||||
claide (1.0.2)
|
||||
cocoapods (1.3.1)
|
||||
cocoapods (1.4.0)
|
||||
activesupport (>= 4.0.2, < 5)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
cocoapods-core (= 1.3.1)
|
||||
cocoapods-deintegrate (>= 1.0.1, < 2.0)
|
||||
cocoapods-core (= 1.4.0)
|
||||
cocoapods-deintegrate (>= 1.0.2, < 2.0)
|
||||
cocoapods-downloader (>= 1.1.3, < 2.0)
|
||||
cocoapods-plugins (>= 1.0.0, < 2.0)
|
||||
cocoapods-search (>= 1.0.0, < 2.0)
|
||||
cocoapods-stats (>= 1.0.0, < 2.0)
|
||||
cocoapods-trunk (>= 1.2.0, < 2.0)
|
||||
cocoapods-trunk (>= 1.3.0, < 2.0)
|
||||
cocoapods-try (>= 1.1.0, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
escape (~> 0.0.4)
|
||||
fourflusher (~> 2.0.1)
|
||||
gh_inspector (~> 1.0)
|
||||
molinillo (~> 0.5.7)
|
||||
molinillo (~> 0.6.4)
|
||||
nap (~> 1.0)
|
||||
ruby-macho (~> 1.1)
|
||||
xcodeproj (>= 1.5.1, < 2.0)
|
||||
cocoapods-core (1.3.1)
|
||||
xcodeproj (>= 1.5.4, < 2.0)
|
||||
cocoapods-core (1.4.0)
|
||||
activesupport (>= 4.0.2, < 6)
|
||||
fuzzy_match (~> 2.0.4)
|
||||
nap (~> 1.0)
|
||||
cocoapods-deintegrate (1.0.1)
|
||||
cocoapods-deintegrate (1.0.2)
|
||||
cocoapods-downloader (1.1.3)
|
||||
cocoapods-plugins (1.0.0)
|
||||
nap
|
||||
|
|
@ -120,7 +120,7 @@ GEM
|
|||
http-cookie (1.0.3)
|
||||
domain_name (~> 0.5)
|
||||
httpclient (2.8.3)
|
||||
i18n (0.9.0)
|
||||
i18n (0.9.1)
|
||||
concurrent-ruby (~> 1.0)
|
||||
json (2.1.0)
|
||||
jwt (2.1.0)
|
||||
|
|
@ -133,8 +133,8 @@ GEM
|
|||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2016.0521)
|
||||
mini_magick (4.5.1)
|
||||
minitest (5.10.3)
|
||||
molinillo (0.5.7)
|
||||
minitest (5.11.1)
|
||||
molinillo (0.6.4)
|
||||
multi_json (1.13.0)
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.0.0)
|
||||
|
|
@ -189,7 +189,7 @@ PLATFORMS
|
|||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
cocoapods (~> 1.3.1)
|
||||
cocoapods (~> 1.4)
|
||||
fastlane (~> 2.75)
|
||||
|
||||
BUNDLED WITH
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ when creating your [API Key](https://www.google.com/recaptcha/admin).
|
|||
## Installation
|
||||
|
||||
ReCaptcha is available through [CocoaPods](http://cocoapods.org) and [Carthage](https://github.com/Carthage/Carthage).
|
||||
To install it, simply add the following line to your depedencies file:
|
||||
To install it, simply add the following line to your dependencies file:
|
||||
|
||||
#### Cocoapods
|
||||
``` ruby
|
||||
|
|
@ -42,7 +42,7 @@ extension for the ReCaptcha framework.
|
|||
|
||||
## Usage
|
||||
|
||||
Simply add `ReCaptchaKey` and `ReCaptchaDomain` to your Info.plist and run:
|
||||
Simply add `ReCaptchaKey` and `ReCaptchaDomain` (with a protocol) to your Info.plist and run:
|
||||
|
||||
``` swift
|
||||
let recaptcha = try? ReCaptcha()
|
||||
|
|
|
|||
|
|
@ -8,10 +8,14 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
private var workItems = [AnyHashable: DispatchWorkItem]()
|
||||
private let nilContext = UUID()
|
||||
|
||||
/// Adds throttling to dispatch queues
|
||||
extension DispatchQueue {
|
||||
/// Stores a throttle DispatchWorkItem instance for a given context
|
||||
private static var workItems = [AnyHashable: DispatchWorkItem]()
|
||||
|
||||
/// An object representing a context if none is given
|
||||
private static let nilContext = UUID()
|
||||
|
||||
/**
|
||||
- parameters:
|
||||
- deadline: The timespan to delay a closure execution
|
||||
|
|
@ -22,13 +26,13 @@ extension DispatchQueue {
|
|||
*/
|
||||
func throttle(deadline: DispatchTime, context: AnyHashable = nilContext, action: @escaping () -> Void) {
|
||||
let worker = DispatchWorkItem {
|
||||
defer { workItems[context] = nil }
|
||||
defer { DispatchQueue.workItems.removeValue(forKey: context) }
|
||||
action()
|
||||
}
|
||||
|
||||
asyncAfter(deadline: deadline, execute: worker)
|
||||
|
||||
workItems[context]?.cancel()
|
||||
workItems[context] = worker
|
||||
DispatchQueue.workItems[context]?.cancel()
|
||||
DispatchQueue.workItems[context] = worker
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ open class ReCaptcha: ReCaptchaWebViewManager {
|
|||
}
|
||||
}
|
||||
|
||||
/** Internal data model for DI in unit tests
|
||||
/** Internal data model for CI in unit tests
|
||||
*/
|
||||
struct Config {
|
||||
/// The raw unformated HTML file content
|
||||
|
|
@ -93,7 +93,7 @@ open class ReCaptcha: ReCaptchaWebViewManager {
|
|||
|
||||
self.html = rawHTML
|
||||
self.apiKey = apiKey
|
||||
self.baseURL = domain
|
||||
self.baseURL = Config.fixSchemeIfNeeded(for: domain)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -128,3 +128,26 @@ open class ReCaptcha: ReCaptchaWebViewManager {
|
|||
super.init(html: config.html, apiKey: config.apiKey, baseURL: config.baseURL, endpoint: endpoint.url)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private Methods
|
||||
|
||||
private extension ReCaptcha.Config {
|
||||
/**
|
||||
- parameter url: The URL to be fixed
|
||||
- returns: An URL with scheme
|
||||
|
||||
If the given URL has no scheme, prepends `http://` to it and return the fixed URL.
|
||||
*/
|
||||
static func fixSchemeIfNeeded(for url: URL) -> URL {
|
||||
guard url.scheme?.isEmpty != false else {
|
||||
return url
|
||||
}
|
||||
|
||||
if let fixedURL = URL(string: "http://" + url.absoluteString) {
|
||||
debugPrint("[ReCaptcha] - Prepending 'http://' to url (\(url))")
|
||||
return fixedURL
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue