Skip to content

Instantly share code, notes, and snippets.

@jkereako
Created September 8, 2020 13:15
Show Gist options
  • Save jkereako/d111ff6f4594873d409d3194371d6732 to your computer and use it in GitHub Desktop.
Save jkereako/d111ff6f4594873d409d3194371d6732 to your computer and use it in GitHub Desktop.
ReCAPTCHA v2 in Swift
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="https://www.google.com/recaptcha/api.js?onload=onLoad&render=explicit&hl=en" async defer></script>
<title></title>
<script type="text/javascript">
const post = function(value) {
window.webkit.messageHandlers.recaptcha.postMessage(value);
};
console.log = function(message) {
post(message);
};
var onLoad = function() {
grecaptcha.render(
"recaptcha",
{
sitekey: "${siteKey}",
callback: function(token) {
post(token);
},
size: "normal"
}
);
};
</script>
</head>
<body>
<div id="recaptcha"></div>
</body>
</html>
import UIKit
import WebKit
final class ReCAPTCHAViewController: UIViewController {
private var webView: WKWebView!
private let viewModel: ReCAPTCHAViewModel
init(viewModel: ReCAPTCHAViewModel) {
self.viewModel = viewModel
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func loadView() {
let webConfiguration = WKWebViewConfiguration()
let contentController = WKUserContentController()
contentController.add(viewModel, name: "recaptcha")
webConfiguration.userContentController = contentController
webView = WKWebView(frame: .zero, configuration: webConfiguration)
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.leftBarButtonItem = UIBarButtonItem(
barButtonSystemItem: .close,
target: self,
action: #selector(didSelectCloseButton)
)
webView.loadHTMLString(viewModel.html, baseURL: viewModel.url)
}
}
// MARK: - Target-Actions
private extension ReCAPTCHAViewController {
@IBAction func didSelectCloseButton() {
dismiss(animated: true)
}
}
import WebKit
protocol ReCAPTCHAViewModelDelegate: class {
func didSolveCAPTCHA(token: String)
}
final class ReCAPTCHAViewModel: NSObject {
weak var delegate: ReCAPTCHAViewModelDelegate?
var html: String {
guard let filePath = Bundle.main.path(
forResource: "recaptcha", ofType: "html"
) else {
assertionFailure("Unable to find the file.")
return ""
}
let contents = try! String(
contentsOfFile: filePath, encoding: .utf8
)
return parse(contents, with: ["siteKey": siteKey])
}
let siteKey: String
let url: URL
/// Creates a ReCAPTCHAViewModel
/// - Parameters:
/// - siteKey: ReCAPTCHA's site key
/// - url: The URL for registered with Google
init(siteKey: String, url: URL) {
self.siteKey = siteKey
self.url = url
super.init()
}
}
// MARK: - WKScriptMessageHandler
extension ReCAPTCHAViewModel: WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController,
didReceive message: WKScriptMessage) {
guard let message = message.body as? String else {
assertionFailure("Expected a string")
return
}
delegate?.didSolveCAPTCHA(token: message)
}
}
private extension ReCAPTCHAViewModel {
func parse(_ string: String, with valueMap: [String: String]) -> String {
var parsedString = string
valueMap.forEach { key, value in
parsedString = parsedString.replacingOccurrences(
of: "${\(key)}", with: value
)
}
return parsedString
}
}
@sofent
Copy link

sofent commented Apr 25, 2022

thanks it work fine in my case,but it show retapcha code everytime while access via web did not completely invisibe. any suggestion why?

@CodeWithOz
Copy link

@dittmar @jkereako hey folks do you know if it's possible to make this usable in a cordova/ionic app? I'm not familiar with native development so I'm not sure what the necessary steps would be if it's possible.

@michzio
Copy link

michzio commented Mar 13, 2023

What is the reason to not use reCAPTCHA Enterprise ? there is the same limit as I can see 1,000,000 views per month?

@shanmugam105
Copy link

I think need iOS Target 14.x for reCAPTCHA Enterprise

@ZaynaxiOSDev
Copy link

How can I Observe Expired Sessions?

@shanmugam105
Copy link

shanmugam105 commented May 18, 2023

@ZaynaxiOSDev

https://www.google.com/recaptcha/api/siteverify?secret=your_secret&response=response_token

Use this GET api for timeout status validation. Replace your_secret & response_token

@ZaynaxiOSDev
Copy link

Is this possible to generate a delegate method like didSolveCAPTCHA?

If yes, then how can I achieve that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment