Skip to content

dodobrands/HCaptcha-ios-sdk

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

85 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HCaptcha

Carthage compatible Version Platform Swift Package Manager compatible


Add hCaptcha to your project. This library automatically handles hCaptcha's events and returns a validation token, presenting the challenge via a modal if needed.

Warning ⚠️

To secure your application, you need to send the token received here to your backend for server-side validation via the api.hcaptcha.com/siteverify endpoint.

Installation

HCaptcha is available through CocoaPods and packaged for Carthage and SPM (Swift Package Manager).

To install it, simply add the following line to your dependencies file:

Cocoapods

pod "HCaptcha"
# or
pod "HCaptcha/RxSwift"

Carthage

github "hCaptcha/HCaptcha-ios-sdk"

Carthage will create two different frameworks named HCaptcha and HCaptcha_RxSwift, the latter containing the RxSwift extension for the HCaptcha framework.

Known issues:

SPM

Standard SPM formula: uses Package.swift

Usage

hCaptcha sitekeys can be specified as Info.plist keys or can be passed as parameters when instantiating HCaptcha().

For the Info.plist configuration, add HCaptchaKey (sitekey) and HCaptchaDomain (with a protocol, i.e. https://) to your Info.plist.

  • HCaptchaKey is your hCaptcha sitekey.
  • HCaptchaDomain should be a string like https://www.your.com
  • baseURL should match HCaptchaDomain if specified; it controls the URI used to initialize the hCaptcha session. Example: https://www.your.com

With these values set, run:

let hcaptcha = try? HCaptcha()

override func viewDidLoad() {
    super.viewDidLoad()

    hcaptcha?.configureWebView { [weak self] webview in
        webview.frame = self?.view.bounds ?? CGRect.zero
    }
}


func validate() {
    hcaptcha?.validate(on: view) { [weak self] (result: HCaptchaResult) in
        print(try? result.dematerialize())
    }
}

Note: in case you need to show hCaptcha above UIVisualEffectView make sure to pass visualEffectView.contentView instead visualEffectView. Per Apple's documentation:

After you add the visual effect view to the view hierarchy, add any subviews to the contentView property of the visual effect view. Do not add subviews directly to the visual effect view itself.

More details here.

If you prefer to keep the information out of the Info.plist, you can instead use:

let hcaptcha = try? HCaptcha(
    apiKey: "YOUR_HCAPTCHA_KEY", 
    baseURL: URL(string: "YOUR_HCAPTCHA_DOMAIN")!
)

...

You can also install the reactive subpod and use it with RxSwift:

hcaptcha.rx.validate(on: view)
    .subscribe(onNext: { (token: String) in
        // Do something
    })

Note: caller code is responsible for hiding the WebView after challenge processing. This is illustrated in the Example app, and can be achieved with:

  1. Regular Swift API:

    ...
    var captchaWebView: WKWebView?
    ...
    
    hcaptcha?.configureWebView { [weak self] webview in
        self?.captchaWebView = webview
    }
    ...
    
    hcaptcha.validate(on: view) { result in
        ...
    
        captchaWebView?.removeFromSuperview()
    }
  2. RxSwift API (check the example for more details):

    ...
    hcaptcha?.configureWebView { [weak self] webview in
        webview.tag = "hCaptchaViewTag"
    }
    ...
    
    let disposeBag = DisposeBag()
    let validate = hcaptcha.rx.validate(on: view)
    ...
    
    validate
        .map { [weak self] _ in
            self?.view.viewWithTag("hCaptchaViewTag")
        }
        .subscribe(onNext: { webview in
            webview?.removeFromSuperview()
        })
        .disposed(by: disposeBag)

Setting the host override (optional)

Since this SDK uses a local HTML file, you may want to set a host override for better tracking and enforcement of siteverify parameters.

You can achieve this by passing the extra param host:

let hcaptcha = try? HCaptcha(
    ...
    host: "your-domain.com",
    ...
)

...

Note: this should be the bare host, i.e. not including a protocol prefix like https://.

Change widget theme

The SDK supports three built-in themes: light, dark, and contrast

let hcaptcha = try? HCaptcha(
    ...
    theme: "dark", // "light" or "contrast"
    ...
)

...

For Enterprise sitekeys we also support custom themes via the customTheme parameter, described below.

Alternate endpoint (optional)

If you are an Enterprise user with first-party hosting access, you can use your own endpoint (i.e. verify.your.com).

You can then enable it in your code:

let hcaptcha = try? HCaptcha(
    ...
    endpoint: URL("https://custom.endpoint")!,
    ...
)

...

More params for Enterprise (optional)

Enterprise params like:

  • rqdata (string)
  • reportapi (string)
  • assethost (string)
  • imghost (string)
  • sentry (bool)
  • customTheme (string representation of JS Object or JSON; see Enterprise docs)

Can be passed via HCaptcha(...)

Please see the hCaptcha Enterprise documentation for more details.

Enabling the visible checkbox flow

This iOS SDK assumes by default that you want an "invisible" checkbox, i.e. that triggering the hCaptcha flow from within your app should either return a token or show the user a challenge directly.

If you instead want the classic "normal" or "compact" checkbox behavior of showing a checkbox to tick and then either closing or showing a challenge, you can pass size to the HCaptcha initializer.

let hcaptcha = try? HCaptcha(size: .compact)

And you will now get the desired behavior.

SwiftUI Example

HCaptcha was originally designed to be used with UIKit. But you can easily use it with SwiftUI as well.

import SwiftUI
import HCaptcha

// Wrapper-view to provide UIView instance
struct UIViewWrapperView : UIViewRepresentable {
    var uiview = UIView()

    func makeUIView(context: Context) -> UIView {
        return uiview
    }

    func updateUIView(_ view: UIView, context: Context) {
    }
}

// Example of hCaptcha usage
struct HCaptchaView: View {
    private(set) var hcaptcha: HCaptcha!

    let placeholder = UIViewWrapperView()

    var body: some View {
        VStack{
            placeholder.frame(width: 400, height: 400, alignment: .center)
            Button(
                "validate",
                action: {
                    hcaptcha.validate(on: placeholder.uiview) { result in
                        print(result)
                    }
                }
            ).padding()
        }
    }


    init() {
        hcaptcha = try! HCaptcha()
        let hostView = self.placeholder.uiview
        hcaptcha.configureWebView { webview in
            webview.frame = hostView.bounds
        }
    }
}

...

Objective-C Example

HCaptcha can be used from Objective-C code. Check out the Example Project

License

HCaptcha is available under the MIT license. See the LICENSE file for more info.

Troubleshooting

Q. I'm getting a "Could not load embedded HTML" exception. What does it mean? A. Most likely you have not included an asset in your build. Please double-check this, and see the example app for more details.

Q. I'm getting "xcconfig: unable to open file" after upgrading the SDK. (Or changing SDK and running Example app.) A: In your app or the Example app dir, run pod deintegrate && pod install to refresh paths.

Inspiration

Originally forked from fjcaetano's ReCaptcha IOS SDK, licensed under MIT.

About

HCaptcha SDK for iOS (Preview)

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Swift 82.4%
  • HTML 6.7%
  • Ruby 6.6%
  • Objective-C 3.3%
  • Shell 1.0%