React Native 原生密码键盘插件

栏目: IOS · 发布时间: 7年前

内容简介:React Native (简称RN)是Facebook于2015年4月开源的跨平台移动应用开发框架,是Facebook早先开源的JS框架 React 在原生移动应用平台的衍生产物,目前支持iOS和安卓两大平台。RN使用Javascript语言,类似于HTML的JSX,以及CSS来开发移动应用,因此熟悉Web前端开发的技术人员只需很少的学习就可以进入移动应用开发领域。在React Native移动平台项目开发中,除了React Native 提供的封装好的部分插件和原声组建外,在实际的项目中还需要使用到很

React Native (简称RN)是Facebook于2015年4月开源的跨平台移动应用开发框架,是Facebook早先开源的JS框架 React 在原生移动应用平台的衍生产物,目前支持iOS和安卓两大平台。RN使用Javascript语言,类似于HTML的JSX,以及CSS来开发移动应用,因此熟悉Web前端开发的技术人员只需很少的学习就可以进入移动应用开发领域。

在React Native移动平台项目开发中,除了React Native 提供的封装好的部分插件和原声组建外,在实际的项目中还需要使用到很多其他的插件,比如网络请求、数据库、相机、相册、通讯录、视频播放器、浏览器、蓝牙连接、图片处理、消息推送、地图、统计、埋点等等APP开发中需要用到的功能,都为IDE开发平台提供封装好的插件,以便项目开发使用。

另外,这些博文都是来源于我日常开发中的技术总结,在时间允许的情况下,我会针对技术点分别分享iOS、Android两个版本,如果有其他技术点需要,可在文章后留言,我会尽全力帮助大家。这篇文章重点介绍原生密码键盘插件的开发与使用

二:实现思路分析

原生密码键盘插件是需要实现自定以键盘包含数字、大写字母、小写字母、特殊字符四种切换方式,并且需要实现随机键盘和非随机键盘模式。 实现根据密码包含数字、大写字母、小写字母、特殊字符种类判断密码强度和长度。 为了密码的安全考虑,实现对输出密码进行SM3加密。 实现键盘类型,其中包括以下6种类型:

FBYCustomKeyBordType_NumWord,//数字及字母键盘 FBYCustomKeyBordType_WordNum,//字母及数字键盘 FBYCustomKeyBordType_NumWordSymbol,//数字及字母,标点键盘 FBYCustomKeyBordType_WordNumSymbol,//字母及数字,标点键盘 FBYCustomKeyBordType_Num,//仅数字键盘 FBYCustomKeyBordType_Word//仅字母键盘

基本键盘截图如下:

React Native 原生密码键盘插件

实现键盘视图显示类型,其中包括以下5种类型:

FBYCustomKeyBordShowType_Common,//普通 FBYCustomKeyBordShowType_Text,//文本框 FBYCustomKeyBordShowType_Pass,//密码 FBYCustomKeyBordShowType_PayPass,//支付密码格 FBYCustomKeyBordShowType_NoTitle//无标题

带有文本框的键盘:

React Native 原生密码键盘插件

有支付密码格的键盘:

React Native 原生密码键盘插件

打开默认浏览器和打开自定义浏览器,具体的实现思路如下:

  1. 新建CustomKeyboard类,实现RCTBridgeModule协议

  2. 添加RCT_EXPORT_MODULE()宏

  3. 添加React Native跟控制器

  4. 声明被JavaScript 调用的方法

  5. 新建数字键盘FBYNumKeyBord类,实现相应视图及功能

  6. 新建字母键盘FBYWordKeyBord类,实现相应视图及功能

  7. 新建纯数字键盘FBYNumOnlyKeyBord类,实现相应视图及功能

  8. 新建符号键盘FBYSymbolKeyBord类,实现相应视图及功能

  9. 新建符号键盘FBYCustomKeyBord类,实现键盘类型切换功能

  10. 实现根据密码判断密码强度和长度功能

  11. 实现输出密码SM3加密功能

  12. 根据传参分析调用自定义键盘

  13. Javascript调用浏览器方法

三:实现源码分析

1. 新建CustomKeyboard类,实现RCTBridgeModule协议

新建继承NSObject的CustomKeyboard类,并实现RCTBridgeModule协议

// CustomKeyboard.h
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import <UIKit/UIKit.h>
@interface CustomKeyboard : NSObject<RCTBridgeModule>
@end
复制代码

2. 添加RCT_EXPORT_MODULE()宏

为了实现RCTBridgeModule协议,CustomKeyboard的类需要包含RCT_EXPORT_MODULE()宏。 并在这个宏里面添加一个参数“KeybordPlugin”用来指定在 JavaScript 中访问这个模块的名字。 如果你不指定,默认就会使用这个 Objective-C 类的名字。 如果类名以 RCT 开头,则 JavaScript 端引入的模块名会自动移除这个前缀。

// CustomKeyboard.m
#import "CustomKeyboard.h"
@implementation CustomKeyboard
RCT_EXPORT_MODULE(KeybordPlugin);
@end
复制代码

3. 添加React Native跟控制器

如果不添加React Native跟控制器,view将不能正常显示出来,实现方法如下:

// CustomKeyboard.m
#import "CustomKeyboard.h"
#import <React/RCTUtils.h>
@implementation CustomKeyboard
RCT_EXPORT_MODULE(KeybordPlugin);
@end
复制代码

引入<React/RCTUtils.h>之后,在视图初始化或者显示的时候,按照如下方法调用即可

UIViewController *vc = RCTPresentedViewController();
复制代码

4. 声明被JavaScript 调用的方法

React Native需要明确的声明要给 JavaScript 导出的方法,否则 React Native 不会导出任何方法。声明通过RCT_EXPORT_METHOD()宏来实现:

// CustomKeyboard.m
#import "CustomKeyboard.h"
#import <React/RCTUtils.h>
@implementation CustomKeyboard
RCT_EXPORT_MODULE(KeybordPlugin);
RCT_EXPORT_METHOD(onKeyboard:(NSDictionary *)arguments
                  :(RCTResponseSenderBlock)sucessCallback
                  :(RCTResponseSenderBlock)failCallback)
{
    NSLog(@"调起原生密码键盘方法");
}
@end
复制代码

5. 新建数字键盘FBYNumKeyBord类,实现相应视图及功能

在数字键盘FBYNumKeyBord类中,视图包含0-9数字按钮、ABC字母切换按钮、@%#特殊字符切换按钮、回删按钮、完成按钮和取消按钮。 实现相应按钮的点击功能以及实现随机键盘和非随机键盘两种模式。 效果图:

React Native 原生密码键盘插件

核心代码如下:

//FBYNumKeyBord.m
- (void)setRandom:(BOOL)random{
    _random = random;
    if (random) {
        NSMutableArray *newArray = [NSMutableArray arrayWithArray:self.numArray];
        for(int i = 0; i< self.numArray.count; i++)
        {
            int m = (arc4random() % (self.numArray.count - i)) + i;
            [newArray exchangeObjectAtIndex:i withObjectAtIndex: m];
        }
        self.numArray = newArray;
        for (UIButton *btn in self.subviews) {
            [btn removeFromSuperview];
        }
        [self addControl];
    }
}
复制代码

6. 新建字母键盘FBYWordKeyBord类,实现相应视图及功能

在数字键盘FBYWordKeyBord类中,视图包含26个字母按钮、大小写切换按钮、123数字键盘切换按钮、@%#特殊字符切换按钮、回删按钮、完成按钮和取消按钮。 实现相应按钮的点击功能以及实现随机键盘和非随机键盘两种模式。 效果图:

React Native 原生密码键盘插件

核心代码如下:

//FBYWordKeyBord.m
for (int i = 0; i< 26; i++) {
        FBYCustomKeyBordButton *btn = [FBYCustomKeyBordButton buttonWithTitle:self.wordArray[i] tag:i delegate:self];
        [btn addTarget:self action:@selector(btnTouchDown:) forControlEvents:(UIControlEventTouchDown)];
         [btn addTarget:self action:@selector(btnTouchCancel:) forControlEvents:(UIControlEventTouchUpInside)];
        [btn addTarget:self action:@selector(btnTouchCancel:) forControlEvents:(UIControlEventTouchUpOutside)];
         [btn addTarget:self action:@selector(btnTouchCancel:) forControlEvents:(UIControlEventTouchCancel)];
        [btnArray addObject:btn];
        [self addSubview:btn];
    }
复制代码

7. 新建纯数字键盘FBYNumOnlyKeyBord类,实现相应视图及功能

在数字键盘FBYNumOnlyKeyBord类中,视图包含0-9数字按钮、回删按钮、完成按钮和取消按钮。 实现相应按钮的点击功能以及实现随机键盘和非随机键盘两种模式。 效果图:

React Native 原生密码键盘插件

核心代码如下:

//FBYNumOnlyKeyBord.m
for (int i=0;i<self.btnArray.count;i++) {
        UIButton *btn =self.btnArray[i];
        if(i<9){
            btn.frame = CGRectMake(btn.tag % 3 * (btnW ), btn.tag / 3 * (btnH ), btnW, btnH);
        }else if (i==9){
            btn.frame = CGRectMake( 1 * (btnW ),  3* (btnH ), btnW, btnH);
        }else if (i==10){
            btn.frame = CGRectMake( 0* (btnW ),  3* (btnH ) , btnW, btnH);
            
        }else if (i==11){
            btn.frame = CGRectMake( 2* (btnW ), 3* (btnH ), btnW, btnH);
        }else if (i==12){
            btn.frame = CGRectMake( 0* (btnW ), 3* (btnH ), btnW, btnH);
        }  
    }
复制代码

8. 新建符号键盘FBYSymbolKeyBord类,实现相应视图及功能

在数字键盘FBYSymbolKeyBord类中,视图包含30种特殊字符按钮、123数字键盘切换按钮、ABC字母切换按钮、回删按钮、完成按钮和取消按钮。 实现相应按钮的点击功能以及实现随机键盘和非随机键盘两种模式。 效果图:

React Native 原生密码键盘插件

核心代码如下:

//FBYSymbolKeyBord.m
- (NSArray *)symbolArray{
    if (!_symbolArray) {
        _symbolArray = @[@"*",@"/",@":",@";",@"(",@")",@"[",@"]",@"$",@"=",@"!",@"^",@"&",@"%",@"+",@"-",@"¥",@"?",@"{",@"}",@"#",@"_",@"\\",@"|",@"~",@"`",@"∑",@"€",@"£",@"。"];
    }
    return _symbolArray;
}

- (void)addControl{
    NSMutableArray *btnArray = [NSMutableArray array];
    for (int i = 0; i < 30; i++) {
        FBYCustomKeyBordButton *btn = [FBYCustomKeyBordButton buttonWithTitle:self.symbolArray[i] tag:i delegate:self];
        [btn addTarget:self action:@selector(btnTouchDown:) forControlEvents:(UIControlEventTouchDown)];
        [btn addTarget:self action:@selector(btnTouchCancel:) forControlEvents:(UIControlEventTouchUpInside)];
        [btn addTarget:self action:@selector(btnTouchCancel:) forControlEvents:(UIControlEventTouchUpOutside)];
        [btn addTarget:self action:@selector(btnTouchCancel:) forControlEvents:(UIControlEventTouchCancel)];
        [self addSubview:btn];
        [btnArray addObject:btn];
    }
}
复制代码

9. 新建FBYCustomKeyBord类,实现键盘类型切换功能

FBYCustomKeyBord类中根据JS调用键盘时传入的参数,来实现何种键盘模式,实现键盘类型,共有6种类型:数字及字母、字母及数字、数字及字母特殊字符、字母及数字特殊字符、仅数字、仅字母。 键盘视图显示类型,共包括5种类型:普通、文本框、密码、支付密码格、无标题。 核心代码如下:

-(void)setKeybordType:(FBYCustomKeyBordType)keybordType{
    _keybordType=keybordType;
    [self.numPad removeFromSuperview];
    if(_keybordType==FBYCustomKeyBordType_NumWord){
        self.numPad.random=self.random;
        self.numPad.delegate=self;
        [self addSubview:self.numPad];
    }else if(_keybordType==FBYCustomKeyBordType_WordNum){
        self.wordPad.random=self.random;
        self.wordPad.delegate=self;
        [self addSubview:self.wordPad];
    }else if(_keybordType==FBYCustomKeyBordType_Num){
        self.numOnlyPad.random=self.random;
        self.numOnlyPad.delegate=self;
        [self addSubview:self.numOnlyPad];
    }else if(_keybordType==FBYCustomKeyBordType_NumWordSymbol){
        self.numPad.random=self.random;
        self.numPad.delegate=self;
        [self addSubview:self.numPad];
    }else if(_keybordType==FBYCustomKeyBordType_Word){
        self.wordPad.random=self.random;
        self.wordPad.delegate=self;
        [self addSubview:self.wordPad];
    }else if (keybordType==FBYCustomKeyBordType_WordNumSymbol){
        self.wordPad.random=self.random;
        self.wordPad.delegate=self;
        [self addSubview:self.wordPad];
    }
}
复制代码

10. 实现根据密码判断密码强度和长度功能

根据密码字符串获取其长度,代码如下:

//FBYCustomKeyBord.m
#pragma mark 长度计算
-(NSUInteger)messageLength:(NSString *)message{
    NSString *msg=[message copy];
    
    NSUInteger length= msg.length;
    NSLog(@"%lu",(unsigned long)length);
    return length;
}
复制代码

根据密码字符串message,通过正则校验,判断字符串中包含几种字符,进而判断其密码强度。 总共是数字、大写字母、小写字母、特殊字符四种状态,包含两种强度为弱,包含三种强度为中,包含四种强度为强,代码如下:

//FBYCustomKeyBord.m
#pragma mark 强度计算
-(NSUInteger)messageStrength:(NSString *)message{
    NSString *msg=[message copy];
    NSUInteger length= msg.length;
    BOOL capitalBool = NO;
    BOOL lowercaseBool = NO;
    BOOL numberBool = NO;
    BOOL stringBool = NO;
    NSString* result1;
    NSString* result2;
    NSString* result3;
    NSString* result4;
    for (int i = 0; i < length; i++) {
        char commitChar = [msg characterAtIndex:i];
        if((commitChar>64)&&(commitChar<91)){
            NSLog(@"字符串中含有大写英文字母");
            capitalBool = YES;
        }else if((commitChar>96)&&(commitChar<123)){
            NSLog(@"字符串中含有小写英文字母");
            lowercaseBool = YES;
        }else if((commitChar>47)&&(commitChar<58)){
            NSLog(@"字符串中含有数字");
            numberBool = YES;
        }else{
            NSLog(@"字符串中含有空格");
            stringBool = YES;
        }
    }
    result1 = [NSString stringWithFormat:@"%d",capitalBool];
    result2 = [NSString stringWithFormat:@"%d",lowercaseBool];
    result3 = [NSString stringWithFormat:@"%d",numberBool];
    result4 = [NSString stringWithFormat:@"%d",stringBool];
    
    NSMutableArray* resultArray = [[NSMutableArray alloc] init];
    [resultArray addObject:[NSString stringWithFormat:@"%@",result1]];
    [resultArray addObject:[NSString stringWithFormat:@"%@",result2]];
    [resultArray addObject:[NSString stringWithFormat:@"%@",result3]];
    [resultArray addObject:[NSString stringWithFormat:@"%@",result4]];
    int intResult=0;
    for (int j=0; j<[resultArray count]; j++)
    {
        if ([[resultArray objectAtIndex:j] isEqualToString:@"1"])
        {
            intResult++;
        }
    }
    NSUInteger result;
    if (intResult == 4){
        result = 3;
    }else if (intResult == 3){
        result = 2;
    }else if (intResult == 2){
        result = 1;
    }else{
        result = 0;
    }
    return result;
}
复制代码

11. 实现输出密码SM3加密功能

这里的密码加密采用的是国密SM3加密方式,代码如下:

#pragma mark 加密设置
-(NSString *)encryptMessage:(NSString *)message{
    NSString *msg=[message copy];
    return [self sm3:msg];
}

#pragma mark - 对字符串做sm3处理
- (NSString *) sm3:(NSString *) input
{
    NSData *inputData = [input dataUsingEncoding:NSUTF8StringEncoding];
    NSData *outputData = [CustomKBSM3Coded sm3_hashWithPainData:inputData];
    //NSString *outputString = [GTMBase64 stringByEncodingData:outputData];
    NSString *outputString = [self convertDataToHexStr:outputData];
    NSString *upper = [outputString uppercaseString];
    return upper;
}
复制代码

12. 根据传参打开浏览器

此浏览器插件支持打开自定义浏览器和打开默认浏览器,具体使用哪种方法打开浏览器,需要JavaScript通过arguments字典以字段的形式传过来,这里就使用openType字段。

// CustomKeyboard.m
#import "CustomKeyboard.h"
#import <React/RCTUtils.h>
@interface CustomKeyboard ()<FBYCustomKeyBordDelegate>
@property(strong,nonatomic)RCTResponseSenderBlock sucessCallback;
@property(strong,nonatomic)RCTResponseSenderBlock failCallback;
@property (nonatomic, strong) FBYCustomKeyBord *keyBoard;
@property(assign,nonatomic)FBYCustomKeyBordType keybordType;
@property(assign,nonatomic)FBYCustomKeyBordShowType keybordShowType;
@property(strong,nonatomic)NSString *tag;
@property(strong,nonatomic)NSString *isUp;
@end
@implementation CustomKeyboard
RCT_EXPORT_MODULE(KeybordPlugin);
RCT_EXPORT_METHOD(open:(NSDictionary *)arguments
                  withCompletionHandler:(RCTResponseSenderBlock)completion
                  failureHandler:(RCTResponseSenderBlock)failure)
{
    dispatch_async(dispatch_get_main_queue(), ^{
        self.keyBoard = [FBYCustomKeyBord instance];
        self.keyBoard.delegate = self;
        self.sucessCallback = sucessCallback;
        self.failCallback =  failCallback;
        NSString *isUp=@"1";
        NSString *isRandom=@"0";
        NSString *type=@"4";
        NSString *showType=@"0";
        NSString *isEncrypt=@"0";
        //是否是随机键盘
        self.keyBoard.random = YES;
        self.keybordType = FBYCustomKeyBordType_Num;   
        self.keybordShowType = FBYCustomKeyBordShowType_Common;     
        self.keyBoard.keybordType = self.keybordType;
        //弹起键盘或收起键盘
        self.keyBoard.keybordShowType = self.keybordShowType;
        dispatch_async(dispatch_get_main_queue(), ^{
            if ((isUp==nil) || isUp.intValue == 1) {
                [self.keyBoard popKeyBordInParent:RCTPresentedViewController()];
            } else {
                [self.keyBoard disappearSwitchBtnClickWithBlock:^{
                    self.sucessCallback(@[@{SucessReslutCode:@"1",SucessData:@"ok"}]);
                    CIBNSLog(@"成功调起密码键盘方法");
                }]; 
            }
        });
    });
}
//键盘数据回调
-(void)customKeybord:(FBYCustomKeyBord *)keybord didReturnMessage:(NSString *)message withLength:(NSUInteger)length withStrength:(NSUInteger)strength{
    if(self.tag == nil){
        self.tag = [CustomKeyboard getSecondTimeStringSince1970];
    }
    if (![self.isUp isEqualToString:@"0"]) {
        self.sucessCallback(@[@{SucessReslutCode:@"1",SucessData:@{@"pwdLength":[NSString stringWithFormat:@"%lu",(unsigned long)length],@"pwdStrong":[NSString stringWithFormat:@"%lu",strength],@"pwdValue":message}}]);
        NSLog(@"成功调起密码键盘方法");
    }
}

复制代码

13. Javascript调用浏览器方法

现在从 Javascript 里可以这样调用这个方法:

import { NativeModules } from "react-native";
const CustomkeyBoardPlugin = NativeModules.KeybordPlugin;
CustomkeyBoardPlugin.onKeyboard({isRandom:"1",isUp:"1",type:"4",showType:"3"},(msg) => {
                                         Alert.alert(JSON.stringify(msg));
                                         },(err) => {
                                         Alert.alert(JSON.stringify(err));
                                         });
复制代码

希望可以帮助大家,如有问题可加QQ技术交流群: 668562416

如果哪里有什么不对或者不足的地方,还望读者多多提意见或建议

如需转载请联系我,经过授权方可转载,谢谢

本篇已同步到个人博客:FBY展菲


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Building Web Reputation Systems

Building Web Reputation Systems

Randy Farmer、Bryce Glass / Yahoo Press / 2010 / GBP 31.99

What do Amazon's product reviews, eBay's feedback score system, Slashdot's Karma System, and Xbox Live's Achievements have in common? They're all examples of successful reputation systems that enable ......一起来看看 《Building Web Reputation Systems》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具