Initial code

This commit is contained in:
Flávio Caetano 2017-04-11 15:00:44 -03:00
parent d2224c599a
commit b7fd217d31
66 changed files with 4131 additions and 8 deletions

48
.gitignore vendored Normal file
View File

@ -0,0 +1,48 @@
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
## Build generated
build/
DerivedData
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
## Other
*.xccheckout
*.moved-aside
*.xcuserstate
*.orig
## Obj-C/Swift specific
*.hmap
*.ipa
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion
*.iml
## Directory-based project format:
.idea/
.DS_Store
## CocoaPods
#Pods/
html/highwinds_credentials.json
html/node_modules/
html/fb-*.html
html/ios-*.html
html/mp4-*.html
html/player-inject-*.js
.bitrise*

11
Example/Podfile Normal file
View File

@ -0,0 +1,11 @@
use_frameworks!
target 'ReCaptcha_Example' do
pod 'ReCaptcha', :path => '../'
target 'ReCaptcha_Tests' do
inherit! :search_paths
end
end

19
Example/Podfile.lock Normal file
View File

@ -0,0 +1,19 @@
PODS:
- ReCaptcha (0.1.0):
- Result (~> 3.0)
- Result (3.2.1)
DEPENDENCIES:
- ReCaptcha (from `../`)
EXTERNAL SOURCES:
ReCaptcha:
:path: "../"
SPEC CHECKSUMS:
ReCaptcha: d9912029dfd0988054ec6f1237098a19ef694fd0
Result: 2453a22e5c5b11c0c3a478736e82cd02f763b781
PODFILE CHECKSUM: 816c00f9db90d74940892ce0fa0bcc81d31a3270
COCOAPODS: 1.2.0.beta.3

View File

@ -0,0 +1,34 @@
{
"name": "ReCaptcha",
"version": "0.1.0",
"summary": "ReCaptcha for iOS",
"description": "Add Google invisible ReCaptcha to your app",
"homepage": "https://github.com/fjcaetano/ReCaptcha",
"license": {
"type": "MIT",
"file": "LICENSE"
},
"authors": {
"fjcaetano": "flavio@vieiracaetano.com"
},
"source": {
"git": "https://github.com/fjcaetano/ReCaptcha.git",
"tag": "0.1.0"
},
"social_media_url": "https://twitter.com/flavio_caetano",
"platforms": {
"ios": "8.0"
},
"source_files": "ReCaptcha/Classes/**/*",
"resource_bundles": {
"ReCaptcha": [
"ReCaptcha/Assets/*"
]
},
"frameworks": "WebKit",
"dependencies": {
"Result": [
"~> 3.0"
]
}
}

19
Example/Pods/Manifest.lock generated Normal file
View File

@ -0,0 +1,19 @@
PODS:
- ReCaptcha (0.1.0):
- Result (~> 3.0)
- Result (3.2.1)
DEPENDENCIES:
- ReCaptcha (from `../`)
EXTERNAL SOURCES:
ReCaptcha:
:path: "../"
SPEC CHECKSUMS:
ReCaptcha: d9912029dfd0988054ec6f1237098a19ef694fd0
Result: 2453a22e5c5b11c0c3a478736e82cd02f763b781
PODFILE CHECKSUM: 816c00f9db90d74940892ce0fa0bcc81d31a3270
COCOAPODS: 1.2.0.beta.3

1060
Example/Pods/Pods.xcodeproj/project.pbxproj generated Normal file

File diff suppressed because it is too large Load Diff

21
Example/Pods/Result/LICENSE generated Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Rob Rix
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.

113
Example/Pods/Result/README.md generated Normal file
View File

@ -0,0 +1,113 @@
# Result
[![Build Status](https://travis-ci.org/antitypical/Result.svg?branch=master)](https://travis-ci.org/antitypical/Result)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
[![CocoaPods](https://img.shields.io/cocoapods/v/Result.svg)](https://cocoapods.org/)
[![Reference Status](https://www.versioneye.com/objective-c/result/reference_badge.svg?style=flat)](https://www.versioneye.com/objective-c/result/references)
This is a Swift µframework providing `Result<Value, Error>`.
`Result<Value, Error>` values are either successful (wrapping `Value`) or failed (wrapping `Error`). This is similar to Swifts native `Optional` type: `success` is like `some`, and `failure` is like `none` except with an associated `Error` value. The addition of an associated `Error` allows errors to be passed along for logging or displaying to the user.
Using this µframework instead of rolling your own `Result` type allows you to easily interface with other frameworks that also use `Result`.
## Use
Use `Result` whenever an operation has the possibility of failure. Consider the following example of a function that tries to extract a `String` for a given key from a JSON `Dictionary`.
```swift
typealias JSONObject = [String: Any]
enum JSONError: Error {
case noSuchKey(String)
case typeMismatch
}
func stringForKey(json: JSONObject, key: String) -> Result<String, JSONError> {
guard let value = json[key] else {
return .failure(.noSuchKey(key))
}
if let value = value as? String {
return .success(value)
}
else {
return .failure(.typeMismatch)
}
}
```
This function provides a more robust wrapper around the default subscripting provided by `Dictionary`. Rather than return `Any?`, it returns a `Result` that either contains the `String` value for the given key, or an `ErrorType` detailing what went wrong.
One simple way to handle a `Result` is to deconstruct it using a `switch` statement.
```swift
switch stringForKey(json, key: "email") {
case let .success(email):
print("The email is \(email)")
case let .failure(.noSuchKey(key)):
print("\(key) is not a valid key")
case .failure(.typeMismatch):
print("Didn't have the right type")
}
```
Using a `switch` statement allows powerful pattern matching, and ensures all possible results are covered. Swift 2.0 offers new ways to deconstruct enums like the `if-case` statement, but be wary as such methods do not ensure errors are handled.
Other methods available for processing `Result` are detailed in the [API documentation](http://cocoadocs.org/docsets/Result/).
## Result vs. Throws
Swift 2.0 introduces error handling via throwing and catching `Error`. `Result` accomplishes the same goal by encapsulating the result instead of hijacking control flow. The `Result` abstraction enables powerful functionality such as `map` and `flatMap`, making `Result` more composable than `throw`.
Since dealing with APIs that throw is common, you can convert such functions into a `Result` by using the `materialize` method. Conversely, a `Result` can be used to throw an error by calling `dematerialize`.
## Higher Order Functions
`map` and `flatMap` operate the same as `Optional.map` and `Optional.flatMap` except they apply to `Result`.
`map` transforms a `Result` into a `Result` of a new type. It does this by taking a function that transforms the `Value` type into a new value. This transformation is only applied in the case of a `success`. In the case of a `failure`, the associated error is re-wrapped in the new `Result`.
```swift
// transforms a Result<Int, JSONError> to a Result<String, JSONError>
let idResult = intForKey(json, key:"id").map { id in String(id) }
```
Here, the final result is either the id as a `String`, or carries over the `failure` from the previous result.
`flatMap` is similar to `map` in that in transforms the `Result` into another `Result`. However, the function passed into `flatMap` must return a `Result`.
An in depth discussion of `map` and `flatMap` is beyond the scope of this documentation. If you would like a deeper understanding, read about functors and monads. This article is a good place to [start](http://www.javiersoto.me/post/106875422394).
## Integration
### Carthage
1. Add this repository as a submodule and/or [add it to your Cartfile](https://github.com/Carthage/Carthage/blob/master/Documentation/Artifacts.md#cartfile) if youre using [carthage](https://github.com/Carthage/Carthage/) to manage your dependencies.
2. Drag `Result.xcodeproj` into your project or workspace.
3. Link your target against `Result.framework`.
4. Application targets should ensure that the framework gets copied into their application bundle. (Framework targets should instead require the application linking them to include Result.)
### Cocoapods
```ruby
pod 'Result', '~> 3.0.0'
```
### Swift Package Manager
```swift
import PackageDescription
let package = Package(
name: "MyProject",
targets: [],
dependencies: [
.Package(url: "https://github.com/antitypical/Result.git",
majorVersion: 3)
]
)
```

271
Example/Pods/Result/Result/Result.swift generated Normal file
View File

@ -0,0 +1,271 @@
// Copyright (c) 2015 Rob Rix. All rights reserved.
/// An enum representing either a failure with an explanatory error, or a success with a result value.
public enum Result<T, Error: Swift.Error>: ResultProtocol, CustomStringConvertible, CustomDebugStringConvertible {
case success(T)
case failure(Error)
// MARK: Constructors
/// Constructs a success wrapping a `value`.
public init(value: T) {
self = .success(value)
}
/// Constructs a failure wrapping an `error`.
public init(error: Error) {
self = .failure(error)
}
/// Constructs a result from an `Optional`, failing with `Error` if `nil`.
public init(_ value: T?, failWith: @autoclosure () -> Error) {
self = value.map(Result.success) ?? .failure(failWith())
}
/// Constructs a result from a function that uses `throw`, failing with `Error` if throws.
public init(_ f: @autoclosure () throws -> T) {
self.init(attempt: f)
}
/// Constructs a result from a function that uses `throw`, failing with `Error` if throws.
public init(attempt f: () throws -> T) {
do {
self = .success(try f())
} catch {
self = .failure(error as! Error)
}
}
// MARK: Deconstruction
/// Returns the value from `success` Results or `throw`s the error.
public func dematerialize() throws -> T {
switch self {
case let .success(value):
return value
case let .failure(error):
throw error
}
}
/// Case analysis for Result.
///
/// Returns the value produced by applying `ifFailure` to `failure` Results, or `ifSuccess` to `success` Results.
public func analysis<Result>(ifSuccess: (T) -> Result, ifFailure: (Error) -> Result) -> Result {
switch self {
case let .success(value):
return ifSuccess(value)
case let .failure(value):
return ifFailure(value)
}
}
// MARK: Errors
/// The domain for errors constructed by Result.
public static var errorDomain: String { return "com.antitypical.Result" }
/// The userInfo key for source functions in errors constructed by Result.
public static var functionKey: String { return "\(errorDomain).function" }
/// The userInfo key for source file paths in errors constructed by Result.
public static var fileKey: String { return "\(errorDomain).file" }
/// The userInfo key for source file line numbers in errors constructed by Result.
public static var lineKey: String { return "\(errorDomain).line" }
/// Constructs an error.
public static func error(_ message: String? = nil, function: String = #function, file: String = #file, line: Int = #line) -> NSError {
var userInfo: [String: Any] = [
functionKey: function,
fileKey: file,
lineKey: line,
]
if let message = message {
userInfo[NSLocalizedDescriptionKey] = message
}
return NSError(domain: errorDomain, code: 0, userInfo: userInfo)
}
// MARK: CustomStringConvertible
public var description: String {
return analysis(
ifSuccess: { ".success(\($0))" },
ifFailure: { ".failure(\($0))" })
}
// MARK: CustomDebugStringConvertible
public var debugDescription: String {
return description
}
}
// MARK: - Derive result from failable closure
public func materialize<T>(_ f: () throws -> T) -> Result<T, AnyError> {
return materialize(try f())
}
public func materialize<T>(_ f: @autoclosure () throws -> T) -> Result<T, AnyError> {
do {
return .success(try f())
} catch {
return .failure(AnyError(error))
}
}
@available(*, deprecated, message: "Use the overload which returns `Result<T, AnyError>` instead")
public func materialize<T>(_ f: () throws -> T) -> Result<T, NSError> {
return materialize(try f())
}
@available(*, deprecated, message: "Use the overload which returns `Result<T, AnyError>` instead")
public func materialize<T>(_ f: @autoclosure () throws -> T) -> Result<T, NSError> {
do {
return .success(try f())
} catch {
// This isn't great, but it lets us maintain compatibility until this deprecated
// method can be removed.
#if _runtime(_ObjC)
return .failure(error as NSError)
#else
// https://github.com/apple/swift-corelibs-foundation/blob/swift-3.0.2-RELEASE/Foundation/NSError.swift#L314
let userInfo = _swift_Foundation_getErrorDefaultUserInfo(error) as? [String: Any]
let nsError = NSError(domain: error._domain, code: error._code, userInfo: userInfo)
return .failure(nsError)
#endif
}
}
// MARK: - Cocoa API conveniences
#if !os(Linux)
/// Constructs a `Result` with the result of calling `try` with an error pointer.
///
/// This is convenient for wrapping Cocoa API which returns an object or `nil` + an error, by reference. e.g.:
///
/// Result.try { NSData(contentsOfURL: URL, options: .dataReadingMapped, error: $0) }
public func `try`<T>(_ function: String = #function, file: String = #file, line: Int = #line, `try`: (NSErrorPointer) -> T?) -> Result<T, NSError> {
var error: NSError?
return `try`(&error).map(Result.success) ?? .failure(error ?? Result<T, NSError>.error(function: function, file: file, line: line))
}
/// Constructs a `Result` with the result of calling `try` with an error pointer.
///
/// This is convenient for wrapping Cocoa API which returns a `Bool` + an error, by reference. e.g.:
///
/// Result.try { NSFileManager.defaultManager().removeItemAtURL(URL, error: $0) }
public func `try`(_ function: String = #function, file: String = #file, line: Int = #line, `try`: (NSErrorPointer) -> Bool) -> Result<(), NSError> {
var error: NSError?
return `try`(&error) ?
.success(())
: .failure(error ?? Result<(), NSError>.error(function: function, file: file, line: line))
}
#endif
// MARK: - ErrorProtocolConvertible conformance
extension NSError: ErrorProtocolConvertible {
public static func error(from error: Swift.Error) -> Self {
func cast<T: NSError>(_ error: Swift.Error) -> T {
return error as! T
}
return cast(error)
}
}
// MARK: - Errors
/// An error that is impossible to construct.
///
/// This can be used to describe `Result`s where failures will never
/// be generated. For example, `Result<Int, NoError>` describes a result that
/// contains an `Int`eger and is guaranteed never to be a `failure`.
public enum NoError: Swift.Error, Equatable {
public static func ==(lhs: NoError, rhs: NoError) -> Bool {
return true
}
}
/// A type-erased error which wraps an arbitrary error instance. This should be
/// useful for generic contexts.
public struct AnyError: Swift.Error {
/// The underlying error.
public let error: Swift.Error
public init(_ error: Swift.Error) {
if let anyError = error as? AnyError {
self = anyError
} else {
self.error = error
}
}
}
extension AnyError: ErrorProtocolConvertible {
public static func error(from error: Error) -> AnyError {
return AnyError(error)
}
}
extension AnyError: CustomStringConvertible {
public var description: String {
return String(describing: error)
}
}
// There appears to be a bug in Foundation on Linux which prevents this from working:
// https://bugs.swift.org/browse/SR-3565
// Don't forget to comment the tests back in when removing this check when it's fixed!
#if !os(Linux)
extension AnyError: LocalizedError {
public var errorDescription: String? {
return error.localizedDescription
}
public var failureReason: String? {
return (error as? LocalizedError)?.failureReason
}
public var helpAnchor: String? {
return (error as? LocalizedError)?.helpAnchor
}
public var recoverySuggestion: String? {
return (error as? LocalizedError)?.recoverySuggestion
}
}
#endif
// MARK: - migration support
extension Result {
@available(*, unavailable, renamed: "success")
public static func Success(_: T) -> Result<T, Error> {
fatalError()
}
@available(*, unavailable, renamed: "failure")
public static func Failure(_: Error) -> Result<T, Error> {
fatalError()
}
}
extension NSError {
@available(*, unavailable, renamed: "error(from:)")
public static func errorFromErrorType(_ error: Swift.Error) -> Self {
fatalError()
}
}
import Foundation

View File

@ -0,0 +1,200 @@
// Copyright (c) 2015 Rob Rix. All rights reserved.
/// A type that can represent either failure with an error or success with a result value.
public protocol ResultProtocol {
associatedtype Value
associatedtype Error: Swift.Error
/// Constructs a successful result wrapping a `value`.
init(value: Value)
/// Constructs a failed result wrapping an `error`.
init(error: Error)
/// Case analysis for ResultProtocol.
///
/// Returns the value produced by appliying `ifFailure` to the error if self represents a failure, or `ifSuccess` to the result value if self represents a success.
func analysis<U>(ifSuccess: (Value) -> U, ifFailure: (Error) -> U) -> U
/// Returns the value if self represents a success, `nil` otherwise.
///
/// A default implementation is provided by a protocol extension. Conforming types may specialize it.
var value: Value? { get }
/// Returns the error if self represents a failure, `nil` otherwise.
///
/// A default implementation is provided by a protocol extension. Conforming types may specialize it.
var error: Error? { get }
}
public extension ResultProtocol {
/// Returns the value if self represents a success, `nil` otherwise.
public var value: Value? {
return analysis(ifSuccess: { $0 }, ifFailure: { _ in nil })
}
/// Returns the error if self represents a failure, `nil` otherwise.
public var error: Error? {
return analysis(ifSuccess: { _ in nil }, ifFailure: { $0 })
}
/// Returns a new Result by mapping `Success`es values using `transform`, or re-wrapping `Failure`s errors.
public func map<U>(_ transform: (Value) -> U) -> Result<U, Error> {
return flatMap { .success(transform($0)) }
}
/// Returns the result of applying `transform` to `Success`es values, or re-wrapping `Failure`s errors.
public func flatMap<U>(_ transform: (Value) -> Result<U, Error>) -> Result<U, Error> {
return analysis(
ifSuccess: transform,
ifFailure: Result<U, Error>.failure)
}
/// Returns a Result with a tuple of the receiver and `other` values if both
/// are `Success`es, or re-wrapping the error of the earlier `Failure`.
public func fanout<R: ResultProtocol>(_ other: @autoclosure () -> R) -> Result<(Value, R.Value), Error>
where Error == R.Error
{
return self.flatMap { left in other().map { right in (left, right) } }
}
/// Returns a new Result by mapping `Failure`'s values using `transform`, or re-wrapping `Success`es values.
public func mapError<Error2>(_ transform: (Error) -> Error2) -> Result<Value, Error2> {
return flatMapError { .failure(transform($0)) }
}
/// Returns the result of applying `transform` to `Failure`s errors, or re-wrapping `Success`es values.
public func flatMapError<Error2>(_ transform: (Error) -> Result<Value, Error2>) -> Result<Value, Error2> {
return analysis(
ifSuccess: Result<Value, Error2>.success,
ifFailure: transform)
}
/// Returns a new Result by mapping `Success`es values using `success`, and by mapping `Failure`'s values using `failure`.
public func bimap<U, Error2>(success: (Value) -> U, failure: (Error) -> Error2) -> Result<U, Error2> {
return analysis(
ifSuccess: { .success(success($0)) },
ifFailure: { .failure(failure($0)) }
)
}
}
public extension ResultProtocol {
// MARK: Higher-order functions
/// Returns `self.value` if this result is a .Success, or the given value otherwise. Equivalent with `??`
public func recover(_ value: @autoclosure () -> Value) -> Value {
return self.value ?? value()
}
/// Returns this result if it is a .Success, or the given result otherwise. Equivalent with `??`
public func recover(with result: @autoclosure () -> Self) -> Self {
return analysis(
ifSuccess: { _ in self },
ifFailure: { _ in result() })
}
}
/// Protocol used to constrain `tryMap` to `Result`s with compatible `Error`s.
public protocol ErrorProtocolConvertible: Swift.Error {
static func error(from error: Swift.Error) -> Self
}
public extension ResultProtocol where Error: ErrorProtocolConvertible {
/// Returns the result of applying `transform` to `Success`es values, or wrapping thrown errors.
public func tryMap<U>(_ transform: (Value) throws -> U) -> Result<U, Error> {
return flatMap { value in
do {
return .success(try transform(value))
}
catch {
let convertedError = Error.error(from: error)
// Revisit this in a future version of Swift. https://twitter.com/jckarter/status/672931114944696321
return .failure(convertedError)
}
}
}
}
// MARK: - Operators
infix operator &&& : LogicalConjunctionPrecedence
/// Returns a Result with a tuple of `left` and `right` values if both are `Success`es, or re-wrapping the error of the earlier `Failure`.
@available(*, deprecated, renamed: "ResultProtocol.fanout(self:_:)")
public func &&& <L: ResultProtocol, R: ResultProtocol> (left: L, right: @autoclosure () -> R) -> Result<(L.Value, R.Value), L.Error>
where L.Error == R.Error
{
return left.fanout(right)
}
precedencegroup ChainingPrecedence {
associativity: left
higherThan: TernaryPrecedence
}
infix operator >>- : ChainingPrecedence
/// Returns the result of applying `transform` to `Success`es values, or re-wrapping `Failure`s errors.
///
/// This is a synonym for `flatMap`.
@available(*, deprecated, renamed: "ResultProtocol.flatMap(self:_:)")
public func >>- <T: ResultProtocol, U> (result: T, transform: (T.Value) -> Result<U, T.Error>) -> Result<U, T.Error> {
return result.flatMap(transform)
}
/// Returns `true` if `left` and `right` are both `Success`es and their values are equal, or if `left` and `right` are both `Failure`s and their errors are equal.
public func == <T: ResultProtocol> (left: T, right: T) -> Bool
where T.Value: Equatable, T.Error: Equatable
{
if let left = left.value, let right = right.value {
return left == right
} else if let left = left.error, let right = right.error {
return left == right
}
return false
}
/// Returns `true` if `left` and `right` represent different cases, or if they represent the same case but different values.
public func != <T: ResultProtocol> (left: T, right: T) -> Bool
where T.Value: Equatable, T.Error: Equatable
{
return !(left == right)
}
/// Returns the value of `left` if it is a `Success`, or `right` otherwise. Short-circuits.
public func ?? <T: ResultProtocol> (left: T, right: @autoclosure () -> T.Value) -> T.Value {
return left.recover(right())
}
/// Returns `left` if it is a `Success`es, or `right` otherwise. Short-circuits.
public func ?? <T: ResultProtocol> (left: T, right: @autoclosure () -> T) -> T {
return left.recover(with: right())
}
// MARK: - migration support
@available(*, unavailable, renamed: "ResultProtocol")
public typealias ResultType = ResultProtocol
@available(*, unavailable, renamed: "Error")
public typealias ResultErrorType = Swift.Error
@available(*, unavailable, renamed: "ErrorProtocolConvertible")
public typealias ErrorTypeConvertible = ErrorProtocolConvertible
extension ResultProtocol {
@available(*, unavailable, renamed: "recover(with:)")
public func recoverWith(_ result: @autoclosure () -> Self) -> Self {
fatalError()
}
}
extension ErrorProtocolConvertible {
@available(*, unavailable, renamed: "error(from:)")
public static func errorFromErrorType(_ error: Swift.Error) -> Self {
fatalError()
}
}

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@ -0,0 +1,50 @@
# Acknowledgements
This application makes use of the following third party libraries:
## ReCaptcha
Copyright (c) 2017 fjcaetano <flavio@vieiracaetano.com>
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.
## Result
The MIT License (MIT)
Copyright (c) 2014 Rob Rix
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.
Generated by CocoaPods - https://cocoapods.org

View File

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>FooterText</key>
<string>This application makes use of the following third party libraries:</string>
<key>Title</key>
<string>Acknowledgements</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>Copyright (c) 2017 fjcaetano &lt;flavio@vieiracaetano.com&gt;
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.
</string>
<key>License</key>
<string>MIT</string>
<key>Title</key>
<string>ReCaptcha</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>The MIT License (MIT)
Copyright (c) 2014 Rob Rix
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.</string>
<key>License</key>
<string>MIT</string>
<key>Title</key>
<string>Result</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>Generated by CocoaPods - https://cocoapods.org</string>
<key>Title</key>
<string></string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
</array>
<key>StringsTable</key>
<string>Acknowledgements</string>
<key>Title</key>
<string>Acknowledgements</string>
</dict>
</plist>

View File

@ -0,0 +1,5 @@
#import <Foundation/Foundation.h>
@interface PodsDummy_Pods_ReCaptcha_Example : NSObject
@end
@implementation PodsDummy_Pods_ReCaptcha_Example
@end

View File

@ -0,0 +1,101 @@
#!/bin/sh
set -e
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
install_framework()
{
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
local source="${BUILT_PRODUCTS_DIR}/$1"
elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
elif [ -r "$1" ]; then
local source="$1"
fi
local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
if [ -L "${source}" ]; then
echo "Symlinked..."
source="$(readlink "${source}")"
fi
# use filter instead of exclude so missing patterns dont' throw errors
echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
local basename
basename="$(basename -s .framework "$1")"
binary="${destination}/${basename}.framework/${basename}"
if ! [ -r "$binary" ]; then
binary="${destination}/${basename}"
fi
# Strip invalid architectures so "fat" simulator / device frameworks work on device
if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
strip_invalid_archs "$binary"
fi
# Resign the code if required by the build settings to avoid unstable apps
code_sign_if_enabled "${destination}/$(basename "$1")"
# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
local swift_runtime_libs
swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]})
for lib in $swift_runtime_libs; do
echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
code_sign_if_enabled "${destination}/${lib}"
done
fi
}
# Signs a framework with the provided identity
code_sign_if_enabled() {
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
# Use the current code_sign_identitiy
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'"
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
code_sign_cmd="$code_sign_cmd &"
fi
echo "$code_sign_cmd"
eval "$code_sign_cmd"
fi
}
# Strip invalid architectures
strip_invalid_archs() {
binary="$1"
# Get architectures for current file
archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)"
stripped=""
for arch in $archs; do
if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
stripped="$stripped $arch"
fi
done
if [[ "$stripped" ]]; then
echo "Stripped $binary of architectures:$stripped"
fi
}
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "$BUILT_PRODUCTS_DIR/ReCaptcha/ReCaptcha.framework"
install_framework "$BUILT_PRODUCTS_DIR/Result/Result.framework"
fi
if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "$BUILT_PRODUCTS_DIR/ReCaptcha/ReCaptcha.framework"
install_framework "$BUILT_PRODUCTS_DIR/Result/Result.framework"
fi
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
wait
fi

View File

@ -0,0 +1,99 @@
#!/bin/sh
set -e
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
> "$RESOURCES_TO_COPY"
XCASSET_FILES=()
case "${TARGETED_DEVICE_FAMILY}" in
1,2)
TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
;;
1)
TARGET_DEVICE_ARGS="--target-device iphone"
;;
2)
TARGET_DEVICE_ARGS="--target-device ipad"
;;
3)
TARGET_DEVICE_ARGS="--target-device tv"
;;
*)
TARGET_DEVICE_ARGS="--target-device mac"
;;
esac
install_resource()
{
if [[ "$1" = /* ]] ; then
RESOURCE_PATH="$1"
else
RESOURCE_PATH="${PODS_ROOT}/$1"
fi
if [[ ! -e "$RESOURCE_PATH" ]] ; then
cat << EOM
error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script.
EOM
exit 1
fi
case $RESOURCE_PATH in
*.storyboard)
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.xib)
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.framework)
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
;;
*.xcdatamodel)
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\""
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom"
;;
*.xcdatamodeld)
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\""
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd"
;;
*.xcmappingmodel)
echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\""
xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
;;
*.xcassets)
ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH"
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
;;
*)
echo "$RESOURCE_PATH"
echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
;;
esac
}
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then
mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
fi
rm -f "$RESOURCES_TO_COPY"
if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ]
then
# Find all other xcassets (this unfortunately includes those of path pods and other targets).
OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
while read line; do
if [[ $line != "${PODS_ROOT}*" ]]; then
XCASSET_FILES+=("$line")
fi
done <<<"$OTHER_XCASSETS"
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
fi

View File

@ -0,0 +1,16 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
FOUNDATION_EXPORT double Pods_ReCaptcha_ExampleVersionNumber;
FOUNDATION_EXPORT const unsigned char Pods_ReCaptcha_ExampleVersionString[];

View File

@ -0,0 +1,10 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/ReCaptcha" "$PODS_CONFIGURATION_BUILD_DIR/Result"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/ReCaptcha/ReCaptcha.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/Result/Result.framework/Headers"
OTHER_LDFLAGS = $(inherited) -framework "ReCaptcha" -framework "Result"
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}/Pods

View File

@ -0,0 +1,6 @@
framework module Pods_ReCaptcha_Example {
umbrella header "Pods-ReCaptcha_Example-umbrella.h"
export *
module * { export * }
}

View File

@ -0,0 +1,10 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/ReCaptcha" "$PODS_CONFIGURATION_BUILD_DIR/Result"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/ReCaptcha/ReCaptcha.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/Result/Result.framework/Headers"
OTHER_LDFLAGS = $(inherited) -framework "ReCaptcha" -framework "Result"
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}/Pods

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@ -0,0 +1,3 @@
# Acknowledgements
This application makes use of the following third party libraries:
Generated by CocoaPods - https://cocoapods.org

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>FooterText</key>
<string>This application makes use of the following third party libraries:</string>
<key>Title</key>
<string>Acknowledgements</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>Generated by CocoaPods - https://cocoapods.org</string>
<key>Title</key>
<string></string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
</array>
<key>StringsTable</key>
<string>Acknowledgements</string>
<key>Title</key>
<string>Acknowledgements</string>
</dict>
</plist>

View File

@ -0,0 +1,5 @@
#import <Foundation/Foundation.h>
@interface PodsDummy_Pods_ReCaptcha_Tests : NSObject
@end
@implementation PodsDummy_Pods_ReCaptcha_Tests
@end

View File

@ -0,0 +1,92 @@
#!/bin/sh
set -e
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
install_framework()
{
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
local source="${BUILT_PRODUCTS_DIR}/$1"
elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
elif [ -r "$1" ]; then
local source="$1"
fi
local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
if [ -L "${source}" ]; then
echo "Symlinked..."
source="$(readlink "${source}")"
fi
# use filter instead of exclude so missing patterns dont' throw errors
echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
local basename
basename="$(basename -s .framework "$1")"
binary="${destination}/${basename}.framework/${basename}"
if ! [ -r "$binary" ]; then
binary="${destination}/${basename}"
fi
# Strip invalid architectures so "fat" simulator / device frameworks work on device
if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
strip_invalid_archs "$binary"
fi
# Resign the code if required by the build settings to avoid unstable apps
code_sign_if_enabled "${destination}/$(basename "$1")"
# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
local swift_runtime_libs
swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]})
for lib in $swift_runtime_libs; do
echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
code_sign_if_enabled "${destination}/${lib}"
done
fi
}
# Signs a framework with the provided identity
code_sign_if_enabled() {
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
# Use the current code_sign_identitiy
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'"
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
code_sign_cmd="$code_sign_cmd &"
fi
echo "$code_sign_cmd"
eval "$code_sign_cmd"
fi
}
# Strip invalid architectures
strip_invalid_archs() {
binary="$1"
# Get architectures for current file
archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)"
stripped=""
for arch in $archs; do
if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
stripped="$stripped $arch"
fi
done
if [[ "$stripped" ]]; then
echo "Stripped $binary of architectures:$stripped"
fi
}
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
wait
fi

View File

@ -0,0 +1,99 @@
#!/bin/sh
set -e
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
> "$RESOURCES_TO_COPY"
XCASSET_FILES=()
case "${TARGETED_DEVICE_FAMILY}" in
1,2)
TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
;;
1)
TARGET_DEVICE_ARGS="--target-device iphone"
;;
2)
TARGET_DEVICE_ARGS="--target-device ipad"
;;
3)
TARGET_DEVICE_ARGS="--target-device tv"
;;
*)
TARGET_DEVICE_ARGS="--target-device mac"
;;
esac
install_resource()
{
if [[ "$1" = /* ]] ; then
RESOURCE_PATH="$1"
else
RESOURCE_PATH="${PODS_ROOT}/$1"
fi
if [[ ! -e "$RESOURCE_PATH" ]] ; then
cat << EOM
error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script.
EOM
exit 1
fi
case $RESOURCE_PATH in
*.storyboard)
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.xib)
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.framework)
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
;;
*.xcdatamodel)
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\""
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom"
;;
*.xcdatamodeld)
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\""
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd"
;;
*.xcmappingmodel)
echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\""
xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
;;
*.xcassets)
ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH"
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
;;
*)
echo "$RESOURCE_PATH"
echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
;;
esac
}
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then
mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
fi
rm -f "$RESOURCES_TO_COPY"
if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ]
then
# Find all other xcassets (this unfortunately includes those of path pods and other targets).
OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
while read line; do
if [[ $line != "${PODS_ROOT}*" ]]; then
XCASSET_FILES+=("$line")
fi
done <<<"$OTHER_XCASSETS"
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
fi

View File

@ -0,0 +1,16 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
FOUNDATION_EXPORT double Pods_ReCaptcha_TestsVersionNumber;
FOUNDATION_EXPORT const unsigned char Pods_ReCaptcha_TestsVersionString[];

View File

@ -0,0 +1,7 @@
FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/ReCaptcha" "$PODS_CONFIGURATION_BUILD_DIR/Result"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/ReCaptcha/ReCaptcha.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/Result/Result.framework/Headers"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}/Pods

View File

@ -0,0 +1,6 @@
framework module Pods_ReCaptcha_Tests {
umbrella header "Pods-ReCaptcha_Tests-umbrella.h"
export *
module * { export * }
}

View File

@ -0,0 +1,7 @@
FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/ReCaptcha" "$PODS_CONFIGURATION_BUILD_DIR/Result"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/ReCaptcha/ReCaptcha.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/Result/Result.framework/Headers"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}/Pods

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@ -0,0 +1,5 @@
#import <Foundation/Foundation.h>
@interface PodsDummy_ReCaptcha : NSObject
@end
@implementation PodsDummy_ReCaptcha
@end

View File

@ -0,0 +1,12 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif

View File

@ -0,0 +1,16 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
FOUNDATION_EXPORT double ReCaptchaVersionNumber;
FOUNDATION_EXPORT const unsigned char ReCaptchaVersionString[];

View File

@ -0,0 +1,6 @@
framework module ReCaptcha {
umbrella header "ReCaptcha-umbrella.h"
export *
module * { export * }
}

View File

@ -0,0 +1,12 @@
CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/ReCaptcha
FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Result"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public"
OTHER_LDFLAGS = -framework "WebKit"
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>0.1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>3.2.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@ -0,0 +1,5 @@
#import <Foundation/Foundation.h>
@interface PodsDummy_Result : NSObject
@end
@implementation PodsDummy_Result
@end

View File

@ -0,0 +1,12 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif

View File

@ -0,0 +1,16 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
FOUNDATION_EXPORT double ResultVersionNumber;
FOUNDATION_EXPORT const unsigned char ResultVersionString[];

View File

@ -0,0 +1,6 @@
framework module Result {
umbrella header "Result-umbrella.h"
export *
module * { export * }
}

View File

@ -0,0 +1,10 @@
CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/Result
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public"
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
PODS_BUILD_DIR = $BUILD_DIR
PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/Result
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES

View File

@ -0,0 +1,591 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
52549DA49C762538F7829851 /* Pods_ReCaptcha_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9417A28DC340FF0BC1627B3F /* Pods_ReCaptcha_Tests.framework */; };
607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; };
607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; };
607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; };
607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; };
607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; };
607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; };
BD850CB2DF4C9C94FC51226C /* Pods_ReCaptcha_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 62BEEA62161F672468CCFD64 /* Pods_ReCaptcha_Example.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 607FACC81AFB9204008FA782 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 607FACCF1AFB9204008FA782;
remoteInfo = ReCaptcha;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
0A2D0E5B4C6E445BF971488B /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; name = README.md; path = ../README.md; sourceTree = "<group>"; };
44568771DD76CFBDF2D1C83D /* Pods-ReCaptcha_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReCaptcha_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ReCaptcha_Tests/Pods-ReCaptcha_Tests.release.xcconfig"; sourceTree = "<group>"; };
4FED8267564AACFFEE83DB15 /* Pods-ReCaptcha_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReCaptcha_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ReCaptcha_Tests/Pods-ReCaptcha_Tests.debug.xcconfig"; sourceTree = "<group>"; };
607FACD01AFB9204008FA782 /* ReCaptcha_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ReCaptcha_Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
607FACE51AFB9204008FA782 /* ReCaptcha_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ReCaptcha_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = "<group>"; };
62BEEA62161F672468CCFD64 /* Pods_ReCaptcha_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ReCaptcha_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
62C1DD0E80E9920845E5DA51 /* ReCaptcha.podspec */ = {isa = PBXFileReference; includeInIndex = 1; name = ReCaptcha.podspec; path = ../ReCaptcha.podspec; sourceTree = "<group>"; };
80FF4E03D71AACBD81A36301 /* Pods-ReCaptcha_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReCaptcha_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ReCaptcha_Example/Pods-ReCaptcha_Example.debug.xcconfig"; sourceTree = "<group>"; };
9417A28DC340FF0BC1627B3F /* Pods_ReCaptcha_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ReCaptcha_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C2A0BDD35B5E219129E9BC65 /* Pods-ReCaptcha_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReCaptcha_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-ReCaptcha_Example/Pods-ReCaptcha_Example.release.xcconfig"; sourceTree = "<group>"; };
C8537003ECC47117AF54DCA9 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
607FACCD1AFB9204008FA782 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
BD850CB2DF4C9C94FC51226C /* Pods_ReCaptcha_Example.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
607FACE21AFB9204008FA782 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
52549DA49C762538F7829851 /* Pods_ReCaptcha_Tests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
607FACC71AFB9204008FA782 = {
isa = PBXGroup;
children = (
607FACF51AFB993E008FA782 /* Podspec Metadata */,
607FACD21AFB9204008FA782 /* Example for ReCaptcha */,
607FACE81AFB9204008FA782 /* Tests */,
607FACD11AFB9204008FA782 /* Products */,
716E2370DBF48D5E2C86E802 /* Pods */,
FDC29111B59FAB9F0F44DADB /* Frameworks */,
);
sourceTree = "<group>";
};
607FACD11AFB9204008FA782 /* Products */ = {
isa = PBXGroup;
children = (
607FACD01AFB9204008FA782 /* ReCaptcha_Example.app */,
607FACE51AFB9204008FA782 /* ReCaptcha_Tests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
607FACD21AFB9204008FA782 /* Example for ReCaptcha */ = {
isa = PBXGroup;
children = (
607FACD51AFB9204008FA782 /* AppDelegate.swift */,
607FACD71AFB9204008FA782 /* ViewController.swift */,
607FACD91AFB9204008FA782 /* Main.storyboard */,
607FACDC1AFB9204008FA782 /* Images.xcassets */,
607FACDE1AFB9204008FA782 /* LaunchScreen.xib */,
607FACD31AFB9204008FA782 /* Supporting Files */,
);
name = "Example for ReCaptcha";
path = ReCaptcha;
sourceTree = "<group>";
};
607FACD31AFB9204008FA782 /* Supporting Files */ = {
isa = PBXGroup;
children = (
607FACD41AFB9204008FA782 /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
607FACE81AFB9204008FA782 /* Tests */ = {
isa = PBXGroup;
children = (
607FACEB1AFB9204008FA782 /* Tests.swift */,
607FACE91AFB9204008FA782 /* Supporting Files */,
);
path = Tests;
sourceTree = "<group>";
};
607FACE91AFB9204008FA782 /* Supporting Files */ = {
isa = PBXGroup;
children = (
607FACEA1AFB9204008FA782 /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
607FACF51AFB993E008FA782 /* Podspec Metadata */ = {
isa = PBXGroup;
children = (
62C1DD0E80E9920845E5DA51 /* ReCaptcha.podspec */,
0A2D0E5B4C6E445BF971488B /* README.md */,
C8537003ECC47117AF54DCA9 /* LICENSE */,
);
name = "Podspec Metadata";
sourceTree = "<group>";
};
716E2370DBF48D5E2C86E802 /* Pods */ = {
isa = PBXGroup;
children = (
80FF4E03D71AACBD81A36301 /* Pods-ReCaptcha_Example.debug.xcconfig */,
C2A0BDD35B5E219129E9BC65 /* Pods-ReCaptcha_Example.release.xcconfig */,
4FED8267564AACFFEE83DB15 /* Pods-ReCaptcha_Tests.debug.xcconfig */,
44568771DD76CFBDF2D1C83D /* Pods-ReCaptcha_Tests.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
FDC29111B59FAB9F0F44DADB /* Frameworks */ = {
isa = PBXGroup;
children = (
62BEEA62161F672468CCFD64 /* Pods_ReCaptcha_Example.framework */,
9417A28DC340FF0BC1627B3F /* Pods_ReCaptcha_Tests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
607FACCF1AFB9204008FA782 /* ReCaptcha_Example */ = {
isa = PBXNativeTarget;
buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "ReCaptcha_Example" */;
buildPhases = (
51299F67A8756E2B3EAE411A /* [CP] Check Pods Manifest.lock */,
607FACCC1AFB9204008FA782 /* Sources */,
607FACCD1AFB9204008FA782 /* Frameworks */,
607FACCE1AFB9204008FA782 /* Resources */,
8F03FFB3F5C55E873C23C682 /* [CP] Embed Pods Frameworks */,
ED1C0E07490C9C4B4A401061 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
);
name = ReCaptcha_Example;
productName = ReCaptcha;
productReference = 607FACD01AFB9204008FA782 /* ReCaptcha_Example.app */;
productType = "com.apple.product-type.application";
};
607FACE41AFB9204008FA782 /* ReCaptcha_Tests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "ReCaptcha_Tests" */;
buildPhases = (
32C4C887B33CF62A7DE5872D /* [CP] Check Pods Manifest.lock */,
607FACE11AFB9204008FA782 /* Sources */,
607FACE21AFB9204008FA782 /* Frameworks */,
607FACE31AFB9204008FA782 /* Resources */,
8B5691817244442ACEDE9B1B /* [CP] Embed Pods Frameworks */,
D444826FD5C8EEFF5D77456E /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
607FACE71AFB9204008FA782 /* PBXTargetDependency */,
);
name = ReCaptcha_Tests;
productName = Tests;
productReference = 607FACE51AFB9204008FA782 /* ReCaptcha_Tests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
607FACC81AFB9204008FA782 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 0820;
ORGANIZATIONNAME = CocoaPods;
TargetAttributes = {
607FACCF1AFB9204008FA782 = {
CreatedOnToolsVersion = 6.3.1;
LastSwiftMigration = 0820;
};
607FACE41AFB9204008FA782 = {
CreatedOnToolsVersion = 6.3.1;
LastSwiftMigration = 0820;
TestTargetID = 607FACCF1AFB9204008FA782;
};
};
};
buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "ReCaptcha" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 607FACC71AFB9204008FA782;
productRefGroup = 607FACD11AFB9204008FA782 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
607FACCF1AFB9204008FA782 /* ReCaptcha_Example */,
607FACE41AFB9204008FA782 /* ReCaptcha_Tests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
607FACCE1AFB9204008FA782 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */,
607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */,
607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
607FACE31AFB9204008FA782 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
32C4C887B33CF62A7DE5872D /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
51299F67A8756E2B3EAE411A /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
8B5691817244442ACEDE9B1B /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ReCaptcha_Tests/Pods-ReCaptcha_Tests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
8F03FFB3F5C55E873C23C682 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ReCaptcha_Example/Pods-ReCaptcha_Example-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
D444826FD5C8EEFF5D77456E /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ReCaptcha_Tests/Pods-ReCaptcha_Tests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
ED1C0E07490C9C4B4A401061 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ReCaptcha_Example/Pods-ReCaptcha_Example-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
607FACCC1AFB9204008FA782 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
607FACD81AFB9204008FA782 /* ViewController.swift in Sources */,
607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
607FACE11AFB9204008FA782 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
607FACEC1AFB9204008FA782 /* Tests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
607FACE71AFB9204008FA782 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 607FACCF1AFB9204008FA782 /* ReCaptcha_Example */;
targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
607FACD91AFB9204008FA782 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
607FACDA1AFB9204008FA782 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = {
isa = PBXVariantGroup;
children = (
607FACDF1AFB9204008FA782 /* Base */,
);
name = LaunchScreen.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
607FACED1AFB9204008FA782 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.3;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
607FACEE1AFB9204008FA782 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.3;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
607FACF01AFB9204008FA782 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 80FF4E03D71AACBD81A36301 /* Pods-ReCaptcha_Example.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = ReCaptcha/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MODULE_NAME = ExampleApp;
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
607FACF11AFB9204008FA782 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = C2A0BDD35B5E219129E9BC65 /* Pods-ReCaptcha_Example.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = ReCaptcha/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MODULE_NAME = ExampleApp;
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Release;
};
607FACF31AFB9204008FA782 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 4FED8267564AACFFEE83DB15 /* Pods-ReCaptcha_Tests.debug.xcconfig */;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
INFOPLIST_FILE = Tests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
607FACF41AFB9204008FA782 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 44568771DD76CFBDF2D1C83D /* Pods-ReCaptcha_Tests.release.xcconfig */;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
INFOPLIST_FILE = Tests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "ReCaptcha" */ = {
isa = XCConfigurationList;
buildConfigurations = (
607FACED1AFB9204008FA782 /* Debug */,
607FACEE1AFB9204008FA782 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "ReCaptcha_Example" */ = {
isa = XCConfigurationList;
buildConfigurations = (
607FACF01AFB9204008FA782 /* Debug */,
607FACF11AFB9204008FA782 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "ReCaptcha_Tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
607FACF31AFB9204008FA782 /* Debug */,
607FACF41AFB9204008FA782 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 607FACC81AFB9204008FA782 /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:ReCaptcha.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0820"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "607FACCF1AFB9204008FA782"
BuildableName = "ReCaptcha_Example.app"
BlueprintName = "ReCaptcha_Example"
ReferencedContainer = "container:ReCaptcha.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "607FACE41AFB9204008FA782"
BuildableName = "ReCaptcha_Tests.xctest"
BlueprintName = "ReCaptcha_Tests"
ReferencedContainer = "container:ReCaptcha.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "607FACE41AFB9204008FA782"
BuildableName = "ReCaptcha_Tests.xctest"
BlueprintName = "ReCaptcha_Tests"
ReferencedContainer = "container:ReCaptcha.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "607FACCF1AFB9204008FA782"
BuildableName = "ReCaptcha_Example.app"
BlueprintName = "ReCaptcha_Example"
ReferencedContainer = "container:ReCaptcha.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "607FACCF1AFB9204008FA782"
BuildableName = "ReCaptcha_Example.app"
BlueprintName = "ReCaptcha_Example"
ReferencedContainer = "container:ReCaptcha.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "607FACCF1AFB9204008FA782"
BuildableName = "ReCaptcha_Example.app"
BlueprintName = "ReCaptcha_Example"
ReferencedContainer = "container:ReCaptcha.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:ReCaptcha.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,46 @@
//
// AppDelegate.swift
// ReCaptcha
//
// Created by fjcaetano on 03/22/2017.
// Copyright (c) 2017 fjcaetano. All rights reserved.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6214" systemVersion="14A314h" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6207"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 CocoaPods. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
<rect key="frame" x="20" y="439" width="441" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="ReCaptcha" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
<rect key="frame" x="20" y="140" width="441" height="43"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="548" y="455"/>
</view>
</objects>
</document>

View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12118" systemVersion="16D32" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="vXZ-lx-hvc">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12086"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="ufC-wZ-h7g">
<objects>
<viewController id="vXZ-lx-hvc" customClass="ViewController" customModule="ReCaptcha_Example" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="jyV-Pf-zRb"/>
<viewControllerLayoutGuide type="bottom" id="2fi-mo-0CV"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="kh9-bI-dsS">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="RDW-bD-rSo">
<rect key="frame" x="50" y="505" width="275" height="50"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="Bt8-Ou-ht2"/>
</constraints>
<state key="normal" title="Validate"/>
<connections>
<action selector="didPressButtonWithButton:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="FpZ-S1-HW0"/>
</connections>
</button>
<activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="jHc-GP-v1Z">
<rect key="frame" x="177" y="323" width="20" height="20"/>
</activityIndicatorView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="o6f-cL-1PF">
<rect key="frame" x="20" y="192" width="335" height="283"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="o6f-cL-1PF" firstAttribute="leading" secondItem="kh9-bI-dsS" secondAttribute="leading" constant="20" id="0dV-t0-W0Y"/>
<constraint firstItem="2fi-mo-0CV" firstAttribute="top" secondItem="RDW-bD-rSo" secondAttribute="bottom" constant="112" id="E4K-Vp-ZL2"/>
<constraint firstItem="o6f-cL-1PF" firstAttribute="centerY" secondItem="kh9-bI-dsS" secondAttribute="centerY" priority="750" id="NMD-ir-PXe"/>
<constraint firstItem="RDW-bD-rSo" firstAttribute="top" secondItem="o6f-cL-1PF" secondAttribute="bottom" constant="30" id="TZe-z9-MZS"/>
<constraint firstItem="jHc-GP-v1Z" firstAttribute="centerY" secondItem="kh9-bI-dsS" secondAttribute="centerY" id="VOe-WJ-FKo"/>
<constraint firstItem="jHc-GP-v1Z" firstAttribute="centerX" secondItem="kh9-bI-dsS" secondAttribute="centerX" id="XkT-zr-eUO"/>
<constraint firstAttribute="trailing" secondItem="o6f-cL-1PF" secondAttribute="trailing" constant="20" id="c74-nm-rgi"/>
<constraint firstAttribute="trailing" secondItem="RDW-bD-rSo" secondAttribute="trailing" constant="50" id="c7q-Rw-n0F"/>
<constraint firstItem="RDW-bD-rSo" firstAttribute="leading" secondItem="kh9-bI-dsS" secondAttribute="leading" constant="50" id="iXO-hP-XZ7"/>
</constraints>
</view>
<connections>
<outlet property="label" destination="o6f-cL-1PF" id="KQV-3X-RKr"/>
<outlet property="spinner" destination="jHc-GP-v1Z" id="gRn-JW-FIK"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="x5A-6p-PRh" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>

View File

@ -0,0 +1,48 @@
{
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "29x29",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "40x40",
"scale" : "3x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "2x"
},
{
"idiom" : "iphone",
"size" : "60x60",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>ReCaptchaKey</key>
<string>6LdE-hkUAAAAAKWfpXjXrsLMwDc0psCcjvpBgGr6</string>
<key>ReCaptchaDomain</key>
<string>http://localhost</string>
<key>LSApplicationCategoryType</key>
<string></string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
</array>
</dict>
</plist>

View File

@ -0,0 +1,46 @@
//
// ViewController.swift
// ReCaptcha
//
// Created by fjcaetano on 03/22/2017.
// Copyright (c) 2017 fjcaetano. All rights reserved.
//
import UIKit
import ReCaptcha
import Result
class ViewController: UIViewController {
fileprivate static let webViewTag = 123
fileprivate let recaptcha = try! ReCaptcha()
@IBOutlet weak var label: UILabel!
@IBOutlet weak var spinner: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
recaptcha.presenterView = view
recaptcha.configureWebView { [weak self] webview in
webview.frame = self?.view.bounds ?? CGRect.zero
webview.tag = ViewController.webViewTag
}
}
@IBAction func didPressButton(button: UIButton) {
spinner.startAnimating()
button.isEnabled = false
recaptcha.validate { [weak self] result in
self?.spinner.stopAnimating()
self?.label.text = try? result.dematerialize()
self?.view.viewWithTag(ViewController.webViewTag)?.removeFromSuperview()
}
}
}

24
Example/Tests/Info.plist Normal file
View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

29
Example/Tests/Tests.swift Normal file
View File

@ -0,0 +1,29 @@
import UIKit
import XCTest
import ReCaptcha
class 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 testExample() {
// This is an example of a functional test case.
XCTAssert(true, "Pass")
}
func testPerformanceExample() {
// This is an example of a performance test case.
self.measure() {
// Put the code you want to measure the time of here.
}
}
}

12
LICENSE
View File

@ -1,6 +1,4 @@
MIT License
Copyright (c) 2017 Flávio Caetano
Copyright (c) 2017 Flávio Caetano <flavio@vieiracaetano.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -9,13 +7,13 @@ 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 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.
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -1,2 +1,52 @@
# ReCaptcha
[In]visible ReCaptcha for iOS
[![CI Status](http://img.shields.io/travis/fjcaetano/ReCaptcha.svg?style=flat)](https://travis-ci.org/fjcaetano/ReCaptcha)
[![Version](https://img.shields.io/cocoapods/v/ReCaptcha.svg?style=flat)](http://cocoapods.org/pods/ReCaptcha)
[![License](https://img.shields.io/cocoapods/l/ReCaptcha.svg?style=flat)](http://cocoapods.org/pods/ReCaptcha)
[![Platform](https://img.shields.io/cocoapods/p/ReCaptcha.svg?style=flat)](http://cocoapods.org/pods/ReCaptcha)
-----
Add Google's [Invisible ReCaptcha](https://developers.google.com/recaptcha/docs/invisible) to your project. This library
automatically handles ReCaptcha's events and retrieves the validation token or notifies you to present the challenge if
invisibility is not possible.
## Installation
ReCaptcha is available through [CocoaPods](http://cocoapods.org). To install it, simply add the following line to your
Podfile:
``` ruby
pod "ReCaptcha"
```
## Usage
Simply add `ReCaptchaKey` and `ReCaptchaDomain` to your Info.plist and run:
``` swift
override func viewDidLoad() {
super.viewDidLoad()
recaptcha.presenterView = view
recaptcha.configureWebView { [weak self] webview in
webview.frame = self?.view.bounds ?? CGRect.zero
webview.tag = ViewController.webViewTag
}
}
func validate() {
recaptcha.validate { [weak self] result in
dprint(try? result.dematerialize())
}
}
```
## Author
Flávio Caetano, flavio@vieiracaetano.com
## License
ReCaptcha is available under the MIT license. See the LICENSE file for more info.

42
ReCaptcha.podspec Normal file
View File

@ -0,0 +1,42 @@
#
# Be sure to run `pod lib lint ReCaptcha.podspec' to ensure this is a
# valid spec before submitting.
#
# Any lines starting with a # are optional, but their use is encouraged
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
#
Pod::Spec.new do |s|
s.name = 'ReCaptcha'
s.version = '0.1.0'
s.summary = 'ReCaptcha for iOS'
# This description is used to generate tags and improve search results.
# * Think: What does it do? Why did you write it? What is the focus?
# * Try to keep it short, snappy and to the point.
# * Write the description between the DESC delimiters below.
# * Finally, don't worry about the indent, CocoaPods strips it!
s.description = <<-DESC
Add Google invisible ReCaptcha to your app
DESC
s.homepage = 'https://github.com/fjcaetano/ReCaptcha'
# s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'fjcaetano' => 'flavio@vieiracaetano.com' }
s.source = { :git => 'https://github.com/fjcaetano/ReCaptcha.git', :tag => s.version.to_s }
s.social_media_url = 'https://twitter.com/flavio_caetano'
s.ios.deployment_target = '8.0'
s.source_files = 'ReCaptcha/Classes/**/*'
# s.resource_bundles = {
# 'ReCaptcha' => ['ReCaptcha/Assets/*']
# }
# s.public_header_files = 'Pod/Classes/**/*.h'
s.frameworks = 'WebKit'
s.dependency 'Result', '~> 3.0'
end

View File

View File

@ -0,0 +1,40 @@
<html>
<head>
<meta name="viewport" content="width=device-width" />
<script type="text/javascript">
var observeDOM = function(element, completion) {
new MutationObserver(function(mutations) {
mutations.forEach(function(mutationRecord) {
completion();
});
})
.observe(element, {attributes: true, attributeFilter: ['style']})
};
var execute = function() {
observeDOM(document.getElementsByTagName("div")[3], function() {
window.webkit.messageHandlers.recaptcha.postMessage({action: "showReCaptcha"});
});
grecaptcha.execute();
}
var onSubmit = function(token) {
console.log(token);
window.webkit.messageHandlers.recaptcha.postMessage({token: token});
};
var onloadCallback = function() {
grecaptcha.render('submit', {
'sitekey' : '%@',
'callback' : onSubmit,
'size': 'invisible'
});
};
</script>
</head>
<body>
<span id="submit" style="visibility: hidden;"></span>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
</body>
</html>

View File

View File

@ -0,0 +1,31 @@
//
// NSError+ReCaptcha.swift
// Pods
//
// Created by Flávio Caetano on 22/03/17.
//
//
import Foundation
fileprivate let kErrorDomain = "com.flaviocaetano.ReCaptcha"
extension NSError {
enum Code: Int {
case undefined
case htmlLoadError
case apiKeyNotFound
case baseURLNotFound
case wrongMessageFormat
}
var rc_code: Code? {
return Code(rawValue: code)
}
convenience init(code: Code, userInfo: [AnyHashable: Any]? = nil) {
self.init(domain: kErrorDomain, code: code.rawValue, userInfo: userInfo)
}
}

View File

@ -0,0 +1,40 @@
//
// ReCaptcha.swift
// Pods
//
// Created by Flávio Caetano on 22/03/17.
//
//
import Foundation
import WebKit
open class ReCaptcha: ReCaptchaWebViewManager {
fileprivate struct Constants {
struct InfoDictKeys {
static let APIKey = "ReCaptchaKey"
static let Domain = "ReCaptchaDomain"
}
}
public init(apiKey: String? = nil, baseURL: URL? = nil) throws {
guard let filePath = Bundle(for: ReCaptcha.self).path(forResource: "recaptcha", ofType: "html") else {
throw NSError(code: .htmlLoadError)
}
// Fetches from info.plist
let infoDict = Bundle.main.infoDictionary
guard let apiKey = apiKey ?? (infoDict?[Constants.InfoDictKeys.APIKey] as? String) else {
throw NSError(code: .apiKeyNotFound)
}
guard let domain = infoDict?[Constants.InfoDictKeys.Domain] as? String, let baseURL = baseURL ?? URL(string: domain) else {
throw NSError(code: .baseURLNotFound)
}
let rawHTML = try String(contentsOfFile: filePath)
super.init(html: String(format: rawHTML, apiKey), apiKey: apiKey, baseURL: baseURL)
}
}

View File

@ -0,0 +1,60 @@
//
// ReCaptchaDecoder.swift
// Pods
//
// Created by Flávio Caetano on 22/03/17.
//
//
import Foundation
import WebKit
class ReCaptchaDecoder: NSObject {
enum Result {
case token(String)
case showReCaptcha
case error(NSError)
}
fileprivate let sendMessage: ((Result) -> Void)
init(didReceiveMessage: @escaping (Result) -> Void) {
sendMessage = didReceiveMessage
super.init()
}
func send(error: NSError) {
sendMessage(.error(error))
}
}
// MARK: Script Handler
extension ReCaptchaDecoder: WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
guard let dict = message.body as? [String: Any] else {
return sendMessage(.error(NSError(code: .wrongMessageFormat)))
}
sendMessage(Result.from(response: dict))
}
}
// MARK: - Result
fileprivate extension ReCaptchaDecoder.Result {
static func from(response: [String: Any]) -> ReCaptchaDecoder.Result {
if let token = response["token"] as? String {
return .token(token)
}
if let action = response["action"] as? String, action == "showReCaptcha" {
return .showReCaptcha
}
return .error(NSError(code: .undefined))
}
}

View File

@ -0,0 +1,120 @@
//
// ReCaptchaWebViewManager.swift
// Pods
//
// Created by Flávio Caetano on 22/03/17.
//
//
import Foundation
import WebKit
import Result
open class ReCaptchaWebViewManager: NSObject {
public typealias Response = Result<String, NSError>
fileprivate struct Constants {
static let ExecuteJSCommand = "execute();"
}
open weak var presenterView: UIView?
fileprivate var completion: ((Response) -> Void)?
fileprivate var configureWebView: ((WKWebView) -> Void)?
fileprivate var decoder: ReCaptchaDecoder!
fileprivate var didFinishLoading = false // webView.isLoading does not work in this case
fileprivate lazy var webView: WKWebView = {
let webview = WKWebView(frame: CGRect.zero, configuration: self.buildConfiguration())
webview.navigationDelegate = self
return webview
}()
init(html: String, apiKey: String, baseURL: URL) {
super.init()
decoder = ReCaptchaDecoder { [weak self] result in
self?.handle(result: result)
}
webView.loadHTMLString(String(format: html, apiKey), baseURL: baseURL)
}
open func validate(completion: @escaping (Response) -> Void) {
self.completion = completion
execute()
}
open func stop() {
webView.stopLoading()
}
open func configureWebView(_ configure: @escaping (WKWebView) -> Void) {
self.configureWebView = configure
}
}
// MARK: - Navigation
extension ReCaptchaWebViewManager: WKNavigationDelegate {
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
didFinishLoading = true
presenterView?.addSubview(webView)
if completion != nil {
// User has requested for validation
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.execute()
}
}
}
}
// MARK: - Private Methods
fileprivate extension ReCaptchaWebViewManager {
func execute() {
guard didFinishLoading else {
// Hasn't finished loading the HTML yet
return
}
webView.evaluateJavaScript(Constants.ExecuteJSCommand) { [weak self] result, error in
if let error = error {
self?.decoder.send(error: error as NSError)
}
}
}
func buildConfiguration() -> WKWebViewConfiguration {
let controller = WKUserContentController()
controller.add(decoder, name: "recaptcha")
let conf = WKWebViewConfiguration()
conf.userContentController = controller
return conf
}
func handle(result: ReCaptchaDecoder.Result) {
switch result {
case .token(let token):
completion?(Response.success(token))
case .error(let error):
completion?(Response.failure(error))
case .showReCaptcha:
configureWebView?(webView)
}
}
}

1
_Pods.xcodeproj Symbolic link
View File

@ -0,0 +1 @@
Example/Pods/Pods.xcodeproj