我正在尝试使用
expo-sqlite
加载预先存在的数据库。它在 Android 上运行得很好,但在 iOS 上我遇到了一些问题。
我打开DB的代码如下:
return (
<>
<SQLiteProvider databaseName="@/data/products.db" assetSource={{ assetId: require('@/data/products.db') }}>
<ResultRenderer profile={profile} />
<Text>{buildSQLquery(profile)}</Text>
</SQLiteProvider>
</>
);
但是,在 iOS 上,这只会抛出:
ERROR Error: The file “ExponentAsset-171a7c1e81bf6393675b790dec0140a7.db” doesn’t exist.
This error is located at:
in SQLiteProviderNonSuspense (created by SQLiteProvider)
in SQLiteProvider (created by RenderScreen)
in RenderScreen
in Unknown (created by Route((results)/results))
in Suspense (created by Route((results)/results))
in Route (created by Route((results)/results))
in Route((results)/results) (created by SceneView)
in StaticContainer
in EnsureSingleNavigator (created by SceneView)
in SceneView (created by SceneView)
in RCTView (created by View)
in View (created by DebugContainer)
in DebugContainer (created by MaybeNestedStack)
in MaybeNestedStack (created by SceneView)
in RCTView (created by View)
in View (created by SceneView)
in RNSScreen (created by Animated(Anonymous))
in Animated(Anonymous) (created by InnerScreen)
in Suspender (created by Freeze)
in Suspense (created by Freeze)
in Freeze (created by DelayedFreeze)
in DelayedFreeze (created by InnerScreen)
in InnerScreen (created by Screen)
in Screen (created by SceneView)
in SceneView (created by NativeStackViewInner)
in Suspender (created by Freeze)
in Suspense (created by Freeze)
in Freeze (created by DelayedFreeze)
in DelayedFreeze (created by ScreenStack)
in RNSScreenStack (created by ScreenStack)
in ScreenStack (created by NativeStackViewInner)
in NativeStackViewInner (created by NativeStackView)
in RCTView (created by View)
in View (created by SafeAreaProviderCompat)
in SafeAreaProviderCompat (created by NativeStackView)
in NativeStackView (created by NativeStackNavigator)
in PreventRemoveProvider (created by NavigationContent)
in NavigationContent
in Unknown (created by NativeStackNavigator)
in NativeStackNavigator
in Unknown (created by RootLayout)
in ThemeProvider (created by RootLayout)
in RootLayout
in Unknown (created by Route())
in Suspense (created by Route())
in Route (created by Route())
in Route() (created by ContextNavigator)
in RNCSafeAreaProvider (created by SafeAreaProvider)
in SafeAreaProvider (created by wrapper)
in wrapper (created by ContextNavigator)
in EnsureSingleNavigator
in BaseNavigationContainer
in ThemeProvider
in NavigationContainerInner (created by ContextNavigator)
in ContextNavigator (created by ExpoRoot)
in ExpoRoot (created by App)
in App (created by ErrorOverlay)
in ErrorToastContainer (created by ErrorOverlay)
in ErrorOverlay (created by withDevTools(ErrorOverlay))
in withDevTools(ErrorOverlay)
in RCTView (created by View)
in View (created by AppContainer)
in RCTView (created by View)
in View (created by AppContainer)
in AppContainer
in main(RootComponent), js engine: hermes
我不太知道这个文件名来自哪里,但我想知道如何解决这个问题。
我已经尝试使用此代码打开数据库:
const db = SQLite.openDatabaseSync("@/data/products.db", {});
const result = db.getAllSync("SELECT * from products")
console.log(result);
这奇怪地引发了另一个错误:
ERROR Error: FunctionCallException: Calling the 'initSync' function has failed (at ExpoModulesCore/SyncFunctionDefinition.swift:87)
→ Caused by: ArgumentCastException: The 1st argument cannot be cast to type SharedObject<NativeDatabase> (at ExpoModulesCore/JavaScriptUtils.swift:61)
→ Caused by: NativeSharedObjectNotFoundException: Unable to find the native shared object associated with given JavaScript object (at ExpoModulesCore/DynamicSharedObjectType.swift:58)
This error is located at:
in IntroScreen
in Unknown (created by Route((intro)/index))
in Suspense (created by Route((intro)/index))
in Route (created by Route((intro)/index))
in Route((intro)/index) (created by SceneView)
in StaticContainer
in EnsureSingleNavigator (created by SceneView)
in SceneView (created by SceneView)
in RCTView (created by View)
in View (created by DebugContainer)
in DebugContainer (created by MaybeNestedStack)
in MaybeNestedStack (created by SceneView)
in RCTView (created by View)
in View (created by SceneView)
in RNSScreen (created by Animated(Anonymous))
in Animated(Anonymous) (created by InnerScreen)
in Suspender (created by Freeze)
in Suspense (created by Freeze)
in Freeze (created by DelayedFreeze)
in DelayedFreeze (created by InnerScreen)
in InnerScreen (created by Screen)
in Screen (created by SceneView)
in SceneView (created by NativeStackViewInner)
in Suspender (created by Freeze)
in Suspense (created by Freeze)
in Freeze (created by DelayedFreeze)
in DelayedFreeze (created by ScreenStack)
in RNSScreenStack (created by ScreenStack)
in ScreenStack (created by NativeStackViewInner)
in NativeStackViewInner (created by NativeStackView)
in RCTView (created by View)
in View (created by SafeAreaProviderCompat)
in SafeAreaProviderCompat (created by NativeStackView)
in NativeStackView (created by NativeStackNavigator)
in PreventRemoveProvider (created by NavigationContent)
in NavigationContent
in Unknown (created by NativeStackNavigator)
in NativeStackNavigator
in Unknown (created by RootLayout)
in ThemeProvider (created by RootLayout)
in RootLayout
in Unknown (created by Route())
in Suspense (created by Route())
in Route (created by Route())
in Route() (created by ContextNavigator)
in RNCSafeAreaProvider (created by SafeAreaProvider)
in SafeAreaProvider (created by wrapper)
in wrapper (created by ContextNavigator)
in EnsureSingleNavigator
in BaseNavigationContainer
in ThemeProvider
in NavigationContainerInner (created by ContextNavigator)
in ContextNavigator (created by ExpoRoot)
in ExpoRoot (created by App)
in App (created by ErrorOverlay)
in ErrorToastContainer (created by ErrorOverlay)
in ErrorOverlay (created by withDevTools(ErrorOverlay))
in withDevTools(ErrorOverlay)
in RCTView (created by View)
in View (created by AppContainer)
in RCTView (created by View)
in View (created by AppContainer)
in AppContainer
in main(RootComponent), js engine: hermes
我对此感到非常困惑 - 你知道解决这个问题的方法吗?
我已经能够解决这个问题了。
如果遇到这种情况,你需要这样做:
resolver.assetExts
数组:const { getDefaultConfig } = require("expo/metro-config");
const config = getDefaultConfig(__dirname);
config.resolver.assetExts.push(
// Adds support for `.db` files for SQLite databases
"db"
);
module.exports = config;
assets
文件夹内databaseName
更改为文件名 - 而不是整个路径!以我的例子来说,它看起来像这样:<SQLiteProvider databaseName="products.db" assetSource={{ assetId: require('@/assets/databases/products.db') }}>
<ResultRenderer parsedProfile={parsedProfile} parsedFilter={parsedFilter} />
</SQLiteProvider>
我希望这对其他人有帮助。