Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,6 @@ jobs:
# Run tests
- name: Run Harness E2E tests
working-directory: example
run: yarn harness:ios
run: |
export NODE_OPTIONS="--max-old-space-size=6144"
yarn harness:ios
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import com.mendix.mendixnative.react.splash.MendixSplashScreenPresenter;

import java.util.List;
import java.util.Map;

public interface MendixApplication extends ReactApplication {
boolean getUseDeveloperSupport();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.mendix.mendixnative

import android.app.Activity
import com.facebook.react.ReactHost
import com.facebook.react.devsupport.DevSupportManagerBase
import com.facebook.react.modules.network.OkHttpClientProvider
import com.mendix.mendixnative.config.AppPreferences
import com.mendix.mendixnative.react.*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.mendix.mendixnative

import android.app.Application
import com.facebook.react.ReactHost
import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.bridge.JSBundleLoader
import com.facebook.react.bridge.JSBundleLoaderDelegate
Expand All @@ -28,8 +27,6 @@ import com.mendixnative.MendixNativePackage
import java.util.*
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load

import com.facebook.react.defaults.DefaultReactNativeHost

abstract class MendixReactApplication : Application(), MendixApplication, ErrorHandlerFactory {
private val appSessionId = "" + Math.random() * 1000 + Date().time
override fun getAppSessionId(): String = appSessionId
Expand All @@ -44,33 +41,11 @@ abstract class MendixReactApplication : Application(), MendixApplication, ErrorH

private var jsBundleFileProvider: JSBundleFileProvider? = jsBundleProvider

override var reactNativeHost: ReactNativeHost = object : DefaultReactNativeHost(this) {
override fun getUseDeveloperSupport(): Boolean = this@MendixReactApplication.useDeveloperSupport

override fun getPackages(): List<ReactPackage> {
val pkgs: MutableList<ReactPackage> = ArrayList()
// Use the packages provided by the concrete Application subclass.
pkgs.addAll(this@MendixReactApplication.packages)
// Inject splashScreenPresenter into any MendixNativePackage instances without creating duplicates.
applyInternalPackageAugmentations(pkgs)
return pkgs
}

override fun getJSBundleFile(): String? = this@MendixReactApplication.jsBundleFile
override fun getJSMainModuleName(): String = "index"
override fun getBundleAssetName(): String? = super.getBundleAssetName()
override fun getRedBoxHandler(): RedBoxHandler? = null

// Hermes & New Arch flags; Hermes executor will be picked automatically when isHermesEnabled is true.
override val isNewArchEnabled: Boolean = true
override val isHermesEnabled: Boolean = true
}

/**
* Build the [ReactHost] ourselves instead of using [DefaultReactHost.getDefaultReactHost],
* because that factory evaluates [ReactNativeHost.getJSBundleFile] once at creation time and
* bakes the result into a fixed [JSBundleLoader]. After an OTA update deploys a new bundle,
* a subsequent [ReactHost.reload] would still load the stale bundle.
* Build the [ReactHost] with a custom [JSBundleLoader] instead of using a static bundle path.
* The default approach evaluates the bundle file path once at creation time and bakes it into
* a fixed [JSBundleLoader]. After an OTA update deploys a new bundle, a subsequent
* [ReactHost.reload] would still load the stale bundle.
*
* By providing a **dynamic** [JSBundleLoader] whose [JSBundleLoader.loadScript] calls
* [getJSBundleFile] on every invocation, each reload picks up the latest bundle path —
Expand Down Expand Up @@ -133,10 +108,7 @@ abstract class MendixReactApplication : Application(), MendixApplication, ErrorH
override fun onCreate() {
super.onCreate()
SoLoader.init(this, OpenSourceMergedSoMapping)
// Only load the New Architecture entry point when enabled (always true here, but guarded for safety).
if (reactNativeHost is DefaultReactNativeHost) {
load()
}
load()
}

override fun getJSBundleFile(): String? {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package com.mendix.mendixnative.activity

import android.os.Build
import android.os.Bundle
import android.view.KeyEvent
import com.facebook.react.ReactActivity
import com.facebook.react.ReactActivityDelegate
import com.facebook.react.bridge.ReactContext
import com.facebook.react.devsupport.interfaces.DevSupportManager
import com.mendix.mendixnative.DevAppMenuHandler
import com.mendix.mendixnative.MendixApplication
import com.mendix.mendixnative.MendixInitializer
import com.mendix.mendixnative.react.MendixApp
import com.mendix.mendixnative.react.splash.MendixSplashScreenPresenter
import com.mendix.mendixnative.util.MendixBackwardsCompatUtility
import java.io.Serializable

open class MendixReactActivity : ReactActivity(), DevAppMenuHandler, LaunchScreenHandler {

Expand All @@ -24,7 +24,7 @@ open class MendixReactActivity : ReactActivity(), DevAppMenuHandler, LaunchScree

override fun onCreate(savedInstanceState: Bundle?) {
mendixApp = mendixApp
?: intent.getSerializableExtra(MENDIX_APP_INTENT_KEY) as? MendixApp
?: getSerializableData(MENDIX_APP_INTENT_KEY, MendixApp::class.java)
?: throw IllegalStateException("MendixApp configuration can't be null")
val mendixApplication = application as? MendixApplication
?: throw ClassCastException("Application needs to implement MendixApplication")
Expand All @@ -36,6 +36,19 @@ open class MendixReactActivity : ReactActivity(), DevAppMenuHandler, LaunchScree
super.onCreate(null)
}

inline fun <reified T : Serializable> getSerializableData(key: String?, clazz: Class<T>): T? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
intent.getSerializableExtra<T?>(key, clazz)
} else {
@Suppress("DEPRECATION")
val data = intent.getSerializableExtra(key)
if (data is T) {
return data
}
return null
}
}

override fun onDestroy() {
mendixInitializer.onDestroy()
super.onDestroy()
Expand All @@ -46,12 +59,9 @@ open class MendixReactActivity : ReactActivity(), DevAppMenuHandler, LaunchScree
}

override fun showDevAppMenu() {
currentDevSupportManager?.showDevOptionsDialog();
currentDevSupportManager?.showDevOptionsDialog()
}

private val currentReactContext: ReactContext?
get() = if (reactNativeHost.hasInstance()) reactInstanceManager.currentReactContext else null

val currentDevSupportManager: DevSupportManager?
get() = reactHost.devSupportManager

Expand All @@ -70,9 +80,7 @@ open class MendixReactActivity : ReactActivity(), DevAppMenuHandler, LaunchScree
}

override fun showLaunchScreen() {
if (!MendixBackwardsCompatUtility.getInstance().unsupportedFeatures.hideSplashScreenInClient && splashScreenPresenter != null) {
splashScreenPresenter?.show(this)
}
splashScreenPresenter?.show(this)
}

override fun hideLaunchScreen() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.mendix.mendixnative.fragment

import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.view.KeyEvent
import com.facebook.react.devsupport.interfaces.DevSupportManager
Expand All @@ -9,6 +10,7 @@ import com.mendix.mendixnative.MendixInitializer
import com.mendix.mendixnative.activity.LaunchScreenHandler
import com.mendix.mendixnative.react.MendixApp
import com.mendix.mendixnative.util.MendixDoubleTapRecognizer
import java.io.Serializable

/**
* Class used for Sample apps
Expand Down Expand Up @@ -54,7 +56,7 @@ open class MendixReactFragment : ReactFragment(), MendixReactFragmentView {
}

if (mendixApp == null) {
mendixApp = requireArguments().getSerializable(ARG_MENDIX_APP) as MendixApp?
mendixApp = getSerializableData(ARG_MENDIX_APP, MendixApp::class.java)
?: throw IllegalArgumentException("Mendix app is required")
}

Expand All @@ -73,9 +75,22 @@ open class MendixReactFragment : ReactFragment(), MendixReactFragmentView {
super.onCreate(savedInstanceState)
}

inline fun <reified T : Serializable> getSerializableData(key: String?, clazz: Class<T>): T? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
requireArguments().getSerializable<T?>(key, clazz)
} else {
@Suppress("DEPRECATION")
val data = requireArguments().getSerializable(key)
if (data is T) {
return data
}
return null
}
}

fun onNewIntent(intent: Intent) {
if (reactNativeHost.hasInstance()) {
reactNativeHost.reactInstanceManager.onNewIntent(intent);
reactHost?.currentReactContext?.let {
it.onNewIntent(it.currentActivity, intent)
}
}

Expand All @@ -84,7 +99,7 @@ open class MendixReactFragment : ReactFragment(), MendixReactFragmentView {
super.onDestroy()
}

override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
if (keyCode == KeyEvent.KEYCODE_MENU || doubleTapReloadRecognizer.didDoubleTapBacktick(
keyCode,
view
Expand All @@ -100,7 +115,7 @@ open class MendixReactFragment : ReactFragment(), MendixReactFragmentView {

override fun showDevAppMenu() {
activity?.let {
currentDevSupportManager?.showDevOptionsDialog();
currentDevSupportManager?.showDevOptionsDialog()
}
}

Expand All @@ -109,7 +124,7 @@ open class MendixReactFragment : ReactFragment(), MendixReactFragmentView {
}

interface MendixReactFragmentView : DevAppMenuHandler, BackButtonHandler {
fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean
fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean
}

interface BackButtonHandler {
Expand Down
Loading
Loading