Skip to content
Merged
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
7 changes: 4 additions & 3 deletions ExpoTestApp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,9 @@ The Rokt section also demonstrates:
- Using `RoktLayoutView` as an embedded placeholder component

On Android, the Rokt session APIs require `android-core` and
`android-rokt-kit` `5.79.0` or newer. If configured, the shared Expo
`customBaseUrl` setting is applied to Android through
`android-rokt-kit` `6.0.0` or newer. Apps that include `android-rokt-kit`
`6.0.0` must build with `compileSdk` 35+ and Android Gradle Plugin 8.6+. If
configured, the shared Expo `customBaseUrl` setting is applied to Android through
`NetworkOptions.setCustomBaseURL`.

### Implementation guide: Shoppable Ads (`selectShoppableAds`)
Expand Down Expand Up @@ -262,7 +263,7 @@ Check `android/app/build.gradle` for kit dependencies (if specified):
```gradle
dependencies {
// mParticle kits
implementation "com.mparticle:android-rokt-kit:+"
implementation "com.mparticle:android-rokt-kit:[6.0.0, 7.0)"
}
```

Expand Down
29 changes: 27 additions & 2 deletions MIGRATING.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,32 @@
# Migration Guides

This document provides migration guidance for changes in `react-native-mparticle`.
Release versions and changelog entries are generated by the Release Draft workflow.

## Migrating Android apps to mParticle Android SDK 6.0.0

The React Native JavaScript API is unchanged. Existing calls to
`MParticle.Rokt.selectPlacements`, `close()`, `setSessionId()`,
`getSessionId()`, and `purchaseFinalized()` continue to use the same
JavaScript signatures and event names.

### Android Rokt Dependencies

Android apps that use Rokt must include matching 6.x mParticle artifacts:

```gradle
implementation "com.mparticle:android-core:[6.0.0, 7.0)"
implementation "com.mparticle:android-rokt-kit:[6.0.0, 7.0)"
```

Apps that include `android-rokt-kit` `6.0.0` must build with `compileSdk` 35+
and Android Gradle Plugin 8.6+.

### Android Expo Config Plugin

If you use the Expo config plugin with `androidKits`, the plugin injects kit
dependencies with the `[6.0.0, 7.0)` range.

`selectShoppableAds` remains a no-op on Android in this release.

## Migrating to the mParticle Apple SDK 9.2.0 Rokt update

Expand Down Expand Up @@ -32,7 +57,7 @@ MParticle.Rokt.getSessionId(): Promise<string | null>

`close()` is supported on iOS and Android. Session APIs are backed by the iOS
mParticle Rokt kit. On Android, apps that use these session APIs must use
`android-core` and `android-rokt-kit` `5.79.0` or newer.
`android-core` and `android-rokt-kit` `6.0.0` or newer.

### Expo Config Plugin

Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -301,10 +301,11 @@ In Expo apps, use `iosKits: ["mParticle-Rokt"]` for standard Rokt placements. Th

See [MIGRATING.md](./MIGRATING.md) for release-specific migration guidance.

For Android integrations that use `MParticle.Rokt.setSessionId()` or
`MParticle.Rokt.getSessionId()`, `android-core` and `android-rokt-kit`
`5.79.0` or newer are required. Android CNAME setup through
`customBaseUrl` also requires `android-core` `5.79.0` or newer.
For Android Rokt integrations, including `MParticle.Rokt.*` APIs and
`RoktLayoutView`, `android-core` and `android-rokt-kit` `6.0.0` or newer are
required. Apps that include `android-rokt-kit` `6.0.0` must build with
`compileSdk` 35+ and Android Gradle Plugin 8.6+. Android CNAME setup through
`customBaseUrl` also requires `android-core` `6.0.0` or newer.

See [Identity](http://docs.mparticle.com/developers/sdk/ios/identity/) for more information on supplying an `MPIdentityApiRequest` object during SDK initialization.

Expand Down
8 changes: 4 additions & 4 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,8 @@ dependencies {
//
// (See https://github.com/mparticle/mparticle-android-sdk for the latest version)
//
// Bounded upper bound prevents resolving to 6.0.0-rc.1+ on Maven Central.
// 6.x removed deprecated symbols (e.g. UserAttributeListener); see #710.
api 'com.mparticle:android-core:[5.79.2, 6.0)'
api 'com.mparticle:android-core:[6.0.0, 7.0)'
compileOnly 'com.mparticle:android-rokt-kit:[6.0.0, 7.0)'

//
// And, if you want to include kits, you can do so as follows:
Expand All @@ -136,6 +135,7 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
testImplementation files('libs/java-json.jar')

testImplementation 'com.mparticle:android-core:5.79.2'
testImplementation 'com.mparticle:android-core:6.0.0'
testCompileOnly 'com.mparticle:android-rokt-kit:6.0.0'
testImplementation("com.facebook.react:react-android:+")
}
27 changes: 13 additions & 14 deletions android/src/main/java/com/mparticle/react/MParticleModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import com.facebook.react.bridge.WritableNativeArray
import com.facebook.react.bridge.WritableNativeMap
import com.mparticle.MPEvent
import com.mparticle.MParticle
import com.mparticle.UserAttributeListener
import com.mparticle.TypedUserAttributeListener
import com.mparticle.commerce.CommerceEvent
import com.mparticle.commerce.Impression
import com.mparticle.commerce.Product
Expand Down Expand Up @@ -153,22 +153,21 @@ class MParticleModule(
val selectedUser = MParticle.getInstance()?.Identity()?.getUser(parseMpid(mpid))
if (selectedUser != null) {
selectedUser.getUserAttributes(
object : UserAttributeListener {
object : TypedUserAttributeListener {
override fun onUserAttributesReceived(
userAttributes: Map<String, String>?,
userAttributeLists: Map<String, List<String>>?,
mpid: Long?,
userAttributes: Map<String, Any?>,
userAttributeLists: Map<String, List<String?>?>,
mpid: Long,
) {
val resultMap = WritableNativeMap()
userAttributes?.let { attrs ->
for ((key, value) in attrs) {
resultMap.putString(key, value)
}
val resultMap = getWritableMap()
for ((key, value) in userAttributes) {
resultMap.putString(key, value?.toString())
Comment thread
thomson-t marked this conversation as resolved.
}
userAttributeLists?.let { attrLists ->
for ((key, valueList) in attrLists) {

for ((key, valueList) in userAttributeLists) {
valueList?.let {
val resultArray = WritableNativeArray()
for (arrayVal in valueList) {
for (arrayVal in it) {
resultArray.pushString(arrayVal)
}
resultMap.putArray(key, resultArray)
Expand All @@ -179,7 +178,7 @@ class MParticleModule(
},
)
} else {
callback.invoke(null, WritableNativeMap())
callback.invoke(null, getWritableMap())
}
}

Expand Down
69 changes: 50 additions & 19 deletions android/src/main/java/com/mparticle/react/MParticlePackage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import com.facebook.react.module.model.ReactModuleInfo
import com.facebook.react.module.model.ReactModuleInfoProvider
import com.facebook.react.uimanager.ViewManager
import com.mparticle.react.rokt.MPRoktModule
import com.mparticle.react.rokt.MPRoktModuleImpl
import com.mparticle.react.rokt.RoktLayoutViewManager

class MParticlePackage : TurboReactPackage() {
Expand All @@ -21,14 +20,23 @@ class MParticlePackage : TurboReactPackage() {
MParticleModule(reactContext)
}

MPRoktModuleImpl.MODULE_NAME -> {
MPRoktModule(reactContext)
ROKT_MODULE_NAME -> {
if (isRoktKitAvailable) {
MPRoktModule(reactContext)
} else {
null
}
}

else -> null
}

override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> = listOf(RoktLayoutViewManager())
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> =
if (isRoktKitAvailable) {
listOf(RoktLayoutViewManager())
} else {
emptyList()
}

override fun getReactModuleInfoProvider() =
ReactModuleInfoProvider {
Expand All @@ -46,23 +54,46 @@ class MParticlePackage : TurboReactPackage() {
BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, // isTurboModule
),
)
moduleInfos.put(
MPRoktModuleImpl.MODULE_NAME,
ReactModuleInfo(
MPRoktModuleImpl.MODULE_NAME,
MPRoktModuleImpl.MODULE_NAME,
true, // canOverrideExistingModule
false, // needsEagerInit
true, // hasConstants
false, // isCxxModule
BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, // isTurboModule
),
)
if (isRoktKitAvailable) {
moduleInfos.put(
ROKT_MODULE_NAME,
ReactModuleInfo(
ROKT_MODULE_NAME,
ROKT_MODULE_NAME,
true, // canOverrideExistingModule
false, // needsEagerInit
true, // hasConstants
false, // isCxxModule
BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, // isTurboModule
),
)
}
moduleInfos.toMap()
}

override fun getViewManagers(reactContext: ReactApplicationContext): List<ModuleSpec> =
listOf(
ModuleSpec.viewManagerSpec { RoktLayoutViewManager() },
)
if (isRoktKitAvailable) {
listOf(
ModuleSpec.viewManagerSpec { RoktLayoutViewManager() },
)
} else {
emptyList()
}

// The Rokt kit's presence on the classpath is fixed for the app's lifetime; compute the
// reflective check once instead of on every module/view-manager registration call.
private val isRoktKitAvailable: Boolean by lazy {
try {
Class.forName("com.mparticle.kits.RoktEmbeddedView")
true
} catch (_: ClassNotFoundException) {
false
} catch (_: LinkageError) {
false
}
}

private companion object {
const val ROKT_MODULE_NAME = "RNMPRokt"
}
}
Loading
Loading