iOS 接入
更新时间:2026-10-09
iOS 接入
1. 接入流程
- 开通验证码服务后,在控制台添加验证场景,获取该场景分配的业务
ak(AccessKey); - 在 iOS 客户端集成验证码 SDK;
- 在业务页面中调用验证码 SDK 拉起验证,将 验证通过返回的参数值传到 iOS App 业务端;
- 业务端把相关参数传入验证码服务端进行验签。
2. 接入方式
iOS 端支持两种接入方式,请根据业务形态选择:
| 接入方式 | 说明 | 适用场景 | 参考文档 |
|---|---|---|---|
| ① WebView 引入 H5 页面 | 在 App 内通过 WKWebView 加载验证码 H5 页面,通过 JS 桥接获取验证结果 | 已有 WebView 业务页面、希望复用 H5 接入逻辑、对包体积敏感 | 见《[Web/H5 接入]》 |
| ② iOS 原生客户端集成 | 集成验证码 iOS SDK,通过原生控件 YMGCaptchaViewController 拉起验证 |
原生 App、需要原生交互体验 | 见本文档以下内容 |
- 两种方式的验证结果(
svcp_stk)与服务端验签流程完全一致,均参见《服务端接入》。
3. SDK 方案说明
验证码 iOS SDK 本质上是对 H5 验证码能力的原生封装,在保留 Web 端安全对抗能力的同时,提供原生调用体验。
- 通过 WKWebView 承载验证页面,监听并拦截验证成功的回调,完成与 H5 验证逻辑的双向通信;
- 技术选型:Swift + 独立封装的
UIViewController,通过宿主UIViewController.present()方式弹出验证页面; - 以 framework 形式交付,支持滑块、数字点选、文字点选、轨迹绘制等多种验证形态;
- 验证逻辑与对抗策略基于 SaaS 架构在云端统一维护、自动更新。
3.1 交互说明
- 在业务触发点(如登录、提交按钮)拉起验证码页面;
- 点击阴影空白处(上下左右)可退出验证;
- 验证通过后自动退出并回调返回
svcp_stk;验证失败时停留在验证页,可重试。
4. SDK 集成方式
1. 添加 SDK 依赖
SDK 以文件形式交付(YMGBehaviorVerify.framework):
- 将
YMGBehaviorVerify.framework拖入工程; - 在
Target > General > Frameworks, Libraries, and Embedded Content中将其设置为 Embed & Sign。
2. 工程配置
- iOS 无需在 Info.plist 中声明网络权限;
- 验证码服务通过 HTTPS 访问,默认满足 App Transport Security(ATS)要求;
3. 混淆配置
- iOS 无代码混淆步骤;如工程使用了代码裁剪/资源剥离脚本,请保留
YMGBehaviorVerify相关类与资源。
5. SDK 控件接口说明
验证码控件定义(Swift):
Swift
1@objc public class YMGCaptchaViewController: UIViewController
2
3/** 构造函数
4 * @param handleCaptchaToken: 验证成功后,验证码通过令牌 svcp_stk 参数的处理回调函数
5 * @param ak: 验证码业务 ak
6 * @param ext: 业务希望绑定的额外参数,不需要可以不传
7 */
8init(
9 handleCaptchaToken: @escaping (_ stoken: String) -> Void,
10 ak: String,
11 ext: String = ""
12)
构造参数说明:
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
| handleCaptchaToken | (String) -> Void | 是 | 验证成功回调,入参为验证码通过令牌 svcp_stk,业务需将其提交至服务端二次校验 |
| ak | String | 是 | 控制台为验证场景分配的业务 AccessKey |
| ext | String | 否 | 业务希望绑定的额外参数,随验证请求透传,可用于业务侧数据关联 |
页面展示:通过宿主的 present(_:animated:) 弹出;弹出后点击阴影空白处,或完成验证并通过,均会退出验证页面并返回原页面。
6. SDK 集成核心代码片段参考
Swift 版本:
JavaScript
1// 引用 SDK 依赖
2import YMGBehaviorVerify
3
4// STEP-1 : 创建 Captcha stoken 处理 callback,验证成功时,会将验证令牌 "svcp_stk" 通过回调函数返回给业务控件
5@objc func handleCaptchaToken(stoken: String) {
6 labelToken.text = stoken // 验证通过,将 stoken 写回到前端
7}
8
9// Button Submit : 触发验证的回调
10@objc func btnSubmit(btnSender: UIButton) {
11 // STEP-2 : 创建验证码控件
12 let captchaVC = YMGBehaviorVerify.YMGCaptchaViewController(handleCaptchaToken: self.handleCaptchaToken, ak: "你的业务AK", ext: "uid1234")
13 // STEP-3 : 通过弹出方式展现控件。弹出后,点击空白区域,或者完成验证并通过,均会退出弹出的控件,返回到原页面
14 self.present(captchaVC, animated: true)
15}
Objective-C 版本:
Swift
1// 引用 SDK 依赖
2#import <YMGBehaviorVerify/YMGBehaviorVerify-Swift.h>
3
4// STEP-1 : 创建 Captcha stoken 处理 callback,验证成功时,会将验证令牌 "svcp_stk" 通过回调函数返回给业务控件
5- (void)handleCaptchaToken:(NSString *)stoken {
6 labelToken.text = stoken; // 验证通过,将 stoken 写回到前端
7}
8
9// Button Submit : 触发验证的回调
10- (void)btnSubmit:(UIButton *)btnSender {
11 // STEP-2 : 创建验证码控件
12 YMGCaptchaViewController *captchaVC = [
13 [YMGCaptchaViewController alloc] initWithHandleCaptchaToken:^(NSString * _Nonnull stoken) {
14 [self handleCaptchaToken:stoken];
15 }
16 ak:@"你的业务AK" ext:@"uid1234"
17 ];
18 // STEP-3 : 通过弹出方式展现控件。弹出后,点击空白区域,或者完成验证并通过,均会退出弹出的控件,返回到原页面
19 [self presentViewController:captchaVC animated:TRUE completion:^{}];
20}
7. 完整 Demo 代码参考
7.1 Swift Demo
Swift
1import UIKit
2import WebKit
3import YMGBehaviorVerify
4
5class ViewController: UIViewController, WKNavigationDelegate {
6
7 //
8 // views
9 //
10 var label: UILabel!
11 var labelToken: UILabel!
12 var textView: UITextView!
13 var btn: UIButton!
14
15 // var captchaView:CaptchaView!
16 override func loadView() {
17 super.loadView()
18 }
19
20 override func viewDidLoad() {
21 super.viewDidLoad()
22
23 let winSize = self.view.bounds.size
24
25 // label
26 label = UILabel(frame: CGRect(x: 20, y: 60, width: winSize.width - 40, height: 40))
27 label.text = "输入 Error 单词,触发验证码(Swift)"
28 self.view.addSubview(label)
29
30 // text input
31 textView = UITextView(frame: CGRect(x: 20, y: 100, width: winSize.width - 40, height: 200))
32 textView.backgroundColor = UIColor.lightGray
33 textView.textColor = UIColor.black
34 textView.text = "Error"
35 textView.font = .systemFont(ofSize: 20)
36 self.view.addSubview(textView)
37
38 // Button
39 btn = UIButton(frame: CGRect(x: winSize.width - 120, y: 320, width: 100, height: 40))
40 btn.setTitle("提交", for: .normal)
41 btn.backgroundColor = UIColor.darkGray
42 btn.isEnabled = true
43 btn.addTarget(self, action: #selector(btnOnUp(btnSender:)), for: .touchUpInside)
44 btn.addTarget(self, action: #selector(btnOnUp(btnSender:)), for: .touchUpOutside)
45 btn.addTarget(self, action: #selector(btnOnDown(btnSender:)), for: .touchDown)
46 btn.addTarget(self, action: #selector(btnSubmit(btnSender:)), for: .touchDown)
47 self.view.addSubview(btn)
48
49 // labelToken
50 labelToken = UILabel(frame: CGRect(x: 20, y: 360, width: winSize.width - 40, height: 200))
51 labelToken.text = "Captcha Token ..."
52 labelToken.numberOfLines = 0
53 labelToken.lineBreakMode = .byCharWrapping // NSLineBreakMode.byWordWrapping
54 self.view.addSubview(labelToken)
55 }
56
57 @objc func btnOnUp(btnSender: UIButton) {
58 btnSender.backgroundColor = UIColor.darkGray
59 }
60
61 @objc func btnOnDown(btnSender: UIButton) {
62 btnSender.backgroundColor = UIColor.gray
63 }
64
65 // //////////////////////////////////////////////////////////////////////////////
66 // demo
67 // //////////////////////////////////////////////////////////////////////////////
68
69 // STEP-1 : 创建 Captcha stoken 处理 callback, 验证成功时,会将验证令牌 "svcp_stk" 通过回调函数返回给业务控件
70 @objc func handleCaptchaToken(stoken: String) {
71 labelToken.text = stoken // 验证通过,将 stoken 写回到前端
72 }
73
74 // Button Submit : 触发验证的回调
75 @objc func btnSubmit(btnSender: UIButton) {
76 if textView.text == "Error" {
77 print("trigger Error Text") // debug note
78
79 // STEP-2 : 创建验证码控件
80 let captchaVC = YMGBehaviorVerify.YMGCaptchaViewController(handleCaptchaToken: self.handleCaptchaToken, ak: "***************************", ext: "uid1234")
81 // STEP-3 : 通过弹出方式展现控件。弹出后,点击空白区域,或者完成验证并通过,均会退出弹出的控件,返回到原页面
82 self.present(captchaVC, animated: true)
83 }
84 }
85
86 // //////////////////////////////////////////////////////////////////////////////
87
88}
7.2 OC Demo
Swift
1#import "ViewController.h"
2#import <YMGBehaviorVerify/YMGBehaviorVerify-Swift.h>
3
4@interface ViewController ()
5
6@end
7
8@implementation ViewController
9
10UILabel *label = NULL;
11UILabel *labelToken = NULL;
12UITextView *textView = NULL;
13UIButton *btn = NULL;
14
15- (void)viewDidLoad {
16 [super viewDidLoad];
17 // Do any additional setup after loading the view.
18
19 CGSize winSize = self.view.bounds.size;
20
21 // label
22 label = [[UILabel alloc] init];
23 label.frame = CGRectMake(20, 60, winSize.width - 40, 40);
24 label.text = @"输入 Error 单词,触发验证码(OC)";
25 [self.view addSubview:label];
26
27 // text input
28 textView = [[UITextView alloc] init];
29 textView.frame = CGRectMake(20, 100, winSize.width - 40, 200);
30 textView.backgroundColor = UIColor.lightGrayColor;
31 textView.textColor = UIColor.blackColor;
32 textView.text = @"Error";
33 textView.font = [UIFont systemFontOfSize:20];
34 [self.view addSubview:textView];
35
36 // Button
37 btn = [[UIButton alloc] init];
38 btn.frame = CGRectMake(winSize.width - 120, 320, 100, 40);
39 [btn setTitle:@"提交" forState:UIControlStateNormal];
40 btn.backgroundColor = UIColor.darkGrayColor;
41 btn.enabled = TRUE;
42 [btn addTarget:self action:@selector(btnOnUp:) forControlEvents:(UIControlEventTouchUpInside)];
43 [btn addTarget:self action:@selector(btnOnUp:) forControlEvents:(UIControlEventTouchUpOutside)];
44 [btn addTarget:self action:@selector(btnOnDown:) forControlEvents:(UIControlEventTouchDown)];
45 [btn addTarget:self action:@selector(btnSubmit:) forControlEvents:(UIControlEventTouchDown)];
46 [self.view addSubview:btn];
47
48 // labelToken
49 labelToken = [[UILabel alloc] init];
50 labelToken.frame = CGRectMake(20, 360, winSize.width - 40, 150);
51 labelToken.text = @"Captcha Token ...";
52 labelToken.numberOfLines = 0;
53 labelToken.lineBreakMode = NSLineBreakByCharWrapping;
54 [self.view addSubview:labelToken];
55}
56
57
58- (void)btnOnUp:(UIButton *)btnSender {
59 btnSender.backgroundColor = UIColor.darkGrayColor;
60}
61
62- (void)btnOnDown:(UIButton *)btnSender {
63 btnSender.backgroundColor = UIColor.grayColor;
64}
65
66// //////////////////////////////////////////////////////////////////////////////
67// demo
68// //////////////////////////////////////////////////////////////////////////////
69
70// STEP-1 : 创建 Captcha stoken 处理 callback, 验证成功时,会将验证令牌 "svcp_stk" 通过回调函数返回给业务控件
71- (void)handleCaptchaToken:(NSString *)stoken {
72 labelToken.text = stoken; // 验证通过,将 stoken 写回到前端
73}
74
75// Button Submit : 触发验证的回调
76- (void)btnSubmit:(UIButton *)btnSender {
77 if ([textView.text isEqualToString:(NSString *)@"Error"]) {
78 NSLog(@"trigger Error Text From VC"); // debug note
79
80 // STEP-2 : 创建验证码控件
81 YMGCaptchaViewController *captchaVC = [
82 [YMGCaptchaViewController alloc] initWithHandleCaptchaToken:^(NSString * _Nonnull stoken) {
83 [self handleCaptchaToken:stoken];
84 }
85 ak:@"***************************" ext:@"uid1234"
86 ];
87 // STEP-3 : 通过弹出方式展现控件。弹出后,点击空白区域,或者完成验证并通过,均会退出弹出的控件,返回到原页面
88 [self presentViewController:captchaVC animated:TRUE completion:^{}];
89 }
90}
91
92@end
8. Token 与服务端验签
- 验证成功后,
handleCaptchaToken回调返回验证码令牌svcp_stk(即《服务端接入》文档中的stk); - 业务客户端将
svcp_stk提交至业务服务端(传输方式由业务自定义,如请求体字段); - 业务服务端调用验证码服务端
/v1/webapi/verint/verifystk接口完成二次校验,具体加解密流程与请求/响应格式见《服务端接入》; - 仅当服务端验签返回
pass == true时,才允许放行业务流程(注册、登录、领券等)。
安全提示:客户端回调结果不可作为最终放行依据,必须以服务端验签结果为准。
评价此篇文章
