一:介紹
React Native (簡(jiǎn)稱RN)是Facebook于2015年4月開源的跨平臺(tái)移動(dòng)應(yīng)用開發(fā)框架图柏,是Facebook早先開源的JS框架 React 在原生移動(dòng)應(yīng)用平臺(tái)的衍生產(chǎn)物哺窄,目前支持iOS和安卓?jī)纱笃脚_(tái)骑科。RN使用Javascript語言俘种,類似于HTML的JSX阳似,以及CSS來開發(fā)移動(dòng)應(yīng)用叨粘,因此熟悉Web前端開發(fā)的技術(shù)人員只需很少的學(xué)習(xí)就可以進(jìn)入移動(dòng)應(yīng)用開發(fā)領(lǐng)域晤揣。
在React Native移動(dòng)平臺(tái)項(xiàng)目開發(fā)中,除了React Native 提供的封裝好的部分插件和原聲組建外纳击,在實(shí)際的項(xiàng)目中還需要使用到很多其他的插件续扔,比如網(wǎng)絡(luò)請(qǐng)求、數(shù)據(jù)庫评疗、相機(jī)测砂、相冊(cè)、通訊錄百匆、視頻播放器、瀏覽器呜投、藍(lán)牙連接加匈、圖片處理、消息推送仑荐、地圖雕拼、統(tǒng)計(jì)、埋點(diǎn)等等APP開發(fā)中需要用到的功能粘招,都為IDE開發(fā)平臺(tái)提供封裝好的插件啥寇,以便項(xiàng)目開發(fā)使用。
另外洒扎,這些博文都是來源于我日常開發(fā)中的技術(shù)總結(jié)辑甜,在時(shí)間允許的情況下,我會(huì)針對(duì)技術(shù)點(diǎn)分別分享iOS袍冷、Android兩個(gè)版本磷醋,如果有其他技術(shù)點(diǎn)需要,可在文章后留言胡诗,我會(huì)盡全力幫助大家邓线。這篇文章重點(diǎn)介紹手勢(shì)密碼插件的開發(fā)與使用
源碼Demo獲取方法
如果需要React Native手勢(shì)密碼插件源碼demo,歡迎關(guān)注 【網(wǎng)羅開發(fā)】微信公眾號(hào)煌恢,回復(fù)【66】便可領(lǐng)取骇陈。
網(wǎng)羅天下方法,方便你我開發(fā)瑰抵,所有文檔會(huì)持續(xù)更新你雌,歡迎關(guān)注一起成長(zhǎng)!
二:實(shí)現(xiàn)思路分析
手勢(shì)密碼插件是需要實(shí)現(xiàn)可視頁面控制器谍憔、設(shè)置手勢(shì)密碼匪蝙、驗(yàn)證手勢(shì)密碼主籍、密碼sm3加密、密碼本地保存等功能逛球,這些功能加通過在PwdLockPlugin類中封裝的SetPwdLock方法和DecryptLock方法來提供給Javascript開發(fā)使用千元。
具體的實(shí)現(xiàn)思路如下:
新建PwdLockPlugin類,實(shí)現(xiàn)RCTBridgeModule協(xié)議
添加RCT_EXPORT_MODULE()宏
添加React Native跟控制器
聲明被JavaScript 調(diào)用的方法
新建設(shè)置密碼控制器
新建驗(yàn)證密碼控制器
設(shè)置手勢(shì)密碼
驗(yàn)證手勢(shì)密碼
密碼sm3加密
Javascript調(diào)用瀏覽器方法
三:實(shí)現(xiàn)源碼分析
實(shí)現(xiàn)源碼分析是根據(jù)上面列出的具體實(shí)現(xiàn)思路來為大家解刨內(nèi)部的實(shí)現(xiàn)流程及核心代碼分析颤绕。
1. 新建PwdLockPlugin類幸海,實(shí)現(xiàn)RCTBridgeModule協(xié)議
新建繼承NSObject的PwdLockPlugin類,并實(shí)現(xiàn)RCTBridgeModule協(xié)議
// PwdLockPlugin.h
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import <UIKit/UIKit.h>
@interface PwdLockPlugin : NSObject<RCTBridgeModule>
@end
2. 添加RCT_EXPORT_MODULE()宏
為了實(shí)現(xiàn)RCTBridgeModule協(xié)議奥务,PwdLockPlugin的類需要包含RCT_EXPORT_MODULE()宏物独。
并在這個(gè)宏里面添加一個(gè)參數(shù)“PwdLockPlugin”用來指定在 JavaScript 中訪問這個(gè)模塊的名字。
如果你不指定氯葬,默認(rèn)就會(huì)使用這個(gè) Objective-C 類的名字挡篓。
如果類名以 RCT 開頭,則 JavaScript 端引入的模塊名會(huì)自動(dòng)移除這個(gè)前綴帚称。
// PwdLockPlugin.m
#import "PwdLockPlugin.h"
@implementation PwdLockPlugin
RCT_EXPORT_MODULE(PwdLockPlugin);
@end
3. 添加React Native跟控制器
如果不添加React Native跟控制器官研,view將不能正常顯示出來,實(shí)現(xiàn)方法如下:
// PwdLockPlugin.m
#import <React/RCTUtils.h>
引入<React/RCTUtils.h>之后闯睹,在視圖初始化或者顯示的時(shí)候戏羽,按照如下方法調(diào)用即可
UIViewController *vc = RCTPresentedViewController();
4. 聲明被JavaScript 調(diào)用的方法
React Native需要明確的聲明要給 JavaScript 導(dǎo)出的方法,否則 React Native 不會(huì)導(dǎo)出任何方法楼吃。下面通過舉例來展示聲明的方法始花,通過RCT_EXPORT_METHOD()宏來實(shí)現(xiàn):
// PwdLockPlugin.m
#import "PwdLockPlugin.h"
#import <React/RCTUtils.h>
@implementation PwdLockPlugin
RCT_EXPORT_MODULE(PwdLockPlugin);
//設(shè)置手勢(shì)密碼
RCT_EXPORT_METHOD(SetPwdLock:(RCTResponseSenderBlock)sucessCallback failCallback:(RCTResponseSenderBlock)failCallback)
{
NSLog(@"調(diào)起設(shè)置密碼方法");
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{
[CLLockVC showSettingLockVCInVC:RCTPresentedViewController() successBlock:^(CLLockVC *lockVC, NSString *pwd) {
[lockVC dismiss:0.0f];
sucessCallback(@[@{@"status":@"1",@"data":@"密碼設(shè)置成功"}]);
NSLog(@"%@",[self jsonStringWithDict:@{@"status":@"1",@"data":@"密碼設(shè)置成功"}]);
//存儲(chǔ)密碼
pwd = [CLLockVC sm3:pwd];
[CoreArchive setStr:pwd key:CoreLockPWDKey];
}];
});
}
//驗(yàn)證手勢(shì)密碼
RCT_EXPORT_METHOD(DecryptLock:(RCTResponseSenderBlock)sucessCallback failCallback:(RCTResponseSenderBlock)failCallback)
{
NSLog(@"調(diào)起驗(yàn)證密碼方法");
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{
[CLLockVC showVerifyLockVCInVC:RCTPresentedViewController() forgetPwdBlock:^{
failCallback(@[@{@"resultCode":@"-1",@"resultMessage":@"手勢(shì)密碼三次驗(yàn)證失敗"}]);
} successBlock:^(CLLockVC *lockVC, NSString *pwd) {
[lockVC dismiss:0.0f];
sucessCallback(@[@{@"status":@"1",@"data":@"手勢(shì)密碼驗(yàn)證成功"}]);
}];
});
}
@end
5. 新建設(shè)置密碼控制器
設(shè)置密碼控制器是由3乘3的9個(gè)可觸摸按鈕實(shí)現(xiàn),用戶可以通過滑動(dòng)屏幕來觸動(dòng)屏幕按鈕孩锡,每個(gè)按鈕有自己特有的編號(hào)(編號(hào)為0-9)酷宵,通過觸動(dòng)按鈕的先后順序來記錄手勢(shì)密碼,并將密碼存儲(chǔ)在本地浮创。
核心源碼如下:
+(instancetype)showSettingLockVCInVC:(UIViewController *)vc successBlock:(void(^)(CLLockVC *lockVC,NSString *pwd))successBlock{
CLLockVC *lockVC = [self lockVC:vc];
lockVC.title = @"設(shè)置密碼";
lockVC.type = CoreLockTypeSetPwd;
lockVC.successBlock = successBlock;
return lockVC;
}
效果如下圖:
6. 新建驗(yàn)證密碼控制器
驗(yàn)證密碼控制器是由3乘3的9個(gè)可觸摸按鈕實(shí)現(xiàn)忧吟,用戶可以通過滑動(dòng)屏幕來觸動(dòng)屏幕按鈕,每個(gè)按鈕有自己特有的編號(hào)(編號(hào)為0-9)斩披,通過觸動(dòng)按鈕的先后順序來記錄手勢(shì)密碼溜族,通過和本地存儲(chǔ)的密碼進(jìn)行對(duì)比驗(yàn)證是否一致,判斷是否通過驗(yàn)證垦沉。
核心源碼如下:
+(instancetype)showVerifyLockVCInVC:(UIViewController *)vc forgetPwdBlock:(void(^)())forgetPwdBlock successBlock:(void(^)(CLLockVC *lockVC, NSString *pwd))successBlock{
CLLockVC *lockVC = [self lockVC:vc];
lockVC.title = @"手勢(shì)解鎖";
lockVC.type = CoreLockTypeVeryfiPwd;
lockVC.successBlock = successBlock;
lockVC.forgetPwdBlock = forgetPwdBlock;
return lockVC;
}
效果如下圖:
7. 設(shè)置手勢(shì)密碼
設(shè)置手勢(shì)密碼的滑動(dòng)實(shí)現(xiàn)流程如下:
- 第一次滑動(dòng)設(shè)置
- 再次確認(rèn)滑動(dòng)設(shè)置
- 檢測(cè)密碼長(zhǎng)度是否符合要求(至少為四個(gè)點(diǎn))
- 判斷兩次設(shè)置的密碼是否一致
- 如果密碼一致提示設(shè)置成功
- 如果不一致提示再次輸入
- 將密碼存儲(chǔ)在本地
核心源碼如下:
//第一次滑動(dòng)設(shè)置
self.lockView.setPWBeginBlock = ^(){
[self.label showNormalMsg:CoreLockPWDTitleFirst];
};
//再次確認(rèn)滑動(dòng)設(shè)置
self.lockView.setPWConfirmlock = ^(){
[self.label showNormalMsg:CoreLockPWDTitleConfirm];
};
//檢測(cè)密碼長(zhǎng)度是否符合要求(至少為四個(gè)點(diǎn))
self.lockView.setPWSErrorLengthTooShortBlock = ^(NSUInteger currentCount){
[self.label showWarnMsg:[NSString stringWithFormat:@"請(qǐng)連接至少%@個(gè)點(diǎn)",@(CoreLockMinItemCount)]];
};
//判斷兩次設(shè)置的密碼是否一致
self.lockView.setPWSErrorTwiceDiffBlock = ^(NSString *pwd1,NSString *pwdNow){
[self.label showWarnMsg:CoreLockPWDDiffTitle];
self.navigationItem.rightBarButtonItem = self.resetItem;
};
//如果密碼一致提示設(shè)置成功
self.lockView.setPWFirstRightBlock = ^(){
[self.label showNormalMsg:CoreLockPWDTitleConfirm];
};
//如果不一致提示再次輸入
self.lockView.setPWTwiceSameBlock = ^(NSString *pwd){
[self.label showNormalMsg:CoreLockPWSuccessTitle];
//將密碼存儲(chǔ)在本地
[CoreArchive setStr:pwd key:CoreLockPWDKey];
self.view.userInteractionEnabled = NO;
if(_successBlock != nil) _successBlock(self,pwd);
if(CoreLockTypeModifyPwd == _type){
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.navigationController popViewControllerAnimated:YES];
});
}
};
8. 驗(yàn)證手勢(shì)密碼
驗(yàn)證手勢(shì)密碼的滑動(dòng)實(shí)現(xiàn)流程如下:
- 滑動(dòng)輸入密碼
- 檢測(cè)密碼長(zhǎng)度是否符合要求(至少為四個(gè)點(diǎn))
- 取出本地存儲(chǔ)的密碼
- 判斷輸入的密碼和本地密碼是否一致
- 如果一致返回驗(yàn)證成功
- 如果不一致提示重新驗(yàn)證
核心源碼如下:
//滑動(dòng)輸入密碼
self.lockView.verifyPWBeginBlock = ^(){
[self.label showNormalMsg:CoreLockVerifyNormalTitle];
};
//檢測(cè)密碼長(zhǎng)度是否符合要求(至少為四個(gè)點(diǎn))
self.lockView.verifyPwdBlock = ^(NSString *pwd){
//取出本地存儲(chǔ)的密碼
NSString *pwdLocal = [CoreArchive strForKey:CoreLockPWDKey];
BOOL res = [pwdLocal isEqualToString:pwd];
//判斷輸入的密碼和本地密碼是否一致
if(res){
[self.label showNormalMsg:CoreLockVerifySuccesslTitle];
}else{
[self.label showWarnMsg:CoreLockVerifyErrorPwdTitle];
}
return res;
};
9. 密碼sm3加密
對(duì)密碼進(jìn)行sm3加密煌抒,可以保證密碼在傳輸過程中安全傳輸,實(shí)現(xiàn)源碼如下:
+ (NSString *) sm3:(NSString *) input
{
NSData *inputData = [input dataUsingEncoding:NSUTF8StringEncoding];
NSData *outputData = [PwdLockSM3Coded sm3_hashWithPainData:inputData];
NSString *outputString = [CLLockVC convertDataToHexStr:outputData];
NSString *upper = [outputString uppercaseString];
return upper;
}
10. Javascript調(diào)用瀏覽器方法
現(xiàn)在從 Javascript 里可以這樣調(diào)用這個(gè)方法:
import { NativeModules } from "react-native";
const PwdLockPlugin = NativeModules.PwdLockPlugin;
//設(shè)置手勢(shì)密碼
PwdlockPlugin.SetPwdLock((msg) => {
Alert.alert(JSON.stringify(msg));
},(err) => {
Alert.alert(JSON.stringify(err));
});
//驗(yàn)證手勢(shì)密碼
PwdlockPlugin.DecryptLock((msg) => {
Alert.alert(JSON.stringify(msg));
},(err) => {
Alert.alert(JSON.stringify(err));
});