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
73 changes: 73 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// swift-tools-version: 6.0
// Experimental: for React Native's Swift Package Manager mode (React Native 0.87 or later), which
// React Native itself marks as not for production. CocoaPods apps do not use this file.
//
// The ReactNative and React-GeneratedCode packages are the local packages React Native's autolinker
// generates for each app, at these paths relative to this package, the same layout other React
// Native libraries use. Revisit them when React Native publishes a remote Swift package.

import PackageDescription

let package = Package(
name: "ReactNativeMparticle",
// React Native's autolinker requires iOS 15; the mParticle SDK declares the same.
platforms: [.iOS(.v15)],
products: [
.library(name: "ReactNativeMparticle", targets: ["ReactNativeMparticle"]),
],
dependencies: [
.package(name: "ReactNative", path: "../../../../xcframeworks"),
.package(name: "React-GeneratedCode", path: "../../../ios"),
// Same URLs as the mParticle kits use, so SwiftPM unifies them into one package identity.
.package(url: "https://github.com/mParticle/mparticle-apple-sdk", "9.2.2"..<"10.0.0"),
.package(url: "https://github.com/ROKT/rokt-contracts-apple.git", "2.0.0"..<"3.0.0"),
],
targets: [
// A separate target: SwiftPM cannot mix Swift and Objective-C++ in one target.
.target(
name: "RNMParticleSwift",
dependencies: [.product(name: "RoktContracts", package: "rokt-contracts-apple")],
path: "ios/RNMParticle/Swift"
),
.target(
name: "ReactNativeMparticle",
dependencies: [
"RNMParticleSwift",
.product(name: "ReactHeaders", package: "ReactNative"),
.product(name: "ReactNativeHeaders", package: "ReactNative"),
.product(name: "ReactNativeDependenciesHeaders", package: "ReactNative"),
.product(name: "ReactAppHeaders", package: "React-GeneratedCode"),
.product(name: "mParticle-Apple-SDK", package: "mparticle-apple-sdk"),
.product(name: "RoktContracts", package: "rokt-contracts-apple"),
],
path: ".",
sources: [
"ios/RNMParticle/RNMPRokt.h",
"ios/RNMParticle/RNMPRokt.mm",
"ios/RNMParticle/RNMPRoktSwift.h",
"ios/RNMParticle/RNMPSDKImports.h",
"ios/RNMParticle/RNMParticle.h",
"ios/RNMParticle/RNMParticle.mm",
"ios/RNMParticle/RoktEventManager.h",
"ios/RNMParticle/RoktEventManager.mm",
"ios/RNMParticle/RoktLayoutManager.m",
"ios/RNMParticle/RoktNativeLayoutComponentView.h",
"ios/RNMParticle/RoktNativeLayoutComponentView.mm",
"ios/RNMParticle/RoktPlaceholderRegistry.h",
"ios/RNMParticle/RoktPlaceholderRegistry.m",
],
publicHeadersPath: "ios",
// Without RCT_NEW_ARCH_ENABLED the TurboModule and Fabric code compiles out, and the app
// crashes looking up the RoktNativeLayout component.
cSettings: [.define("RCT_NEW_ARCH_ENABLED", to: "1"), .headerSearchPath("ios/RNMParticle")],
cxxSettings: [
.define("RCT_NEW_ARCH_ENABLED", to: "1"),
.headerSearchPath("ios/RNMParticle"),
.define("DEBUG", .when(configuration: .debug)),
.define("NDEBUG", .when(configuration: .release)),
],
linkerSettings: [.linkedFramework("UIKit"), .linkedFramework("Foundation"), .linkedFramework("CoreGraphics")]
),
],
cxxLanguageStandard: .cxx20
)
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,17 @@ Every mParticle and Rokt SDK must then come from Swift Package Manager, and none
- The build fails with `[mParticle] $RNMParticleUseSPM is set but the mParticle-Apple-SDK Swift package is not linked into the app target`: `mparticle_spm_post_install` did not run, or the package was removed from the app target afterwards. Call it in `post_install` and run `pod install` again.
- A Debug build shows the red box `[mParticle] The mParticle SDK is loaded more than once`: the SDK comes from both CocoaPods and Swift Package Manager. Remove the mParticle and Rokt pods and Swift packages you added by hand, then set up one mode as described above.

### Experimental: React Native Swift Package Manager mode

> **Not for production.** React Native's own Swift Package Manager mode (React Native 0.87 or later) is experimental, and so is this package's support for it. Use CocoaPods, with or without the opt-in mode above, for apps you ship.

This package ships a `Package.swift`, so `npx react-native spm add` links it without a scaffolded manifest. The app target must also link the mParticle core SDK and each kit as Swift packages, for example in Xcode (File › Add Package Dependencies):

- `https://github.com/mParticle/mparticle-apple-sdk`, product `mParticle-Apple-SDK`
- `https://github.com/mparticle-integrations/mp-apple-integration-rokt`, product `mParticle-Rokt`

Use exactly these URLs, with no `.git` suffix on the first, so Swift Package Manager treats them as the same packages the kits depend on. Then start mParticle in your Swift `AppDelegate` with `import mParticle_Apple_SDK`, as in the CocoaPods setup.

## Android (Manual Setup)

1. Copy your mParticle key and secret from [your workspace's dashboard](https://app.mparticle.com/setup/inputs/apps) and construct an `MParticleOptions` object.
Expand Down
24 changes: 24 additions & 0 deletions js/__tests__/package-swift-sources.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as fs from 'fs';
import * as path from 'path';

/**
* The podspec compiles every file under ios/ by glob, but Package.swift lists the Objective-C++
* target's sources by hand, and CI does not build that manifest. Keep the two in step.
*/
const root = path.join(__dirname, '..', '..');

it('lists every ios/RNMParticle source in Package.swift', () => {
const manifest = fs.readFileSync(path.join(root, 'Package.swift'), 'utf-8');
const listed = new Set(
[...manifest.matchAll(/"(ios\/RNMParticle\/[^"]+\.(?:h|m|mm))"/g)].map(
match => match[1]
)
);
const onDisk = fs
.readdirSync(path.join(root, 'ios', 'RNMParticle'), { recursive: true })
.map(String)
.filter(file => /\.(h|m|mm)$/.test(file))
.map(file => `ios/RNMParticle/${file}`);

expect([...listed].sort()).toEqual(onDisk.sort());
});
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"lib",
"react-native-mparticle.podspec",
"app.plugin.js",
"plugin"
"plugin",
"Package.swift"
],
"publishConfig": {
"access": "public",
Expand Down
Loading