最近在集成极限验证3.0,踏过无数坑后,终于完成,自我感觉官方文档介绍的比较简约,demo写的也是最简单的一种方式。所以在这里写一篇详细的集成流程希望能帮到后面需要集成的童鞋们。
1.导入GT3Captcha.framework和GT3Captcha.Bundle,这一块官网上叙述还是比较详细的,我这就不多介绍了。
2.我用的是与集成用户自定义的按钮事件绑定方式集成,就是自定义按钮,对按钮进行一个与极验的绑定,从而点击按钮触发极验。
(1)继承自UIButton新建一个按钮类(swift)
importUIKit
importGT3Captcha
@objcprotocolCaptchaButtonDelegate {
@objcoptionalfunccaptchaButtonShouldBeginTapAction(_button:VerificationButton)->Bool
funccaptcha(_manager:GT3CaptchaManager, data:Data, response:URLResponse,error:GT3Error)
@objcoptionalfunccaptcha(_manager:GT3CaptchaManager,error:GT3Error)
funccaptchSuccess()
funccaptchFail(error:String)
}
classVerificationButton:UIButton,GT3CaptchaManagerDelegate,GT3CaptchaManagerViewDelegate{
weakvardelegate:CaptchaButtonDelegate?
varphone =""
varchallenge =""
vargtId =""
varsuccess =""
varseccode =""
varvalidate =""
// 初始化极验控制器
lazyvarmanager:GT3CaptchaManager= {
varapiOne =kBaseURL+"/verification/init"
varapiTwo =kBaseURL+"/verification/check"
self.manager=GT3CaptchaManager.sharedGTManager(withAPI1: apiOne, api2: apiTwo, timeout:0.5)
self.manager.delegate=self
self.manager.viewDelegate=self
self.manager.useVisualView(with:UIBlurEffect(style: .dark))
returnself.manager
}()
requiredinit(frame:CGRect,type :UIButtonType) {
super.init(frame: frame)
}
// 点击按钮触发事件
funcstartCaptcha() {
//极验注册
self.manager.registerCaptcha{
}
//开启极验
self.manager.startGTCaptchaWith(animated:true)
}
// 停止极验
funcstopCaptcha() {
self.manager.stopGTCaptcha()
}
//修改api1(在极验第一次请求前的拦截,用于修改第一次请求url,比如拼接所需参数)
funcgtCaptcha(_manager:GT3CaptchaManager!, willSendRequestAPI1 originalRequest:URLRequest!, withReplacedHandler replacedHandler: ((URLRequest?) ->Void)!) {
varapi1Request = originalRequest
vartokenString =""
ifletentity =LoginViewController.kCustomerEntity{
tokenString = entity.token
}
leturl =kBaseURL+"/verification/init"+"?udid="+ MTRequestParam.deviceID() +"×tamp="+ MTRequestParam.timestamp() +"&token="+ tokenString +"&os=ios&v="+kCurVersion+"."+kCurLayoutVersion+"&terminal=1&appid="+kAppID
api1Request?.url =URL(string: url)
//根据自己公司服务器请求所需参数拼接完成后,完成替换api1请求
replacedHandler(api1Request)
}
//获取api1请求回来的数据并进行,按照要求重新组装一下,返回给极验
funcgtCaptcha(_manager:GT3CaptchaManager!, didReceiveDataFromAPI1 dictionary: [AnyHashable:Any]!, withError error:GT3Error!) -> [AnyHashable:Any]! {
ifletdictionary = dictionary {
ifdictionary.keys.contains("results") {
print(dictionary["results"]!)
letdic = dictionary["results"]as! [AnyHashable:Any]
ifdic.keys.contains("body") {
letdicInfo = dic["body"]as! [AnyHashable:Any]
vargtId =""
varchallenge =""
varsuccess =NSNumber()
ifdicInfo.keys.contains("challenge") {
print(dicInfo["challenge"]!)
challenge = (dicInfo["challenge"]as?String)!
}
ifdicInfo.keys.contains("gtId") {
print(dicInfo["gtId"]!)
gtId = (dicInfo["gtId"]as?String)!
}
ifdicInfo.keys.contains("success") {
print(dicInfo["success"]!)
self.success= (dicInfo["success"]!as!String=="true") ?"1":"0"
success = (dicInfo["success"]!as!String=="true") ?NSNumber(value:1) :NSNumber(value:0)
}
self.challenge= challenge
self.gtId= gtId
letnewDic = ["challenge":challenge,"gt": gtId,"success":success]as[String:Any]
returnnewDic
}
}
}
returndictionary
}
//出现验证界面,验证成功后通过此回调返回三个参数(这三个参数需要记录一下,为api2请求所需的参数)
funcgtCaptcha(_manager:GT3CaptchaManager!, didReceiveCaptchaCode code:String!, result: [AnyHashable:Any]!, message:String!) {
print(code)
ifresult.keys.contains("geetest_seccode") {
print(result["geetest_seccode"]asAny)
self.seccode= result["geetest_seccode"]as!String
}
ifresult.keys.contains("geetest_challenge") {
print(result["geetest_challenge"]asAny)
self.challenge= result["geetest_challenge"]as!String
}
ifresult.keys.contains("geetest_validate") {
print(result["geetest_validate"]asAny)
self.validate= result["geetest_validate"]as!String
}
}
//修改api2(在极验第二次请求前的拦截,用于修改第二次请求url)
funcgtCaptcha(_manager:GT3CaptchaManager!, willSendSecondaryCaptchaRequest originalRequest:URLRequest!, withReplacedRequest replacedRequest: ((NSMutableURLRequest?) ->Void)!) {
letapi2Request = originalRequestas?NSMutableURLRequest
vartokenString =""
ifletentity =LoginViewController.kCustomerEntity{
tokenString = entity.token
}
leturl =kBaseURL+"/verification/check"+"?udid="+ MTRequestParam.deviceID() +"×tamp="+ MTRequestParam.timestamp() +"&token="+ tokenString +"&os=ios&v="+kCurVersion+"."+kCurLayoutVersion+"&terminal=1&appid="+kAppID+"&mobile="+ phone +"&challenge="+self.challenge +"&validate="+self.validate +"&seccode="+self.seccode
ifletapi2 = api2Request {
//这里需要转码一下,因为上一步获取到的seccode含有|,转码后再转为URL
letunsafeP = url.addingPercentEncoding(withAllowedCharacters:NSCharacterSet(charactersIn:"`#%^{}\"[]|\\<> ").inverted)
api2.url =URL(string: unsafeP!)
replacedRequest(api2)
}
}
// 成功执行第二次验证
funcgtCaptcha(_manager:GT3CaptchaManager!, didReceiveSecondaryCaptchaData data:Data!, response:URLResponse!, error:GT3Error!, decisionHandler: ((GT3SecondaryCaptchaPolicy) ->Void)!) {
if(!(error !=nil)) {
//处理你的验证结果
decisionHandler(.allow);
ifletdelegate =self.delegate{
delegate.captchSuccess()
}
}
else{
//二次验证发生错误
decisionHandler(.forbidden);
ifletdelegate =self.delegate{
delegate.captchFail(error: error.description)
}
}
}
// 错误回调
funcgtCaptcha(_manager:GT3CaptchaManager!, errorHandler error:GT3Error!) {
if(error.code==-999) {
// 请求被意外中断, 一般由用户进行取消操作导致, 可忽略错误
}
elseif(error.code==-10) {
// 预判断时被封禁, 不会再进行图形验证
}
elseif(error.code==-20) {
// 尝试过多
}
else{
// 网络问题或解析失败, 更多错误码参考开发文档
print(error)
}
ifletdelegate =self.delegate{
delegate.captchFail(error: error.gtDescription)
}
}
funcgtCaptchaUserDidCloseGTView(_manager:GT3CaptchaManager!) {
}
// 状态回调
funcgtCaptcha(_manager:GT3CaptchaManager!, updateCaptchaStatus state:GT3CaptchaState, error:GT3Error!) {
switch(state) {
case.inactive:break
case.active:break
case.computing:break
case.initial:break
case.fail:break
case.error:break
case.success:break
case.cancel:break
case.waiting:break
case.collecting:break
}
}
requiredinit?(coder aDecoder:NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
(2)主页面所需的代码
// 验证码按钮
lazyvarverificationCodeBtn:VerificationButton= {
letbtn =VerificationButton(frame:CGRect(x:kScreenWidth-designToPoint(60+14), y:0.5*designToPoint(44-24), width:designToPoint(60), height:designToPoint(24)), type: .custom)
btn.delegate=self as CaptchaButtonDelegate//一定不要忘掉加代理
btn.setImage(UIImage(named:"bt_yanzhengma1"), for: .normal)
btn.setImage(UIImage(named:"bt_yanzhengma2"), for: .disabled)
btn.addTarget(self, action:#selector(RegisterViewController.onClickVerificationCodeBtn), for: .touchUpInside)
returnbtn
}()
//调用极验方法
verificationCodeBtn.startCaptcha()
3.多说的话:我们公司的业务逻辑是点击验证按钮先走一个请求,后台判断验证码是否有效,如果无效才进行极验(这里才调用verificationCodeBtn.startCaptcha()这个方法),极验成功后再次调用判断验证码有效。验证有效则直接走发送短信功能。