iOS端APP之前使用了騰訊云驗(yàn)證碼的低版本SDK食寡,隨著蘋果開始拒絕使用UIWebView的APP,整改提上日程。
官網(wǎng)找到升級(jí)方案祖娘, 官方已經(jīng)棄用了SDK,實(shí)現(xiàn)方式為在ios端調(diào)用WKWebview加載本地或遠(yuǎn)程包含騰訊驗(yàn)證碼js的頁面贞间,通過html頁面與native層的交互完成整個(gè)流程贿条。
詳見 騰訊防水墻-iOS接入文檔
以下是對(duì)接入的實(shí)現(xiàn),包含了js回調(diào)native方法增热,僅供參考
#import <UIKit/UIKit.h>
#import <WebKit/WebKit.h>
typedef void(^DSWebCodeViewDismissCallback)(void);
typedef void(^DSWebCodeViewVerifySucessCallback)(NSString *ticket);
typedef void(^DSWebCodeViewVerifyFailCallback)(void);
@interface DSWebCodeView : UIView<WKNavigationDelegate, WKScriptMessageHandler>
@property (nonatomic, copy) DSWebCodeViewDismissCallback dismissCallback;
@property (nonatomic, copy) DSWebCodeViewVerifySucessCallback verifySuccessCallback;
@property (nonatomic, copy) DSWebCodeViewVerifyFailCallback verifyFailCallback;
- (void)loadTencentCaptcha;
@end
#import "DSWebCodeView.h"
@interface DSVerifyResultModel : DSBaseModel
@property (nonatomic, copy) NSString *appid;
@property (nonatomic, copy) NSString *randstr;
@property (nonatomic, assign) NSInteger ret;
@property (nonatomic, copy) NSString *ticket;
@end
@implementation DSVerifyResultModel
@end
@interface DSWebCodeView ()
@property (nonatomic, strong) WKWebView *webView;
@end
@implementation DSWebCodeView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setup];
}
return self;
}
- (void)setup {
[self addSubview:self.webView];
}
- (void)dismiss {
[self removeFromSuperview];
if (self.dismissCallback) {
self.dismissCallback();
}
}
// 加載入口方法
- (void)loadTencentCaptcha {
NSString *randomstr = [self randomPassword];
NSString* htmlText = [NSString stringWithFormat:DSWebBridge_html_js(), randomstr];
[self.webView loadHTMLString:htmlText baseURL:nil];
}
//自動(dòng)生成8位隨機(jī)密碼
-(NSString *)randomPassword{
NSTimeInterval random = [NSDate timeIntervalSinceReferenceDate];
NSString *randomString = [[NSString stringWithFormat:@"%.8f",random] MD5];
NSString *randompassword = [randomString substringWithRange:NSMakeRange(6, 8)];
return randompassword;
}
//js調(diào)用原生回調(diào)
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
if ([message.name isEqualToString:@"loadAction"]) {
//加載成功, 更新webview的frame
NSDictionary *jsData = message.body;
self.webView.frame = CGRectMake(0, 0, [jsData[@"sdkView"][@"width"] doubleValue], [jsData[@"sdkView"][@"height"] doubleValue]);
self.webView.center = CGPointMake(SCREEN_WIDTH/2, SCREEN_HEIGHT/2);
}else if([message.name isEqualToString:@"verifiedAction"]) {
//劃動(dòng)驗(yàn)證
DSVerifyResultModel *model = [DSVerifyResultModel yy_modelWithJSON:message.body];
if (model.ret == 0) {//驗(yàn)證成功
[self removeFromSuperview];
!self.verifySuccessCallback ? :self.verifySuccessCallback(model.ticket);
}else if (model.ret == 2) {//點(diǎn)擊關(guān)閉
[self dismiss];
}
}else if([message.name isEqualToString:@"errorAction"]) {//加載失敗
[self removeFromSuperview];
!self.verifyFailCallback?:self.verifyFailCallback();
}
}
- (WKWebView *)webView {
if (!_webView) {
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
configuration.userContentController = [WKUserContentController new];
//注冊(cè)果斷回調(diào)方法
[configuration.userContentController addScriptMessageHandler:self name:@"loadAction"];
[configuration.userContentController addScriptMessageHandler:self name:@"errorAction"];
[configuration.userContentController addScriptMessageHandler:self name:@"verifiedAction"];
WKWebView* webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
webView.navigationDelegate = self;
_webView = webView;
}
return _webView;
}
NSString * DSWebBridge_html_js() {
#define __wvjb_js_func__(x) #x
static NSString * html = @__wvjb_js_func__(
<!DOCTYPE html>
<html>
<head>
<script src="https://ssl.captcha.qq.com/TCaptcha.js?v=%@" type="text/javascript"></script>
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
</head>
<body>
<script type="text/javascript">
(function(){
// 驗(yàn)證成功返回ticket
window.SDKTCaptchaVerifyCallback = function (retJson) {
if (retJson){
window.webkit.messageHandlers.verifiedAction.postMessage(retJson)
}
};
// 驗(yàn)證碼加載完成的回調(diào)整以,用來設(shè)置webview尺寸
window.SDKTCaptchaReadyCallback = function (retJson) {
if (retJson && retJson.sdkView && retJson.sdkView.width && retJson.sdkView.height && parseInt(retJson.sdkView.width) >0 && parseInt(retJson.sdkView.height) >0 ){
window.webkit.messageHandlers.loadAction.postMessage(retJson)
}
};
window.onerror = function (msg, url, line, col, error) {
if (window.TencentCaptcha == null) {
window.webkit.messageHandlers.errorAction.postMessage(error)
}
};
var sdkOptions = {"sdkOpts": {"width": 265, "height": 265}};
sdkOptions.ready = window.SDKTCaptchaReadyCallback;
window.onload = function () {
//此處需要替換xxxxxx為appid
new TencentCaptcha("xxxxxxxx", SDKTCaptchaVerifyCallback, sdkOptions).show();
};
})();
</script></body></html>
);
#undef __wvjb_js_func__
return html;
};
@end