本頁說明如何在 iOS 應用程式中整合 reCAPTCHA。
由於行動裝置的螢幕大小、效能和應用程式 UI 各有不同,因此 iOS 行動應用程式不支援視覺化核取方塊 reCAPTCHA 驗證問題 (「我不是機器人」)。您可以改為實作自己的分層強制執行策略,例如多重驗證流程,為可疑流量提供替代兌換路徑。
SDK 會使用反射和動態程式碼,在已部署的應用程式或 SDK 中更新及改良偵測系統。為避免干擾應用程式,系統中可用的類別集會限制在經過嚴格控管的清單中。
事前準備
將應用程式的最低 SDK 設為 iOS 12,或建立新的行動應用程式。
為 iOS 應用程式平台建立 reCAPTCHA 金鑰。
或者,您也可以執行下列其中一個步驟,複製現有 iOS reCAPTCHA 金鑰的 ID:
如要從 Google Cloud 控制台複製現有金鑰的 ID,請按照下列步驟操作:
前往 reCAPTCHA 頁面。
- 在 reCAPTCHA 金鑰清單中,將指標懸停在要複製的金鑰上,然後按一下 。
- 如要使用 REST API 複製現有金鑰的 ID,請使用 projects.keys.list 方法。
- 如要使用 gcloud CLI 複製現有金鑰的 ID,請使用 gcloud recaptcha keys list 指令。
擁有 GitHub 帳戶。
詳閱 Apple 隱私權詳細資料。
準備 iOS 環境
如要準備開發環境,請完成下列步驟:
下載並安裝最新版 Xcode,然後建立新的空白 iOS 單一檢視畫面應用程式。
使用下列其中一種方式下載 SDK:
CocoaPods
- 下載並安裝 CocoaPods。
建立 Podfile,並在 Podfile 中新增下列程式碼:
source "https://github.com/CocoaPods/Specs.git" target 'AppTarget' do # Podfiles must include use_frameworks! or # use_frameworks! :linkage => :static use_frameworks! pod "RecaptchaEnterprise", "18.8.0-beta01" ... end
執行
pod update
安裝必要的依附元件。
Swift Package Manager
- 在 Xcode 中,依序選取「File」>「Add Packages」,然後在「Search」或「Enter Package URL」欄位中輸入下列網址:
https://github.com/GoogleCloudPlatform/recaptcha-enterprise-mobile-sdk
在「Xcode」對話方塊中,輸入下列詳細資料:
- GitHub 使用者名稱。
- 使用 GitHub 的操作說明建立的個人存取權杖。「個人存取權杖」必須具有「XCode Sign In」對話方塊中列出的範圍。
Xcode 會安裝 SDK 和必要的依附元件。
Flutter
如需透過 Flutter 使用 reCAPTCHA 的詳細操作說明,請參閱 Flutter 說明文件。
ReactNative
如需透過 React Native 使用 reCAPTCHA 的詳細操作說明,請參閱 React Native 說明文件。
直接下載
如要以 xcframework 形式下載 SDK 和其依附元件,請下載用戶端。
設定應用程式
您可以使用 Swift 或 Objective-C 編寫應用程式。
如要設定應用程式,請在應用程式中新增下列檔案:
Swift
如果應用程式是以 Swift 編寫,請加入下列匯入項目:
import RecaptchaEnterprise
Objective-C
如果應用程式是以 Objective-C 編寫,請建立虛擬 Swift 檔案,並加入下列匯入項目,確保 Xcode 可以找到並連結 Swift 程式庫。
import Foundation
如要確保
Swift
程式碼已正確連結,請依序前往「Target」>「Build Settings」>「Always Embed Swift Standard Libraries」,並確認該選項已設為Yes
。
將 reCAPTCHA 整合至 iOS 應用程式
如要將 reCAPTCHA 整合至 iOS 應用程式,請在 Xcode 中按照下列步驟操作:
如要使用您建立的 reCAPTCHA 金鑰 (KEY_ID) 例項化 SDK,請使用下列程式碼更新應用程式:
使用分鏡腳本的 Swift
更新「
ViewController.swift
」。import RecaptchaEnterprise class ViewController: UIViewController { var recaptchaClient: RecaptchaClient? override func viewDidLoad() { super.viewDidLoad() Task { do { self.recaptchaClient = try await Recaptcha.fetchClient(withSiteKey: "KEY_ID") } catch let error as RecaptchaError { print("RecaptchaClient creation error: \(String(describing: error.errorMessage)).") } } } }
如果應用程式的最低 OS 版本低於 13,請改用尾隨閉包:
import RecaptchaEnterprise class ViewController: UIViewController { var recaptchaClient: RecaptchaClient? override func viewDidLoad() { super.viewDidLoad() Recaptcha.fetchClient(withSiteKey: "KEY_ID") { client, error in guard let client = client else { print("RecaptchaClient creation error: \(error).") return } self.recaptchaClient = client } } }
Swift 和 SwiftUI
建立
ViewModel
類別。import RecaptchaEnterprise @MainActor class ViewModel: ObservableObject { private var recaptchaClient: RecaptchaClient? init() { Task { do { self.recaptchaClient = try await Recaptcha.fetchClient(withSiteKey: "KEY_ID") } catch let error as RecaptchaError { print("RecaptchaClient creation error: \(String(describing: error.errorMessage)).") } } } }
如果應用程式的最低 OS 版本低於 13,請改用尾隨閉包:
import RecaptchaEnterprise class ViewController: UIViewController { var recaptchaClient: RecaptchaClient? override func viewDidLoad() { super.viewDidLoad() Recaptcha.fetchClient(withSiteKey: "KEY_ID") { client, error in guard let client = client else { print("RecaptchaClient creation error: \(error).") return } self.recaptchaClient = client } } }
在
ContentView.swift
中例項化ViewModel
。import SwiftUI import RecaptchaEnterprise struct ContentView: View { @StateObject private var viewModel = ViewModel() var body: some View { } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
Objective-C
更新「
ViewController.h
」。#import <RecaptchaEnterprise/RecaptchaEnterprise.h> @interface ViewController : UIViewController @property (strong, atomic) RecaptchaClient *recaptchaClient; @end
更新「
ViewController.m
」。@implementation ViewController [Recaptcha fetchClientWithSiteKey:@"KEY_ID" completion:^void(RecaptchaClient* recaptchaClient, NSError* error) { if (!recaptchaClient) { NSLog(@"%@", (RecaptchaError *)error.errorMessage); return; } self->_recaptchaClient = recaptchaClient; } ]; @end
SDK 初始化作業可能需要幾秒鐘才能完成。為減輕延遲問題,請盡可能提早初始化用戶端,例如在自訂
Application
類別的onCreate()
呼叫期間。您不應讓 UI 元素封鎖 reCAPTCHA SDK。建立按鈕來呼叫 reCAPTCHA 並觸發
execute()
。使用分鏡腳本的 Swift
- 在腳本中建立按鈕。
- 在
ViewController
中建立與您建立的按鈕相關聯的動作。 呼叫
execute()
方法並傳遞Login
動作,即可使用下列程式碼片段傳回 reCAPTCHA 權杖:guard let recaptchaClient = recaptchaClient else { print("RecaptchaClient creation failed.") return } Task { do { let token = try await recaptchaClient.execute(withAction: RecaptchaAction.login) print(token) } catch let error as RecaptchaError { print(error.errorMessage) } }
如果應用程式的最低 OS 版本低於 13,請改用尾隨閉包:
guard let recaptchaClient = recaptchaClient else { print("RecaptchaClient creation failed.") return } recaptchaClient.execute(withAction: RecaptchaAction.login) { token, error in if let token = token { print(token) } else { print(error) } }
Swift 和 SwiftUI
使用執行程式碼更新 ViewModel.swift:
import RecaptchaEnterprise @MainActor class ViewModel: ObservableObject { func execute() { guard let recaptchaClient = self.recaptchaClient else { print("Client not initialized correctly.") return } Task { do { let token = try await recaptchaClient.execute(withAction: RecaptchaAction.login) print(token) } catch let error as RecaptchaError { print(error.errorMessage) } } } }
如果應用程式的最低 OS 版本低於 13,請改用尾隨閉包:
guard let recaptchaClient = recaptchaClient else { print("RecaptchaClient creation failed.") return } recaptchaClient.execute(withAction: RecaptchaAction.login) { token, error in if let token = token { print(token) } else { print(error) } }
更新 ContentView.swift。
import SwiftUI import RecaptchaEnterprise struct ContentView: View { @StateObject private var viewModel = ViewModel() var body: some View { Button { viewModel.execute() } label: { Text("Execute") }.padding() Spacer() } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
Objective-C
- 在情節串連圖中建立按鈕。
- 在
ViewController
中建立與您建立的按鈕相關聯的動作。 呼叫
execute()
方法並傳遞Login
動作,以回傳 reCAPTCHA 權杖:if (!self->_recaptchaClient) { return; } [recaptchaClient execute:RecaptchaAction.login completion:^void(NSString* _Nullable token, NSError* _Nullable error) { if (!token) { NSLog (@"%@", (RecaptchaError *)error.errorMessage); return; } NSLog (@"%@", token); }];
用戶端的
execute
API 可能需要幾秒鐘才能完成,例如在網路速度緩慢的情況下,或是等待背景初始化完成時。請確保execute()
呼叫不會封鎖 UI 事件,例如按下按鈕。測試應用程式:
reCAPTCHA 會使用 Apple 的 App Attest 做為偵測引擎的一部分。如果您不打算在本地開發時使用測試金鑰和固定分數,請按照下列步驟操作:
在 Xcode 中,將 App Attest 功能新增至應用程式。
在專案的
.entitlements
檔案中,將 App Attest 環境設為production
。
如要清除 Xcode 建構環境,請依序點選「Product」選單中的「Clean Build Folder」。
如要執行應用程式,請在「Product」選單中點選「Run」。
在載入的應用程式中,按一下您先前建立的按鈕。
觀察偵錯輸出視窗中的 reCAPTCHA 權杖 (英數字串),如果整合成功,系統就會傳回這個權杖。
從方法 API 遷移至 fetchClient 方法
fetchClient
方法會傳回 RecaptchaClient,在網路連線失敗時重試初始化作業。如果建立用戶端時應用程式沒有網路存取權,用戶端會持續重試,並在取得網路時成功初始化。
如果您呼叫 execute(timeout)
,但用戶端尚未準備就緒,系統會先嘗試初始化,再傳回權杖或 RecaptchaErrorCode。
以下範例說明如何從 getClient
遷移至 fetchClient
。
使用分鏡腳本的 Swift
// Migrate from getClient
func initializeWithGetClient() {
Task {
do {
self.recaptchaClient = try await Recaptcha.getClient(withSiteKey: "KEY_ID")
} catch let error as RecaptchaError {
print("RecaptchaClient creation error: \(String(describing: error.errorMessage)).")
}
}
}
// Migrate to fetchClient
func initializeWithFetchClient() {
Task {
do {
self.recaptchaClient = try await Recaptcha.fetchClient(withSiteKey: "KEY_ID")
} catch let error as RecaptchaError {
print("RecaptchaClient creation error: \(String(describing: error.errorMessage)).")
}
}
}
如果應用程式的最低 OS 版本低於 13,請改用尾隨閉包:
// Migrate from getClient
override func initializeWithGetClient() {
Recaptcha.getClient(withSiteKey: "KEY_ID") { client, error in
guard let client = client else {
print("RecaptchaClient creation error: \(error).")
return
}
self.recaptchaClient = client
}
}
// Migrate to fetchClient
override func initializeWithFetchClient() {
Recaptcha.fetchClient(withSiteKey: "KEY_ID") { client, error in
guard let client = client else {
print("RecaptchaClient creation error: \(error).")
return
}
self.recaptchaClient = client
}
}
Swift 和 SwiftUI
// Migrate from getClient
initializeWithGetClient() {
Task {
do {
self.recaptchaClient = try await Recaptcha.getClient(withSiteKey: "KEY_ID")
} catch let error as RecaptchaError {
print("RecaptchaClient creation error: \(String(describing: error.errorMessage)).")
}
}
}
// Migrate to fetchClient
initializeWithFetchClient() {
Task {
do {
self.recaptchaClient = try await Recaptcha.fetchClient(withSiteKey: "KEY_ID")
} catch let error as RecaptchaError {
print("RecaptchaClient creation error: \(String(describing: error.errorMessage)).")
}
}
}
如果應用程式的最低 OS 版本低於 13,請改用尾隨閉包:
// Migrate from getClient
func initializeWithGetClient() {
super.viewDidLoad()
Recaptcha.getClient(withSiteKey: "KEY_ID") { client, error in
guard let client = client else {
print("RecaptchaClient creation error: \(error).")
return
}
self.recaptchaClient = client
}
}
// Migrate to fetchClient
func initializeWithFetchClient() {
super.viewDidLoad()
Recaptcha.fetchClient(withSiteKey: "KEY_ID") { client, error in
guard let client = client else {
print("RecaptchaClient creation error: \(error).")
return
}
self.recaptchaClient = client
}
}
Objective-C
// Migrate from getClient
@implementation ViewController
[Recaptcha getClientWithSiteKey:@"KEY_ID"
completion:^void(RecaptchaClient* recaptchaClient, NSError* error) {
if (!recaptchaClient) {
NSLog(@"%@", (RecaptchaError *)error.errorMessage);
return;
}
self->_recaptchaClient = recaptchaClient;
}
];
@end
// Migrate to fetchClient
@implementation ViewController
[Recaptcha fetchClientWithSiteKey:@"KEY_ID"
completion:^void(RecaptchaClient* recaptchaClient, NSError* error) {
if (!recaptchaClient) {
NSLog(@"%@", (RecaptchaError *)error.errorMessage);
return;
}
self->_recaptchaClient = recaptchaClient;
}
];
@end
設定 API 呼叫的逾時時間
您可以使用 withTimeout
屬性,為 execute
API 指定逾時值。
Swift
呼叫
execute
時設定逾時。Task { do { let token = try await recaptchaClient.execute( withAction: RecaptchaAction.login, withTimeout: 10000) print(token) } catch let error as RecaptchaError { print(error.errorMessage) } }
如果應用程式的最低 OS 版本低於 13,請改用尾隨閉包:
recaptchaClient.execute( withAction: RecaptchaAction.login, withTimeout: 10000 ) { token, error in if let token = token { print(token) } else { print(error) } }
Objective-C
呼叫
execute
時設定逾時。[recaptchaClient execute:RecaptchaAction.login witTimeout:10000.0 completion:^void(NSString* _Nullable token, NSError* _Nullable error) { if (!token) { NSLog (@"%@", (RecaptchaError *)error.errorMessage); return; } NSLog (@"%@", token); }];
處理錯誤
如果應用程式無法順利與 reCAPTCHA 服務通訊,可能是因為 API 發生錯誤。您必須在應用程式中加入邏輯,妥善處理這類錯誤。
如要進一步瞭解如何減輕常見 API 錯誤的影響,請參閱 RecaptchaErrorCode。
API 參考資料
如需 reCAPTCHA API for iOS 的完整參考資料,請參閱 RecaptchaEnterprise
。
後續步驟
如要評估 reCAPTCHA 回應權杖,請建立評估。