react-native-sqlite-storage如何使用预置数据库

官方README.md中已经有详细的说明,见Pre-populated SQLite database import from application bundle and sandbox

按照作者的说法,需要创建一个叫做www的目录,并且强调必须是www才可以。
在这里插入图片描述
之后呢,就是添加到ios和android工程。按着说明都弄好了之后,作者给出了使用的示例代码如下:

1.SQLite.openDatabase({name : "testDB", createFromLocation : 1}, okCallback,errorCallback);
// default - if your folder is called www and data file is named the same as the dbName - testDB in this example
2.SQLite.openDatabase({name : "testDB", createFromLocation : "~data/mydbfile.sqlite"}, okCallback,errorCallback);
// if your folder is called data rather than www or your filename does not match the name of the db
3.SQLite.openDatabase({name : "testDB", createFromLocation : "/data/mydbfile.sqlite"}, okCallback,errorCallback);
// if your folder is not in app bundle but in app sandbox i.e. downloaded from some remote location.

我们先看第一行代码,作者注释说如果我们创建的文件夹是www,并且数据库名与文件名相同,就可以使用这种方式。这里没有什么问题。

我们再看第二行代码,作者注释说如果我们创建的文件夹是data而不是www,或者我们的数据库名和文件名不一致,就是用这种调用方式。

这样问题就来了,一开始作者说文件夹必须要以www命名,这里又表示可以使用data来命名,到底是怎么回事?另外,为什么要用www命名?是ios的限制还是android的限制?~又是什么鬼?为什么加这个符号?

虽然README.md里文字不少,可是关于这部分说的含含糊糊,另外我对必须使用www这个名字也很不满意。于是特意去查了下,发现ios和android下并没有这种限制,看来是作者自己加的。那只好去看源码了。

打开ios的相关源码node_modules/react-native-sqlite-storage/platforms/ios/SQLite.m,以下是代码片段:

NSString *assetFilePath = options[@"assetFilename"];
if (assetFilePath != NULL && assetFilePath.length > 0) {
  @try {
    if ([assetFilePath isEqualToString:@"1"]){
      NSString *targetBundleDirPath = [[NSBundle mainBundle] resourcePath];
      targetBundleDirPath = [targetBundleDirPath stringByAppendingPathComponent: @"www"];
      assetFilePath = [targetBundleDirPath stringByAppendingPathComponent: dbfilename];
      RCTLog(@"Built path to pre-populated DB asset from app bundle www subdirectory: %@",assetFilePath);
    } else if ([assetFilePath hasPrefix:@"~"]) {
      assetFilePath = [assetFilePath substringFromIndex:1];
      NSString *targetBundleDirPath = [[NSBundle mainBundle] resourcePath];
      assetFilePath = [targetBundleDirPath stringByAppendingPathComponent: assetFilePath];
      RCTLog(@"Built path to pre-populated DB asset from app bundle subdirectory: %@",assetFilePath);
    } else {
      NSURL * documentsDirUrl = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory
                                                                inDomains:NSUserDomainMask] lastObject];
      assetFilePath = [documentsDirUrl.path stringByAppendingPathComponent:assetFilePath];
      RCTLog(@"Built path to pre-populated DB asset from app sandbox documents directory: %@",assetFilePath);
    }
  } @catch(NSException *ex){
    RCTLog(@"Error building path for pre-populated DB asset %@",ex.reason);
  }
}

我们看到,果然是作者搞的鬼:

  • 如果createFromLocation值是1,则使用name的值作为数据库的名字,并且前面加上www构建出数据库文件路径。
  • 如果createFromLocation的值是以~开头,则使用~以后的值拼接出数据库的文件路径。

android的代码在node_modules/react-native-sqlite-storage/platforms/android-native/src/main/java/io/liteglue/SQLitePlugin.java中,实现逻辑类似,有兴趣的自己看下。

作者这样的实现,我觉得是不够有诚意的,完全没有必要使用www~。简单点,增加一个调用参数来标识是否使用包内数据库就可以了,也方便使用的人理解。

说归说,还是得用,不过明白了这里面的逻辑也能安心了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值