diff --git a/CHANGELOG-Unreleased.md b/CHANGELOG-Unreleased.md index 7005d1784..dbbbd9d5b 100644 --- a/CHANGELOG-Unreleased.md +++ b/CHANGELOG-Unreleased.md @@ -20,6 +20,8 @@ - [Android] Added linker flag for building with 16kB page alignment - [TS] make catchError visible to typescript - [LokiJS] Fixed `unsafeResetDatabase()` failing with "another operation is already in progress" when it's called while an autosave is in progress +- [iOS] Fixed compilation on React Native 0.88, which removed `RCTCxxBridge`; JSI is installed through the bridge or the bridgeless proxy alike +- [Android] Generate `BuildConfig` explicitly (AGP 9 no longer does for libraries) and stop applying the unused Kotlin plugin, which collides with AGP 9's built-in Kotlin support - [SQLite] [iOS] Database setup failures on the legacy (non-JSI) bridge (database cannot be opened, schema setup or migration fails) now reject the promise and reach `onSetUpError` instead of raising an `NSException` that crashes the app - [SQLite] [iOS] [Android] After a failed schema setup or migration on the legacy (non-JSI) bridge, operations queued during setup are rejected with the setup error and the driver stays connected, so the app can recover with `database.unsafeResetDatabase()` instead of every call hanging (iOS) or being rejected with "No driver with tag N available" (Android). The Node.js SQLite bridge (`sqlite-node`) behaves the same way diff --git a/native/android/build.gradle b/native/android/build.gradle index a45cfe0b6..5f723c3f9 100644 --- a/native/android/build.gradle +++ b/native/android/build.gradle @@ -7,18 +7,11 @@ buildscript { ext.getExtOrIntegerDefault = {name -> return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['ReactNativeWatermelonDB_' + name]).toInteger() } - - repositories { - mavenCentral() - } - - dependencies { - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}") - } } +// The module has no Kotlin sources anymore, so the Kotlin Gradle plugin is not applied: +// AGP 9 registers its own `kotlin` extension and fails when a plugin applies it again. apply plugin: 'com.android.library' -apply plugin: 'kotlin-android' android { compileSdkVersion getExtOrIntegerDefault('compileSdkVersion') @@ -32,12 +25,17 @@ android { versionCode 1 versionName "1.0" } + + // AGP 9 stops generating BuildConfig for library modules by default; + // the Java sources read BuildConfig.DEBUG + buildFeatures { + buildConfig true + } } dependencies { //noinspection GradleDynamicVersion implementation 'com.facebook.react:react-native:+' - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${getExtOrDefault('kotlinVersion')}" } repositories { diff --git a/native/android/gradle.properties b/native/android/gradle.properties index 777558da3..c791b5661 100644 --- a/native/android/gradle.properties +++ b/native/android/gradle.properties @@ -1,4 +1,3 @@ -ReactNativeWatermelonDB_kotlinVersion=1.3.50 ReactNativeWatermelonDB_compileSdkVersion=31 ReactNativeWatermelonDB_buildToolsVersion=28.0.3 ReactNativeWatermelonDB_targetSdkVersion=28 diff --git a/native/ios/WatermelonDB/JSIInstaller.h b/native/ios/WatermelonDB/JSIInstaller.h index c1b7efb0f..858183e7a 100644 --- a/native/ios/WatermelonDB/JSIInstaller.h +++ b/native/ios/WatermelonDB/JSIInstaller.h @@ -1,13 +1,13 @@ #pragma once -#import +#import #ifdef __cplusplus extern "C" { #endif -void installWatermelonJSI(RCTCxxBridge *bridge); +void installWatermelonJSI(RCTBridge *bridge); void watermelondbProvideSyncJson(int id, NSData *json, NSError **errorPtr); #ifdef __cplusplus diff --git a/native/ios/WatermelonDB/JSIInstaller.mm b/native/ios/WatermelonDB/JSIInstaller.mm index d50824973..6694f77d9 100644 --- a/native/ios/WatermelonDB/JSIInstaller.mm +++ b/native/ios/WatermelonDB/JSIInstaller.mm @@ -1,7 +1,14 @@ #import "JSIInstaller.h" #import "Database.h" -extern "C" void installWatermelonJSI(RCTCxxBridge *bridge) { +// React Native 0.88 removed RCTCxxBridge (and its declaration in RCTBridge+Private.h). +// Both the legacy RCTCxxBridge and the bridgeless RCTBridgeProxy still respond to -runtime, +// so the installer takes a plain RCTBridge and declares the selector itself. +@interface RCTBridge (WatermelonJSIRuntime) +- (void *)runtime; +@end + +extern "C" void installWatermelonJSI(RCTBridge *bridge) { if (bridge.runtime == nullptr) { return; } diff --git a/native/ios/WatermelonDB/objc/WMDatabaseBridge.m b/native/ios/WatermelonDB/objc/WMDatabaseBridge.m index 353204139..ba4a6b367 100644 --- a/native/ios/WatermelonDB/objc/WMDatabaseBridge.m +++ b/native/ios/WatermelonDB/objc/WMDatabaseBridge.m @@ -206,7 +206,7 @@ + (BOOL) requiresMainQueueSetup RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(initializeJSI) { - __block RCTCxxBridge *bridge = (RCTCxxBridge *) _bridge; + __block RCTBridge *bridge = _bridge; dispatch_sync([self methodQueue], ^{ installWatermelonJSI(bridge); });