移动端iOS常见问题解答
iOS 设备在使用 H5 时出现文字点选验证位置错位
文字出现错位是由于 iOS 点击了软键盘顶起了页面,输入框失去焦点后不能恢复导致页面 clientY 变化的原因,提供以下方案:
加长整个页面
H5 中添加如下代码:
html,body { width: 100%; height: 100%; }
|
国际化多语言模式,验证页面语言未跟随系统语言变化,或未按照设置的语言变化
首先检查工程中是否有添加 GT3Captcha.bundle 文件,并确认 GT3Captcha.bundle 中是否包含对应的语言
检查主工程的 Info.plist 文件中是否有设置 CFBundleLocalizations,并查看是否有添加对应语言的英文简称,如下图所示:

如何进行异步任务方式的集成?
自定义一个类,该类需要实现 GT3AsyncTaskProtocol
协议
在该类中实现 GT3AsyncTaskProtocol
协议中的如下两个方法,在第一个方法中,进行自定义的 api1 的请求,拿到对应的 gt
、 challenge
、 success
参数,并通过 completion
回调将参数传给 SDK,在第二个方法中,进行 api2 的验证,并通过 completion
回调将 api2 的验证结果传给 SDK
- (void)executeRegisterTaskWithCompletion:(void (^)(GT3RegisterParameter * _Nullable, GT3Error * _Nullable))completion {
}
- (void)executeValidationTaskWithValidateParam:(GT3ValidationParam *)param completion:(void (^)(BOOL, GT3Error * _Nullable))completion {
}
|
实例化一个 GT3CaptchaManager
,并通过 registerCaptchaWithCustomAsyncTask:completion:
方法注册异步任务,最后调用 startGTCaptchaWithAnimated:
方法即可开启验证
详细可参考如下代码:
@interface DemoAyncTask : NSObject <GT3AsyncTaskProtocol>
@property (nonatomic, weak) id<DemoAyncTaskDelegate> delegate;
- (void)executeValidationTaskWithValidateParam:(GT3ValidationParam *)param completion:(void (^)(BOOL, GT3Error * _Nullable))completion; - (void)executeRegisterTaskWithCompletion:(void (^)(GT3RegisterParameter * _Nullable, GT3Error * _Nullable))completion;
- (void)cancel;
@end
@implementation DemoAyncTask
- (void)executeValidationTaskWithValidateParam:(GT3ValidationParam *)param completion:(void (^)(BOOL, GT3Error * _Nullable))completion {
__block NSMutableArray *postArray = [[NSMutableArray alloc] init]; [param.result enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL * stop) { NSString *paramItem = [NSString stringWithFormat:@"%@=%@", key, obj]; [postArray addObject:paramItem]; }]; NSString *postForm = [postArray componentsJoinedByString:@"&"]; EnvModel *model = [EnvSettingCenter defaultCenter].currentEnv; NSDictionary *headerFields = @{@"Content-Type":@"application/x-www-form-urlencoded;charset=UTF-8"}; NSMutableURLRequest *secondaryRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:model.validateAPI] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:15.0]; secondaryRequest.HTTPMethod = @"POST"; secondaryRequest.allHTTPHeaderFields = headerFields; secondaryRequest.HTTPBody = [postForm dataUsingEncoding:NSUTF8StringEncoding]; NSURLSession *session = [NSURLSession sharedSession]; self.validateDataTask = [session dataTaskWithRequest:secondaryRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; if (!error && httpResponse.statusCode == 200) { NSError *err; NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&err]; if (!err) { NSString *status = [dict objectForKey:@"status"]; if ([status isEqualToString:@"success"]) { NSLog(@"通过业务流程"); if (completion) { completion(YES, nil); } if (_delegate && [_delegate respondsToSelector:@selector(asyncTaskDidFinish:error:)]) { [_delegate asyncTaskDidFinish:YES error:nil]; } } else { if (completion) { completion(NO, nil); } NSLog(@"无法通过业务流程"); if (_delegate && [_delegate respondsToSelector:@selector(asyncTaskDidFinish:error:)]) { [_delegate asyncTaskDidFinish:NO error:nil]; } } } else { GT3Error *anErr = [GT3Error errorWithDomainType:GT3ErrorTypeExtern originalError:err withGTDesciption:@"Error occur."]; if (completion) { completion(NO, anErr); } if (_delegate && [_delegate respondsToSelector:@selector(asyncTaskDidFinish:error:)]) { [_delegate asyncTaskDidFinish:NO error:anErr]; } NSLog(@"error:\n%@", err.localizedDescription); } } else { GT3Error *err = [GT3Error errorWithDomainType:GT3ErrorTypeExtern originalError:error withGTDesciption:@"Error occur."]; if (completion) { completion(NO, err); } if (_delegate && [_delegate respondsToSelector:@selector(asyncTaskDidFinish:error:)]) { [_delegate asyncTaskDidFinish:NO error:err]; } NSLog(@"error:\n%@", error.localizedDescription); } }]; [self.validateDataTask resume]; }
- (void)executeRegisterTaskWithCompletion:(void (^)(GT3RegisterParameter * _Nullable, GT3Error * _Nullable))completion { EnvModel *model = [EnvSettingCenter defaultCenter].currentEnv;
NSString *ts = [NSString stringWithFormat:@"%.0f", [[NSDate date] timeIntervalSince1970] * 1000]; NSURLQueryItem *queryItem = [NSURLQueryItem queryItemWithName:@"t" value:ts]; NSURLComponents *comp = [NSURLComponents componentsWithURL:[NSURL URLWithString:model.registerAPI] resolvingAgainstBaseURL:NO]; comp.queryItems = @[queryItem]; NSURLRequest *request = [NSURLRequest requestWithURL:comp.URL]; NSURLSession *session = [NSURLSession sharedSession]; self.registerDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (!error) { NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingOptions)0 error:&error]; if (!error && dict) { NSString *geetest_id = [dict objectForKey:@"gt"]; NSString *geetest_challenge = [dict objectForKey:@"challenge"]; NSNumber *geetest_success = [dict objectForKey:@"success"]; if (geetest_id && geetest_challenge && geetest_success) { GT3RegisterParameter *param = [[GT3RegisterParameter alloc] init]; param.gt = geetest_id; param.challenge = geetest_challenge; param.success = geetest_success; if (completion) { completion(param, nil); } } } } else { GT3Error *err = [GT3Error errorWithDomainType:GT3ErrorTypeExtern originalError:error withGTDesciption:@"Error occur."]; if (completion) { completion(nil, err); } NSLog(@"error:\n%@", error.localizedDescription); } }]; [self.registerDataTask resume]; }
- (void)cancel { if (self.registerDataTask) { [self.registerDataTask cancel]; }
if (self.validateDataTask) { [self.validateDataTask cancel]; } }
@end
- (GT3CaptchaManager *)manager { if (!_manager) { BOOL debugable = [EnvSettingCenter defaultCenter].debugEnable; BOOL httpsEnable = [EnvSettingCenter defaultCenter].httpsEnable; BOOL naEnable = [EnvSettingCenter defaultCenter].naNodeEnable; GT3LanguageType langType = [EnvSettingCenter defaultCenter].langType; EnvModel *model = [EnvSettingCenter defaultCenter].currentEnv; _manager = [[GT3CaptchaManager alloc] initWithAPI1:model.registerAPI API2:model.validateAPI timeout:5.0]; _manager.delegate = self; _manager.viewDelegate = self; [_manager enableDebugMode:debugable]; [_manager disableSecurityAuthentication:!httpsEnable]; [_manager useLanguage:langType]; if (naEnable) [_manager useServiceNode:GT3CaptchaServiceNodeNA]; [_manager useVisualViewWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]]; } return _manager; }
- (void)_init { DemoAyncTask *asyncTask = [[DemoAyncTask alloc] init]; asyncTask.delegate = self; [self.manager registerCaptchaWithCustomAsyncTask:asyncTask completion:nil]; self.asyncTask = asyncTask; }
- (void)startCaptcha { [self.manager startGTCaptchaWithAnimated:YES]; }
- (void)stopCaptcha { [self.manager stopGTCaptcha]; }
|
如何查看 SDK 版本?
找到 GT3Captcha.framework 文件,选中 -> 双击进入目录 -> 找到 Info.plist -> 双击打开,找到 Bundle version string (short) 对应的值,即为 SDK 的版本,如下图所示:

如何获取二次验证的参数?
异步任务集成时,二次验证的参数在 - (void)executeValidationTaskWithValidateParam:(GT3ValidationParam *)param completion:(void (^)(BOOL, GT3Error * _Nullable))completion
回调方法中的 param
参数的 result
中,param.result
,如下图所示:

非异步任务集成时,二次验证的参数在 - (void)gtCaptcha:(GT3CaptchaManager *)manager didReceiveCaptchaCode:(NSString *)code result:(NSDictionary *)result message:(NSString *)message
回调方法的 result
中,如下图所示:

如何排查 3840 及 101603 错误?
出现这两个错误码,一般是 api1 请求返回的数据格式有问题,请检查 api1 接口返回的数据格式:
返回的数据不是 json 格式
返回的 json 格式与极验官方要求的不一致
正确的 json 格式为下面两种:
{ "challenge": "90977bef1d2c8a8efaea1e41b1d7b19b", "gt": "4faf9dd37eb683586977947ce87a866a", "new_captcha": 1, "success": 1 }
{"data": { "challenge": "90977bef1d2c8a8efaea1e41b1d7b19b", "gt": "4faf9dd37eb683586977947ce87a866a", "new_captcha": 1, "success": 1 } }
|