diff --git a/CHANGELOG.md b/CHANGELOG.md index 834e631..acdafb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [Unreleased] + +### Changes +- Upgrade Android SDK dependency to v2.14.2 +- Upgrade iOS SDK dependency to v2.14.3 + + ## [2.14.1] - 2025-09-12 ### Changes diff --git a/MindboxSdk.podspec b/MindboxSdk.podspec index 2b75735..f5a4ff3 100644 --- a/MindboxSdk.podspec +++ b/MindboxSdk.podspec @@ -17,6 +17,6 @@ Pod::Spec.new do |s| s.dependency "React-Core" - s.dependency "Mindbox", "2.14.1" - s.dependency "MindboxNotifications", "2.14.1" + s.dependency "Mindbox", "2.14.3" + s.dependency "MindboxNotifications", "2.14.3" end diff --git a/android/build.gradle b/android/build.gradle index b17b221..239b3da 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -33,6 +33,7 @@ android { targetSdkVersion getExtOrIntegerDefault('targetSdkVersion') versionCode 1 versionName "1.0" + consumerProguardFiles 'consumer-rules.pro' } buildTypes { @@ -126,5 +127,5 @@ dependencies { // noinspection GradleDynamicVersion api 'com.facebook.react:react-native:+' implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - api 'cloud.mindbox:mobile-sdk:2.14.1' + api 'cloud.mindbox:mobile-sdk:2.14.2' } diff --git a/android/consumer-rules.pro b/android/consumer-rules.pro new file mode 100644 index 0000000..70d3596 --- /dev/null +++ b/android/consumer-rules.pro @@ -0,0 +1,5 @@ +-keep class com.facebook.react.ReactHost { *; } +-keep interface com.facebook.react.ReactInstanceEventListener { *; } +-keep interface com.facebook.react.ReactApplication { + public com.facebook.react.ReactHost getReactHost(); +} diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index dc01239..9c8a289 100644 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -1,4 +1,9 @@ - + + + diff --git a/android/src/main/java/com/mindboxsdk/MindboxEventEmitter.kt b/android/src/main/java/com/mindboxsdk/MindboxEventEmitter.kt new file mode 100644 index 0000000..5a6de8e --- /dev/null +++ b/android/src/main/java/com/mindboxsdk/MindboxEventEmitter.kt @@ -0,0 +1,55 @@ +package com.mindboxsdk + +import android.app.Activity +import android.app.Application +import android.content.Context +import android.content.Intent +import android.util.Log +import com.facebook.react.ReactApplication +import com.facebook.react.ReactInstanceManager +import com.facebook.react.bridge.ReactContext +import com.facebook.react.ReactActivity +import cloud.mindbox.mobile_sdk.Mindbox +import cloud.mindbox.mobile_sdk.logger.Level + +internal class MindboxEventEmitter ( + private val application: Application +) : MindboxEventSubscriber { + + private var jsDelivery: MindboxJsDelivery? = null + + override fun onEvent(event: MindboxSdkLifecycleEvent) { + when (event) { + is MindboxSdkLifecycleEvent.NewIntent -> handleNewIntent(event.reactContext, event.intent) + is MindboxSdkLifecycleEvent.ActivityCreated -> handleActivityCreated(event.reactContext, event.activity) + is MindboxSdkLifecycleEvent.ActivityDestroyed -> handleActivityDestroyed() + } + } + + private fun handleNewIntent(context: ReactContext, intent: Intent) { + Mindbox.writeLog("[RN] Handle new intent in event emitter. ", Level.INFO) + Mindbox.onNewIntent(intent) + Mindbox.onPushClicked(context, intent) + jsDelivery?.sendPushClicked(intent) + } + + private fun handleActivityCreated(reactContext:ReactContext, activity: Activity) { + Mindbox.writeLog("[RN] Handle activity created", Level.INFO) + runCatching { + reactContext.let { reactContext -> + initializeAndSendIntent(reactContext, activity) + } + } + } + + private fun initializeAndSendIntent(context: ReactContext, activity: Activity) { + Mindbox.writeLog("[RN] Initialize MindboxJsDelivery", Level.INFO) + jsDelivery = MindboxJsDelivery.Shared.getInstance(context) + val currentActivity = context.currentActivity ?: activity + currentActivity.intent?.let { handleNewIntent(context, it) } + } + + private fun handleActivityDestroyed() { + jsDelivery = null + } +} diff --git a/android/src/main/java/com/mindboxsdk/MindboxEventSubscriber.kt b/android/src/main/java/com/mindboxsdk/MindboxEventSubscriber.kt new file mode 100644 index 0000000..ad7105f --- /dev/null +++ b/android/src/main/java/com/mindboxsdk/MindboxEventSubscriber.kt @@ -0,0 +1,5 @@ +package com.mindboxsdk + +internal interface MindboxEventSubscriber { + fun onEvent(event: MindboxSdkLifecycleEvent) +} diff --git a/android/src/main/java/com/mindboxsdk/MindboxPushServicesDiscovery.kt b/android/src/main/java/com/mindboxsdk/MindboxPushServicesDiscovery.kt new file mode 100644 index 0000000..e1e2eb4 --- /dev/null +++ b/android/src/main/java/com/mindboxsdk/MindboxPushServicesDiscovery.kt @@ -0,0 +1,72 @@ +package com.mindboxsdk + +import android.os.Bundle +import android.util.Log +import cloud.mindbox.mobile_sdk.pushes.MindboxPushService + +internal class MindboxPushServicesDiscovery(private val meta: Bundle?) { + + companion object { + private const val TAG = "MindboxPushServicesDiscovery" + private const val PUSH_PROVIDER_PREFIX = "cloud.mindbox.push.provider." + } + + private val providerPriority: Map by lazy(LazyThreadSafetyMode.NONE) { + mapOf("FCM" to 0, "HCM" to 1, "RuStore" to 2) + } + + val services: List by lazy(LazyThreadSafetyMode.NONE) { + if (meta == null) { + return@lazy emptyList() + } + meta.keySet() + .asSequence() + .filter { it.startsWith(PUSH_PROVIDER_PREFIX) } + .mapNotNull { key -> meta.getString(key)?.takeIf { it.isNotBlank() } } + .mapNotNull { className -> loadPushService(className) } + .distinctBy { it::class.java.name } + .sortedWith( + compareBy { providerPriority[it.tag] ?: Int.MAX_VALUE } + .thenBy { it.tag } + ) + .toList() + .also { list -> + Log.i(TAG, "Found ${list.size} push services: ${list.joinToString { it.tag }}") + list + } + } + + private fun loadPushService(className: String): MindboxPushService? { + return runCatching { + val clazz = Class.forName(className) + + if (!MindboxPushService::class.java.isAssignableFrom(clazz)) { + Log.w(TAG, "Class $className does not implement MindboxPushService") + return@runCatching null + } + getPushServiceInstance(clazz)?.also { + Log.i(TAG, "Loaded push provider: $className") + } ?: run { + Log.e(TAG, "Failed to create instance for provider: $className") + null + } + }.getOrElse { exception -> + when (exception) { + is ClassNotFoundException -> Log.e(TAG, "Push provider class not found: $className", exception) + else -> Log.e(TAG, "Failed to load push provider: $className", exception) + } + null + } + } + + private fun getPushServiceInstance(clazz: Class<*>): MindboxPushService? { + return runCatching { + val instanceField = clazz.getDeclaredField("INSTANCE") + instanceField.isAccessible = true + instanceField.get(null) as? MindboxPushService + }.getOrElse { + Log.w(TAG, "Failed to get instance for ${clazz.name}") + null + } + } +} diff --git a/android/src/main/java/com/mindboxsdk/MindboxSdkInitProvider.kt b/android/src/main/java/com/mindboxsdk/MindboxSdkInitProvider.kt new file mode 100644 index 0000000..950c8e7 --- /dev/null +++ b/android/src/main/java/com/mindboxsdk/MindboxSdkInitProvider.kt @@ -0,0 +1,66 @@ +package com.mindboxsdk + +import android.app.Application +import android.content.ContentProvider +import android.content.ContentValues +import android.content.pm.PackageManager +import android.database.Cursor +import android.net.Uri +import android.os.Bundle +import android.util.Log +import cloud.mindbox.mobile_sdk.pushes.MindboxPushService +import cloud.mindbox.mobile_sdk.Mindbox + +internal class MindboxSdkInitProvider : ContentProvider() { + + companion object { + private const val AUTO_INIT_ENABLED_KEY = "com.mindbox.sdk.AUTO_INIT_ENABLED" + private const val TAG = "MindboxSdkInitProvider" + } + + override fun onCreate(): Boolean { + runCatching { + Log.i(TAG, "onCreate initProvider.") + (context?.applicationContext as? Application)?.let { application -> + val meta = application.readMetaData() + if (isAutoInitEnabled(application, meta)) { + Log.i(TAG, "Automatic initialization is enabled.") + Mindbox.initPushServices(application, MindboxPushServicesDiscovery(meta).services) + MindboxSdkLifecycleListener.register(application) + } else { + Log.i(TAG, "Automatic initialization is disabled.") + } + } + }.onFailure { error -> + Log.e(TAG, "Automatic initialization failed", error) + } + return true + } + + private fun isAutoInitEnabled(application: Application, metaData: Bundle?): Boolean = + metaData + ?.getBoolean(AUTO_INIT_ENABLED_KEY, false) + ?: false + + private fun Application.readMetaData(): Bundle? = runCatching { + packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA).metaData + }.getOrNull() + + override fun query( + uri: Uri, + projection: Array?, + selection: String?, + selectionArgs: Array?, + sortOrder: String? + ): Cursor? = null + + override fun getType(uri: Uri): String? = null + override fun insert(uri: Uri, values: ContentValues?): Uri? = null + override fun delete(uri: Uri, selection: String?, selectionArgs: Array?): Int = 0 + override fun update( + uri: Uri, + values: ContentValues?, + selection: String?, + selectionArgs: Array? + ): Int = 0 +} diff --git a/android/src/main/java/com/mindboxsdk/MindboxSdkLifecycleEvent.kt b/android/src/main/java/com/mindboxsdk/MindboxSdkLifecycleEvent.kt new file mode 100644 index 0000000..2cce9cf --- /dev/null +++ b/android/src/main/java/com/mindboxsdk/MindboxSdkLifecycleEvent.kt @@ -0,0 +1,11 @@ +package com.mindboxsdk + +import android.app.Activity +import android.content.Intent +import com.facebook.react.bridge.ReactContext + +internal sealed class MindboxSdkLifecycleEvent { + data class NewIntent(val reactContext: ReactContext, val intent: Intent) : MindboxSdkLifecycleEvent() + data class ActivityCreated(val reactContext: ReactContext, val activity: Activity) : MindboxSdkLifecycleEvent() + data class ActivityDestroyed(val activity: Activity) : MindboxSdkLifecycleEvent() +} diff --git a/android/src/main/java/com/mindboxsdk/MindboxSdkLifecycleListener.kt b/android/src/main/java/com/mindboxsdk/MindboxSdkLifecycleListener.kt new file mode 100644 index 0000000..73cdd4e --- /dev/null +++ b/android/src/main/java/com/mindboxsdk/MindboxSdkLifecycleListener.kt @@ -0,0 +1,208 @@ +package com.mindboxsdk + +import android.app.Activity +import android.app.Application +import android.content.Intent +import android.os.Bundle +import com.facebook.react.ReactApplication +import com.facebook.react.ReactInstanceManager +import com.facebook.react.bridge.ActivityEventListener +import com.facebook.react.bridge.ReactContext +import java.util.concurrent.atomic.AtomicBoolean +import cloud.mindbox.mobile_sdk.Mindbox +import cloud.mindbox.mobile_sdk.logger.Level +import cloud.mindbox.mobile_sdk.pushes.MindboxPushService + + +internal class MindboxSdkLifecycleListener private constructor( + private val application: Application, + private val subscriber: MindboxEventSubscriber +) : Application.ActivityLifecycleCallbacks { + + companion object { + @Volatile + private var listener: MindboxSdkLifecycleListener? = null + + fun register( + application: Application, + subscriber: MindboxEventSubscriber = MindboxEventEmitter(application) + ) { + if (listener == null) { + synchronized(this) { + if (listener == null) { + Mindbox.writeLog("[RN] Initialize MindboxSdkLifecycleListener", Level.INFO) + val lifecycleListener = MindboxSdkLifecycleListener(application, subscriber) + application.registerActivityLifecycleCallbacks(lifecycleListener) + listener = lifecycleListener + } + } + } + } + } + + private val mainActivityClassName: String? by lazy { getLauncherActivityClassName() } + + private fun getLauncherActivityClassName(): String? { + val pm = application.packageManager + val intent = pm.getLaunchIntentForPackage(application.packageName) + return intent?.component?.className + } + + private fun isMainActivity(activity: Activity): Boolean { + return activity.javaClass.name == mainActivityClassName + } + + private var activityEventListener: ActivityEventListener? = null + + private fun onReactContextAvailable(reactContext: ReactContext, activity: Activity) { + Mindbox.writeLog("[RN] ReactContext ready", Level.INFO) + addActivityEventListener(reactContext) + subscriber.onEvent(MindboxSdkLifecycleEvent.ActivityCreated(reactContext, activity)) + } + + private fun registerReactContextListener( + application: Application, + onReady: (ReactContext) -> Unit + ) { + val reactApplication = application.getReactApplication() ?: return + val reactInstanceManager = getReactInstanceManager() + + val wrapperListener = object : ReactInstanceManager.ReactInstanceEventListener { + private val called = AtomicBoolean(false) + override fun onReactContextInitialized(context: ReactContext) { + if (called.compareAndSet(false, true)) { + onReady(context) + } + } + } + + reactInstanceManager?.addReactInstanceEventListener(wrapperListener) + // RN 0.78+ introduced ReactHost.addReactInstanceEventListener(...). + // Older RN versions (<= 0.74) expose only ReactInstanceManager.addReactInstanceEventListener(...). + // In New Architecture the ReactInstanceManager listener might not fire + // To support RN 0.78+ reliably while keeping backward compatibility, + // we try to register via ReactHost using reflection (no compile-time dependency). + // If ReactHost API is unavailable (older RN), this call is silently ignored and we rely on + // the ReactInstanceManager path. + addReactHostListener(application, wrapperListener) + } + + override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) { + if (!isMainActivity(activity)) return + + getReactInstanceManager()?.currentReactContext?.let { + onReactContextAvailable(it, activity) + Mindbox.writeLog("[RN] ReactContext already available; skipping listener registration ", Level.INFO) + return + } + + registerReactContextListener(application) { reactContext -> + onReactContextAvailable(reactContext, activity) + } + } + + private fun addActivityEventListener(reactContext: ReactContext) { + activityEventListener?.let { reactContext.removeActivityEventListener(it) } + + activityEventListener = object : ActivityEventListener { + override fun onNewIntent(intent: Intent) { + reactContext.currentActivity + ?.takeIf { isMainActivity(it) } + ?.let { + subscriber.onEvent( + MindboxSdkLifecycleEvent.NewIntent( + reactContext, + intent + ) + ) + } + } + + override fun onActivityResult( + activity: Activity, requestCode: Int, resultCode: Int, data: Intent? + ) { + } + } + reactContext.addActivityEventListener(activityEventListener) + } + + override fun onActivityDestroyed(activity: Activity) { + if (!isMainActivity(activity)) return + subscriber.onEvent(MindboxSdkLifecycleEvent.ActivityDestroyed(activity)) + getReactInstanceManager() + ?.currentReactContext + ?.removeActivityEventListener(activityEventListener) + activityEventListener = null + } + + override fun onActivityStarted(activity: Activity) {} + override fun onActivityResumed(activity: Activity) {} + override fun onActivityPaused(activity: Activity) {} + override fun onActivityStopped(activity: Activity) {} + override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {} + + + private fun getReactInstanceManager(): ReactInstanceManager? = + application.getReactApplication()?.reactNativeHost?.reactInstanceManager + + private fun Application.getReactApplication() = this as? ReactApplication + + private fun addReactHostListener( + application: Application, + wrapperListener: ReactInstanceManager.ReactInstanceEventListener + ) { + runCatching { + val reactApplication = application as ReactApplication + + val hostClass = Class.forName("com.facebook.react.ReactHost") + val listenerClass = Class.forName("com.facebook.react.ReactInstanceEventListener") + + val addMethod = hostClass.getMethod("addReactInstanceEventListener", listenerClass) + val getHostMethod = reactApplication.javaClass.getMethod("getReactHost") + val reactHost = getHostMethod.invoke(reactApplication) + + val proxy = java.lang.reflect.Proxy.newProxyInstance( + listenerClass.classLoader, + arrayOf(listenerClass) + ) { _, method, args -> + if (method.name == "onReactContextInitialized" && args?.size == 1 && args[0] is ReactContext) { + wrapperListener.onReactContextInitialized(args[0] as ReactContext) + } + null + } + + addMethod.invoke(reactHost, proxy) + Mindbox.writeLog("[RN] success added react context listener for reactHost", Level.INFO) + }.onFailure { + Mindbox.writeLog("[RN] failed added react context listener for reactHost ", Level.ERROR) + } + } +} + +/** + * Initializes push notification services for React Native integration. + * + * This method performs two crucial initialization steps: + * 1. Initializes the specified push services (FCM, HMS, RuStore) through Mindbox SDK + * 2. Registers the Mindbox lifecycle listener to handle React Native specific events + * + * @param application The Android Application context used for initialization + * @param pushServices List of push notification services to initialize. Typically includes + * [MindboxFirebase] for Firebase Cloud Messaging and/or + * [MindboxHuawei] for Huawei Cloud Messaging and/or + * [MindboxRuStore] for Huawei Cloud Messaging + * + * @example + * // Typical usage: + * Mindbox.initPushServicesForReactNative( + * application, + * listOf(MindboxFirebase, MindboxHuawei, MindboxRuStore) + * ) + * + * @note This method should be called once during application startup, + * in the Application.onCreate() method. + */ +public fun Mindbox.initPushServicesForReactNative(application: Application, pushServices: List) { + Mindbox.initPushServices(application, pushServices) + MindboxSdkLifecycleListener.register(application) +} diff --git a/example/exampleApp/android/app/src/main/AndroidManifest.xml b/example/exampleApp/android/app/src/main/AndroidManifest.xml index 3152724..5d112d5 100644 --- a/example/exampleApp/android/app/src/main/AndroidManifest.xml +++ b/example/exampleApp/android/app/src/main/AndroidManifest.xml @@ -45,5 +45,9 @@ + + diff --git a/example/exampleApp/android/app/src/main/java/com/exampleapp/MainActivity.kt b/example/exampleApp/android/app/src/main/java/com/exampleapp/MainActivity.kt index 5ab883f..790922f 100644 --- a/example/exampleApp/android/app/src/main/java/com/exampleapp/MainActivity.kt +++ b/example/exampleApp/android/app/src/main/java/com/exampleapp/MainActivity.kt @@ -13,7 +13,7 @@ import com.facebook.react.defaults.DefaultReactActivityDelegate import com.mindboxsdk.MindboxJsDelivery class MainActivity : ReactActivity() { - private var mJsDelivery: MindboxJsDelivery? = null + private var jsDelivery: MindboxJsDelivery? = null override fun getMainComponentName(): String = "exampleApp" override fun createReactActivityDelegate(): ReactActivityDelegate = @@ -22,7 +22,7 @@ class MainActivity : ReactActivity() { // Initializes MindboxJsDelivery and sends the current intent to React Native // https://developers.mindbox.ru/docs/flutter-push-navigation-react-native private fun initializeAndSentIntent(context: ReactContext) { - mJsDelivery = MindboxJsDelivery.Shared.getInstance(context) + jsDelivery = MindboxJsDelivery.Shared.getInstance(context) if (context.hasCurrentActivity()) { sendIntent(context, context.getCurrentActivity()!!.getIntent()) } else { @@ -32,8 +32,8 @@ class MainActivity : ReactActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - val mReactInstanceManager = getReactNativeHost().getReactInstanceManager(); - val reactContext = mReactInstanceManager.getCurrentReactContext(); + val reactInstanceManager = getReactNativeHost().getReactInstanceManager(); + val reactContext = reactInstanceManager.getCurrentReactContext(); // Initialize and send intent if React context is already available // https://developers.mindbox.ru/docs/flutter-push-navigation-react-native @@ -41,11 +41,11 @@ class MainActivity : ReactActivity() { initializeAndSentIntent(reactContext); } else { // Add listener to initialize and send intent once React context is initialized - mReactInstanceManager.addReactInstanceEventListener(object : + reactInstanceManager.addReactInstanceEventListener(object : ReactInstanceManager.ReactInstanceEventListener { override fun onReactContextInitialized(context: ReactContext) { initializeAndSentIntent(context) - mReactInstanceManager.removeReactInstanceEventListener(this) + reactInstanceManager.removeReactInstanceEventListener(this) } }) } @@ -63,6 +63,6 @@ class MainActivity : ReactActivity() { Mindbox.onNewIntent(intent) //send click action Mindbox.onPushClicked(context, intent) - mJsDelivery?.sendPushClicked(intent); + jsDelivery?.sendPushClicked(intent); } } diff --git a/example/exampleApp/android/app/src/main/java/com/exampleapp/MainApplication.kt b/example/exampleApp/android/app/src/main/java/com/exampleapp/MainApplication.kt index d156ddb..7436ac3 100644 --- a/example/exampleApp/android/app/src/main/java/com/exampleapp/MainApplication.kt +++ b/example/exampleApp/android/app/src/main/java/com/exampleapp/MainApplication.kt @@ -21,6 +21,9 @@ import com.facebook.react.modules.core.DeviceEventManagerModule import com.google.gson.Gson import com.google.gson.reflect.TypeToken import cloud.mindbox.mindbox_rustore.MindboxRuStore +import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load +import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost +import com.facebook.react.defaults.DefaultReactNativeHost class MainApplication : Application(), ReactApplication { @@ -39,6 +42,10 @@ class MainApplication : Application(), ReactApplication { //The fifth step of https://developers.mindbox.ru/docs/firebase-send-push-notifications-react-native Mindbox.initPushServices(this, listOf(MindboxFirebase, MindboxHuawei, MindboxRuStore)) SoLoader.init(this, false) + if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { + // If you opted-in for the New Architecture, we load the native entry point for this app. + load() + } } private val gson = Gson() diff --git a/example/exampleApp/android/build.gradle b/example/exampleApp/android/build.gradle index 52f2df7..d2f118c 100644 --- a/example/exampleApp/android/build.gradle +++ b/example/exampleApp/android/build.gradle @@ -2,10 +2,11 @@ buildscript { ext { buildToolsVersion = "34.0.0" minSdkVersion = 23 - compileSdkVersion = 34 - targetSdkVersion = 34 - ndkVersion = "25.1.8937393" + compileSdkVersion = 35 + targetSdkVersion = 35 + ndkVersion = "26.1.10909125" kotlinVersion = "1.8.0" + cmakeVersion = "3.22.1" } repositories { google() diff --git a/example/exampleApp/package.json b/example/exampleApp/package.json index 8d6e6b4..a755306 100644 --- a/example/exampleApp/package.json +++ b/example/exampleApp/package.json @@ -7,6 +7,8 @@ "ios": "react-native run-ios", "lint": "eslint .", "start": "react-native start", + "wipe": "rm -rf ./node_modules && rm -f yarn.lock && rm -f yarn-error.log && cd ./ios && rm -rf ./Pods && rm -f Podfile.lock && cd ../android && rm -rf ./build && rm -rf ./.gradle && cd ./app && rm -rf ./build && cd ../../", + "assemble-debug": "mkdir -p android/app/src/main/assets && npx react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/ && cd android && ./gradlew assembleDebug", "test": "jest" }, "dependencies": { @@ -16,8 +18,8 @@ "mindbox-sdk": "^2.13.1", "react": "18.2.0", "react-native": "0.74.0", - "react-native-gesture-handler": "^2.21.2", - "react-native-permissions": "^5.0.0", + "react-native-gesture-handler": "2.21.2", + "react-native-permissions": "^5.4.0", "react-native-safe-area-context": "^4.9.0", "react-native-screens": "^3.29.0", "react-native-snackbar": "^2.8.0" diff --git a/package.json b/package.json index 648db45..cb511fd 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "mindbox-sdk", "version": "2.14.1", - "target-version": "2.14.1", + "target-version": "2.14.3", "description": "SDK for integration React Native mobile apps with Mindbox", "main": "lib/commonjs/index", "module": "lib/module/index",