一:介紹
React Native (簡稱RN)是Facebook于2015年4月開源的跨平臺移動應用開發(fā)框架,是Facebook早先開源的JS框架 React 在原生移動應用平臺的衍生產物,目前支持iOS和安卓兩大平臺。RN使用Javascript語言,類似于HTML的JSX,以及CSS來開發(fā)移動應用,因此熟悉Web前端開發(fā)的技術人員只需很少的學習就可以進入移動應用開發(fā)領域。
在React Native移動平臺項目開發(fā)中,除了React Native 提供的封裝好的部分插件和原聲組建外,在實際的項目中還需要使用到很多其他的插件,比如網絡請求、數據庫、相機、相冊、通訊錄、視頻播放器、瀏覽器、藍牙連接、圖片處理、消息推送、地圖、統(tǒng)計、埋點等等APP開發(fā)中需要用到的功能,都為IDE開發(fā)平臺提供封裝好的插件,以便項目開發(fā)使用。
另外,這些博文都是來源于我日常開發(fā)中的技術總結,在時間允許的情況下,我會針對技術點分別分享iOS、Android兩個版本,如果有其他技術點需要,可在文章后留言,我會盡全力幫助大家。這篇文章重點介紹FMDB數據庫插件的開發(fā)與使用
源碼Demo獲取方法
如果需要React Native FMDB數據庫插件源碼demo,歡迎關注 【網羅開發(fā)】微信公眾號,回復【64】便可領取。
網羅天下方法,方便你我開發(fā),所有文檔會持續(xù)更新,歡迎關注一起成長!
二:實現思路分析
FMDB數據庫插件是需要實現數據的新增、查詢、修改、刪除等功能,通過querySQLite方法來實現數據的查詢,并將接口提供給Javascript開發(fā)使用
打開默認瀏覽器和打開自定義瀏覽器,具體的實現思路如下:
新建DataBasePlugin類,實現RCTBridgeModule協(xié)議
添加RCT_EXPORT_MODULE()宏
添加React Native跟控制器
聲明被JavaScript 調用的方法
判斷數據庫語句,適合使用那個數據庫方法
創(chuàng)建數據庫DataBase.db
打開數據庫
執(zhí)行sql語句
Javascript調用瀏覽器方法
三:實現源碼分析
1. 新建DataBasePlugin類,實現RCTBridgeModule協(xié)議
新建繼承NSObject的DataBasePlugin類,并實現RCTBridgeModule協(xié)議
// DataBasePlugin.h
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import <UIKit/UIKit.h>
@interface DataBasePlugin : NSObject<RCTBridgeModule>
@end
2. 添加RCT_EXPORT_MODULE()宏
為了實現RCTBridgeModule協(xié)議,DataBasePlugin的類需要包含RCT_EXPORT_MODULE()宏。
并在這個宏里面添加一個參數“DataBasePlugin”用來指定在 JavaScript 中訪問這個模塊的名字。
如果你不指定,默認就會使用這個 Objective-C 類的名字。
如果類名以 RCT 開頭,則 JavaScript 端引入的模塊名會自動移除這個前綴。
// DataBasePlugin.m
#import "DataBasePlugin.h"
@implementation DataBasePlugin
RCT_EXPORT_MODULE(DataBasePlugin);
@end
3. 添加React Native跟控制器
如果不添加React Native跟控制器,view將不能正常顯示出來,實現方法如下:
// DataBasePlugin.m
#import "DataBasePlugin.h"
#import <React/RCTUtils.h>
@implementation DataBasePlugin
RCT_EXPORT_MODULE(DataBasePlugin);
@end
引入<React/RCTUtils.h>之后,在視圖初始化或者顯示的時候,按照如下方法調用即可
UIViewController *vc = RCTPresentedViewController();
4. 聲明被JavaScript 調用的方法
React Native需要明確的聲明要給 JavaScript 導出的方法,否則 React Native 不會導出任何方法。聲明通過RCT_EXPORT_METHOD()宏來實現:
// DataBasePlugin.m
#import "DataBasePlugin.h"
#import <React/RCTUtils.h>
@implementation DataBasePlugin
RCT_EXPORT_MODULE(DataBasePlugin);
RCT_EXPORT_METHOD(execSQLite:(NSDictionary *)arguments
withCompletionHandler:(RCTResponseSenderBlock)completion
failureHandler:(RCTResponseSenderBlock)failure)
{
NSLog(@"數據庫常用語句執(zhí)行方法");
}
RCT_EXPORT_METHOD(querySQLite:(NSDictionary *)arguments
withCompletionHandler:(RCTResponseSenderBlock)completion
failureHandler:(RCTResponseSenderBlock)failure)
{
NSLog(@"數據庫查詢語句執(zhí)行方法");
}
@end
5. 判斷數據庫語句,適合使用那個數據庫方法
由于數據庫查詢語句中的查詢參數,需要通過接口傳入,并不是和sql語句一起傳入,所以需要進行拼接,這就需要用到數據庫查詢方法querySQLite,因為查詢語句中包含select字符串,因此作出如下判斷:
核心代碼如下:
if([arguments[@"sql"] rangeOfString:@"select"].location !=NSNotFound)
{
failure(@[@{@"resultCode":@"0",@"resultMessage":@"請使用查詢方法querySQLite進行查詢"}]);
}
6. 創(chuàng)建數據庫DataBase.db
在導入第三方FMDB庫之后,需要在DataBasePlugin.m引入:
#import "FMDatabase.h"
實現數據庫的第一步,創(chuàng)建數據表,源碼如下:
- (FMDatabase *)db
{
if (!_db) {
NSString *path = [[self getDocumentPath] stringByAppendingPathComponent:@"DataBase.db"];
_db = [FMDatabase databaseWithPath:path];
}
return _db;
}
7. 打開數據庫
判斷數據庫表是否已創(chuàng)建,如果創(chuàng)建成功,或者已經存在數據表,即可打開數據庫,源碼如下:
if (self.db) {
if ([self.db open]) {
} else {
failure(@[@{@"resultCode":@"-1",@"resultMessage":@"打開數據庫失敗"}]);
}
}else{
failure(@[@{@"resultCode":@"-1",@"resultMessage":@"數據庫創(chuàng)建失敗"}]);
}
8. 執(zhí)行sql語句
在創(chuàng)建數據表和打開數據庫成功之后,對Javascript傳入的sql數據庫語句進行處理執(zhí)行,源碼如下:
BOOL result = [self.db executeUpdate:sqlString];
if (result) {
completion(@[@{@"status":@"1",@"data":@"執(zhí)行SQL成功"}]);
} else {
failure(@[@{@"resultCode":@"-1",@"resultMessage":@"執(zhí)行SQL失敗"}]);
}
9. Javascript調用瀏覽器方法
現在從 Javascript 里可以這樣調用這個方法:
import { NativeModules } from "react-native";
const DataBasePlugin = NativeModules.DataBasePlugin;
DataBasePlugin.execSQLite({sql:"CREATE TABLE IF NOT EXISTS NotificatonTable (id integer PRIMARY KEY AUTOINCREMENT, status text NOT NULL, title text NOT NULL, content text NOT NULL, url text NOT NULL, time text NOT NULL, remark text NOT NULL)"},(msg) => {
Alert.alert(JSON.stringify(msg));
},(err) => {
Alert.alert(JSON.stringify(err));
});