Solo  当前访客:0 开始使用

yf98🌕

用心工作,用爱生活。

【Expo小记】修复:使用预先准备的SqliteDB,Android真机与Expo Go正常,iOS模拟器与真机无法找到该数据库的问题:File not database.

这几天写了一个粤小词词典应用,打算做个离线版的,于是使用了自己的sqliteDB文件。

Android上一切正常,Expo Go调试正常,一到eas build iOS就文件不是数据库文件。

如果直接解析DB后缀的是没法使用的,更改一下Metro的配置,支持db文件,也可以项目使用其他的。

`

const { getDefaultConfig } = require('expo/metro-config');

const defaultConfig = getDefaultConfig(__dirname);

defaultConfig.resolver.assetExts.push('db');

module.exports = defaultConfig;

改完后,执行清理缓存的启动:

expo start -c

然后使用以下写法:

`

async function openDatabase(pathToDatabaseFile: string): Promise<SQLite.WebSQLDatabase> {
  if (!(await FileSystem.getInfoAsync(FileSystem.documentDirectory + 'SQLite')).exists) {
    await FileSystem.makeDirectoryAsync(FileSystem.documentDirectory + 'SQLite');
  }
  await FileSystem.downloadAsync(
    Asset.fromModule(require(pathToDatabaseFile)).uri,
    FileSystem.documentDirectory + 'SQLite/myDatabaseName.db'
  );
  return SQLite.openDatabase('myDatabaseName.db');
}

可以看到从资源文件里面解析出来db后,下载到本机(这里说一下:使用expo托管流的,会将资源文件托管到亚马逊的CDN上,在应用首次启动会下载下来)。

回到iOS真机上来,我使用模拟器,打开了模拟器的本地存储,发现实际上是有数据库文件的,但是似乎大小不正常,我的DB有3m,但是模拟器上下载下来的只有200kb,应该是下载的时候损坏了。所以导致不是一个db文件。于是我换了一下写法,使用了copy函数,从资源文件复制到本机,结果打包后还是不行,直接没有复制。

后来去官方论坛查看,非常多的人遇到自带db文件无法使用的问题,并且几乎没有官方人员解答,都是最后被关闭话题。其中一个是:使用hook,来监听文件下载完成后执行其他操作。这样可以避免下载问题导致的文件损坏,鉴于下载问题,我修改了一些逻辑,改成了不托管db文件,然后启动项目后从自带资源文件里复制。

`

  useEffect(() => {
        async function loadResourcesAndDataAsync() {
            try {
                SplashScreen.preventAutoHideAsync().catch((e) => console.log(e));
                const getDatabase = async (databaseAsset: Asset) => {
                    try {
                        if (!(await FileSystem.getInfoAsync(sqlDir)).exists) {
                            await FileSystem.makeDirectoryAsync(sqlDir);
                        }
                        await FileSystem.copyAsync({
                            //@ts-ignore
                            from: databaseAsset.localUri,
                            to: sqlDir + '/' + databaseName,
                        });

                        return SQLite.openDatabase(databaseName);
                    } catch (err) { /* Handle error */
                    }
                };

                if (assets && assets[0] && !assetsError) {
                    const databaseAsset = assets[0];
                    // @ts-ignore
                    ZenStore.db = await getDatabase(databaseAsset);
                }

            } catch (e) {
                // We might want to provide this error information to an error reporting service
                console.warn(e);
                alert(e.message);
                console.error(e)
            } finally {
                setLoadingComplete(true);
                SplashScreen.hideAsync();
            }
        }

        loadResourcesAndDataAsync();
    }, [assets]);

修改托管配置:app.json ,将db排除在外,因为我只托管图片所以将默认的*换成下面的就好了。

`

 "assetBundlePatterns": [
      "assets/images/*"
    ],

希望能帮助到遇到这个问题的小伙伴。

另外 粤小词语iOS上线啦:粤小词 Apple Store


标题:【Expo小记】修复:使用预先准备的SqliteDB,Android真机与Expo Go正常,iOS模拟器与真机无法找到该数据库的问题:File not database.
作者:yf_d
地址:看看我的CSDN

公告

今日诗词
微信:tel322ecdb2d