Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: split documentation per Examples #172

Merged
merged 3 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 43 additions & 39 deletions Example/HCaptcha.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1320"
LastUpgradeVersion = "1600"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "E6A23A382CEA6D480071D531"
BuildableName = "HCaptacha_PassiveExample.app"
BlueprintName = "HCaptacha_PassiveExample"
BuildableName = "HCaptcha_PassiveExample.app"
BlueprintName = "HCaptcha_PassiveExample"
ReferencedContainer = "container:HCaptcha.xcodeproj">
</BuildableReference>
</BuildActionEntry>
Expand Down Expand Up @@ -45,8 +45,8 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "E6A23A382CEA6D480071D531"
BuildableName = "HCaptacha_PassiveExample.app"
BlueprintName = "HCaptacha_PassiveExample"
BuildableName = "HCaptcha_PassiveExample.app"
BlueprintName = "HCaptcha_PassiveExample"
ReferencedContainer = "container:HCaptcha.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
Expand All @@ -62,8 +62,8 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "E6A23A382CEA6D480071D531"
BuildableName = "HCaptacha_PassiveExample.app"
BlueprintName = "HCaptacha_PassiveExample"
BuildableName = "HCaptcha_PassiveExample.app"
BlueprintName = "HCaptcha_PassiveExample"
ReferencedContainer = "container:HCaptcha.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1340"
LastUpgradeVersion = "1600"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
shouldUseLaunchSchemeArgsEnv = "YES">
<TestPlans>
<TestPlanReference
reference = "container:HCaptcha_Tests/HCaptcha_Tests.xctestplan">
reference = "container:HCaptcha_Tests/HCaptcha_Tests.xctestplan"
default = "YES">
</TestPlanReference>
</TestPlans>
<Testables>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1150"
LastUpgradeVersion = "1600"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
17 changes: 17 additions & 0 deletions Example/ObjC-Example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## Objective-C Example

Make sure [installation is complete](../../README.md#installation) and [pre-requisites are met](../../README.md#installation)

`HCaptcha` exposes its API to real native code, so it can be used from `Objective-C`.

Because `HCaptcha` is a pure Swift library, it exposes its API through the `@objc` attribute.

The `@objc` attribute makes Swift methods, properties, and classes available to Objective-C code. By marking a Swift method or class with `@objc`, it is automatically bridged to Objective-C, allowing for interoperability between Swift and Objective-C.

Also because `Objective-C` doesn't support optional arguments, the most popular constructors of `HCaptcha` are available in `Objective-C`

The full code is in [ViewController.m](./ViewController.m).

----

[Back to the main README](../../README.md)
13 changes: 13 additions & 0 deletions Example/Passive-Example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
## Passive ApiKey Example

Make sure [installation is complete](../../README.md#installation) and [pre-requisites are met](../../README.md#installation)

HCaptcha Enterprise supports verification with no interaction from the user: [Passive Site Keys](https://docs.hcaptcha.com/faq#what-are-the-difficulty-levels-for-the-challenges-and-how-are-they-selected).

Using the `passiveApiKey` option with Passive sitekeys provides performance improvements in SDK token generation time, at the cost of less flexibility if you want to change the sitekey mode in the future without a code update.

The full code is in [Example](./ContentView.swift).

----

[Back to the main README](../../README.md)
63 changes: 63 additions & 0 deletions Example/RxSwift-Example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
## RxSwift Example

Once [installation is complete](../../README.md#installation) and [pre-requisites are met](../../README.md#installation), we are ready to proceed with the actual implementation:

``` swift
var hcaptcha: HCaptcha!

// ...

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:

```swift
...
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)
```

The full code is in [`ViewController.swift`](./ViewController.swift)

### SDK Events

This SDK allows you to receive [interaction events](../../README.md#sdk-events). This is how it can be implemented:

For `RxSwift`:

```swift
let hcaptcha = try? HCaptcha(...)
...
hcaptcha.rx.events()
.subscribe { [weak self] rxevent in
let event = rxevent.element?.0

if event == .open {
...
}
}
...
```

----

[Back to the main README](../../README.md)
10 changes: 10 additions & 0 deletions Example/SwiftUI-Example/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?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>HCaptchaDomain</key>
<string>http://localhost</string>
<key>HCaptchaKey</key>
<string>a5f74b19-9e45-40e0-b45d-47ff91b7a6c2</string>
</dict>
</plist>
13 changes: 13 additions & 0 deletions Example/SwiftUI-Example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
### SwiftUI Example

Once [installation is complete](../../README.md#installation) and [pre-requisites are met](../../README.md#installation), we are ready to proceed with the actual implementation:

While `HCaptcha` was originally designed for UIKit, you can easily use it with `SwiftUI` as well. Check out the [SwiftUI Example](./ContentView.swift).

To integrate `UIKit` components into a `SwiftUI` project, you can use `UIViewRepresentable`. This protocol allows you to wrap a `UIKit` view and make it compatible with `SwiftUI`.

For example, to use a `HCaptcha` component (originally designed to show over `UIKit` views) in `SwiftUI`, you would create a `UIViewRepresentable` that provides a "placeholder" view for the `HCaptcha` to be used as host view to add `WKWebView`.

----

[Back to the main README](../../README.md)
116 changes: 116 additions & 0 deletions Example/UIKit-Example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
## UIKit Example

Once [installation is complete](../../README.md#installation) and [pre-requisites are met](../../README.md#installation), we are ready to proceed with the actual implementation:

``` swift
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**: caller code is responsible for hiding the `WebView` after challenge processing. This is illustrated in the Example app, and can be achieved with:

```swift
...
var captchaWebView: WKWebView?
...

hcaptcha?.configureWebView { [weak self] webview in
self?.captchaWebView = webview
}
...

hcaptcha.validate(on: view) { result in
...

captchaWebView?.removeFromSuperview()
}

```

The full code is in [`ViewContoller.swift`](./ViewContoller.swift)

## Show `hCaptcha` above `UIVisualEffectView`

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](https://github.com/hCaptcha/HCaptcha-ios-sdk/issues/50).

## Change hCaptcha frame

If you are customizing display beyond the defaults and need to resize or change the hCaptcha layout, for example after a visual challenge appears, you can use the following approach to trigger a redraw of the view:

``` swift
let hcaptcha = try? HCaptcha(...)
var visualChallengeShown = false
...
hcaptcha?.configureWebView { [weak self] webview in
webview.tag = "hCaptchaViewTag"
if visualChallengeShown {
let padding = 10
webview.frame = CGRect(
x: padding,
y: padding,
width: view.frame.size.width - 2 * padding,
height: targetHeight - 2 * padding
)
} else {
webview.frame = self?.view.bounds ?? CGRect.zero
}
}
...
hcaptcha.onEvent { (event, data) in
if event == .open {
visualChallengeShown = true
hcaptcha.redrawView()
} else if event == .error {
let error = data as? HCaptchaError
print("onEvent error: \(String(describing: error))")
...
}
}
...
hcaptcha.validate(on: view, resetOnError: false) { result in
visualChallengeShown = false
}
```

## SDK Events

This SDK allows you to receive [interaction events](../../README.md#sdk-events). This is how it can be implemented:

``` swift
let hcaptcha = try? HCaptcha(...)

// ...

hcaptcha.onEvent { (event, data) in
if event == .open {
...
} else if event == .error {
let error = data as? HCaptchaError
print("onEvent error: \(String(describing: error))")
...
}
}
```

----

[Back to the main README](../../README.md)
Loading
Loading