iOS SDK
Add Crovly captcha to native iOS apps with Swift and SwiftUI. WKWebView integration with async/await token retrieval.
Installation
Swift Package Manager
Add the package in Xcode: File > Add Package Dependencies, then enter:
https://github.com/crovly/iosOr add to your Package.swift:
dependencies: [
.package(url: "https://github.com/crovly/ios", from: "1.0.0")
]CocoaPods
pod 'CrovlyCaptcha', '~> 1.0'Get your site key at app.crovly.com.
SwiftUI
import SwiftUI
import CrovlyCaptcha
struct LoginView: View {
@State private var token: String?
var body: some View {
VStack(spacing: 16) {
TextField("Email", text: .constant(""))
SecureField("Password", text: .constant(""))
CrovlyCaptchaRepresentable(
configuration: CrovlyConfiguration(siteKey: "YOUR_SITE_KEY"),
onVerify: { token in self.token = token },
onError: { error in print("Error:", error) },
onExpire: { self.token = nil }
)
.frame(height: 80)
Button("Sign In") {
handleLogin()
}
.disabled(token == nil)
}
.padding()
}
}UIKit
import UIKit
import CrovlyCaptcha
class LoginViewController: UIViewController, CrovlyDelegate {
private var token: String?
override func viewDidLoad() {
super.viewDidLoad()
let config = CrovlyConfiguration(
siteKey: "YOUR_SITE_KEY",
theme: .auto,
size: .normal
)
let captchaView = CrovlyCaptchaView(configuration: config)
captchaView.delegate = self
captchaView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(captchaView)
NSLayoutConstraint.activate([
captchaView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
captchaView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
captchaView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
captchaView.heightAnchor.constraint(equalToConstant: 80),
])
}
// MARK: - CrovlyDelegate
func crovlyDidVerify(token: String) {
self.token = token
submitButton.isEnabled = true
}
func crovlyDidError(error: String) {
print("Captcha error:", error)
}
func crovlyDidExpire() {
self.token = nil
submitButton.isEnabled = false
}
}Configuration
let config = CrovlyConfiguration(
siteKey: "YOUR_SITE_KEY",
theme: .dark, // .light, .dark, or .auto
size: .normal, // .normal or .invisible
lang: "tr", // nil for auto-detect
apiUrl: "https://get.crovly.com"
)| Parameter | Type | Default | Description |
|---|---|---|---|
siteKey | String | — | Your public site key (required) |
theme | CrovlyTheme | .auto | Widget theme |
size | CrovlySize | .normal | Widget size mode |
lang | String? | Auto-detect | Language code |
apiUrl | String | https://get.crovly.com | Widget script CDN |
Modal Presentation
Use CrovlyCaptchaViewController to present the captcha as a sheet:
let config = CrovlyConfiguration(siteKey: "YOUR_SITE_KEY")
let captchaVC = CrovlyCaptchaViewController(configuration: config)
captchaVC.delegate = self
captchaVC.dismissOnVerify = true // Auto-dismiss after verification
present(captchaVC, animated: true)On iOS 15+, it automatically uses .medium() sheet detent for a compact presentation.
Delegate Protocol
protocol CrovlyDelegate: AnyObject {
func crovlyDidVerify(token: String) // Required
func crovlyDidError(error: String) // Optional
func crovlyDidExpire() // Optional
}Methods
| Method | Description |
|---|---|
reset() | Reset the widget for a new verification |
Backend Verification
After getting the token, verify it on your server using any of the server-side SDKs:
// On your backend (e.g. Vapor)
let body = ["token": token, "expectedIp": clientIP]
let response = try await client.post("https://api.crovly.com/verify-token") { req in
req.headers.bearerAuthorization = .init(token: secretKey)
try req.content.encode(body)
}Requirements
- iOS 14.0+
- Swift 5.7+
- Xcode 14+