腾讯云验证码iOS端实现

iOS端APP之前使用了腾讯云验证码的低版本SDK,随着苹果开始拒绝使用UIWebView的APP,整改提上日程。

官网找到升级方案, 官方已经弃用了SDK,实现方式为在ios端调用WKWebview加载本地或远程包含腾讯验证码js的页面,通过html页面与native层的交互完成整个流程。
详见 腾讯防水墙-iOS接入文档

以下是对接入的实现,包含了js回调native方法,仅供参考

#import 
#import 

typedef void(^DSWebCodeViewDismissCallback)(void);
typedef void(^DSWebCodeViewVerifySucessCallback)(NSString *ticket);
typedef void(^DSWebCodeViewVerifyFailCallback)(void);

@interface DSWebCodeView : UIView

@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];
}

//自动生成8位随机密码
-(NSString *)randomPassword{
    NSTimeInterval random = [NSDate timeIntervalSinceReferenceDate];
    NSString *randomString = [[NSString stringWithFormat:@"%.8f",random] MD5];
    NSString *randompassword = [randomString substringWithRange:NSMakeRange(6, 8)];
    return randompassword;
}

//js调用原生回调
- (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"]) {
        //划动验证
        DSVerifyResultModel *model = [DSVerifyResultModel yy_modelWithJSON:message.body];
        if (model.ret == 0) {//验证成功
            [self removeFromSuperview];
            !self.verifySuccessCallback ? :self.verifySuccessCallback(model.ticket);
        }else if (model.ret == 2) {//点击关闭
            [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];
        //注册果断回调方法
        [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__(
                                               
                                               
                                               
                                               
                                               
                                               
                                               
                                               
    );
#undef __wvjb_js_func__
    return html;
};

@end

你可能感兴趣的:(腾讯云验证码iOS端实现)