iOS nativo (Swift)
Integre o FaceGuard em aplicações iOS nativas usando WKWebView.
Configuração
Adicione NSCameraUsageDescription ao seu Info.plist:
Info.plist
<key>NSCameraUsageDescription</key>
<string>O FaceGuard precisa de acesso à câmara para verificação facial</string>
Implementação
FaceGuardViewController.swift
import WebKit
class FaceGuardViewController: UIViewController, WKScriptMessageHandler {
private var webView: WKWebView!
func startVerification(token: String) {
let config = WKWebViewConfiguration()
config.allowsInlineMediaPlayback = true
config.mediaTypesRequiringUserActionForPlayback = []
// Ouvir eventos postMessage
config.userContentController.add(self, name: "surtHandler")
// Injetar bridge: reencaminhar postMessage para o handler nativo
let script = WKUserScript(
source: """
window.addEventListener('message', function(e) {
if (e.data && (e.data.type === 'surt:ready' || e.data.action === 'close')) {
window.webkit.messageHandlers.surtHandler.postMessage(JSON.stringify(e.data));
}
});
""",
injectionTime: .atDocumentStart,
forMainFrameOnly: false
)
config.userContentController.addUserScript(script)
webView = WKWebView(frame: view.bounds, configuration: config)
webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(webView)
let url = URL(string: "https://faceguard.surt.com/intro?token=\(token)")!
webView.load(URLRequest(url: url))
}
func userContentController(
_ controller: WKUserContentController,
didReceive message: WKScriptMessage
) {
guard let body = message.body as? String,
let data = body.data(using: .utf8),
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any]
else { return }
if let action = json["action"] as? String, action == "close" {
let reason = json["reason"] as? String ?? ""
let confidence = json["confidence"] as? Double ?? 0
switch reason {
case "approved", "bypass_active":
handleApproved(confidence: confidence)
case "rejected":
handleRejected(confidence: confidence)
case "canceled":
handleCanceled()
case "error", "no_base_photo":
handleError(message: json["error"] as? String ?? reason)
default:
break
}
}
}
func handleApproved(confidence: Double) { /* Conceder acesso */ }
func handleRejected(confidence: Double) { /* Negar acesso */ }
func handleCanceled() { /* Utilizador fechou */ }
func handleError(message: String) { /* Mostrar erro */ }
}
Como funciona o bridge
O WKWebView não recebe nativamente eventos postMessage de iframes. O script JavaScript injetado escuta os eventos message e reencaminha-os para o WKScriptMessageHandler nativo via window.webkit.messageHandlers.
Áreas seguras
Use Auto Layout com safeAreaLayoutGuide para evitar o notch e o indicador de início.