# React Native Integration Patterns

## Overview

The mixpanel-react-native library demonstrates sophisticated React Native integration patterns, including native module bridging, autolinking configuration, and cross-platform compatibility strategies.

## 🔗 Native Module Bridge Architecture

### Platform Registration

#### iOS (CocoaPods Integration)
```ruby
# MixpanelReactNative.podspec
Pod::Spec.new do |s|
  s.name = "MixpanelReactNative"
  s.platform = :ios, "11.0"
  s.swift_version = '5.0'
  s.source_files = "ios/*.{swift,h,m}"
  
  # Key dependencies
  s.dependency "React-Core"
  s.dependency "Mixpanel-swift", '5.0.0'  # Official Mixpanel iOS SDK
end
```

**Key Insights**:
- Minimum iOS 11.0 support
- Swift 5.0 for modern language features
- Direct dependency on official Mixpanel iOS SDK
- Source files include both Swift and Objective-C bridge files

#### Android (Gradle Integration)
```gradle
// android/build.gradle
android {
    compileSdkVersion 34
    minSdkVersion 21      // Android 5.0+
    targetSdkVersion 34
    namespace "com.mixpanel.reactnative"  // AGP 7.0+ namespace
}

dependencies {
    implementation 'com.facebook.react:react-native:+'
    implementation 'com.mixpanel.android:mixpanel-android:8.1.0'  // Official Android SDK
}
```

**Key Insights**:
- Modern Android API levels (21-34)
- Namespace declaration for AGP 7.0+ compatibility
- Direct integration with official Mixpanel Android SDK
- Dynamic React Native version resolution

### Autolinking Configuration

```javascript
// react-native.config.js
module.exports = {
  dependencies: {
    'mixpanel-react-native': {
      platforms: {
        android: {
          "sourceDir": "./node_modules/mixpanel-react-native/android",
          "packageImportPath": "import com.mixpanel.reactnative.MixpanelReactNativePackage;",
          "packageInstance": "new MixpanelReactNativePackage()"
        },
        ios: {
          project: './node_modules/mixpanel-react-native/ios/MixpanelReactNative.xcodeproj',
        }
      }
    }
  }
};
```

**Autolinking Strategy**:
- Explicit configuration for both platforms
- Custom package registration for Android
- Xcode project specification for iOS
- Supports React Native 0.60+ autolinking

## 🏗️ Native Module Implementation Patterns

### iOS Bridge Pattern (Swift + Objective-C)

```swift
// ios/MixpanelReactNative.swift
@objc(MixpanelReactNative)
open class MixpanelReactNative: NSObject {
    
    @objc static func requiresMainQueueSetup() -> Bool {
        return false  // Background initialization OK
    }
    
    @objc
    func initialize(_ token: String,
                    trackAutomaticEvents: Bool,
                    optOutTrackingByDefault: Bool = false,
                    properties: [String: Any],
                    serverURL: String,
                    useGzipCompression: Bool = false,
                    resolver resolve: RCTPromiseResolveBlock,
                    rejecter reject: RCTPromiseRejectBlock) -> Void {
        // Native implementation using Mixpanel-swift SDK
        Mixpanel.initialize(token: token, ...)
        resolve(true)
    }
}
```

**Bridge Patterns**:
- `@objc` decoration for React Native exposure
- Promise-based async operations
- Background-safe initialization
- Direct parameter mapping to native SDK

### Android Bridge Pattern (Java)

```java
// android/.../MixpanelReactNativeModule.java
public class MixpanelReactNativeModule extends ReactContextBaseJavaModule {
    
    @ReactMethod
    public void initialize(String token, 
                          boolean trackAutomaticEvents, 
                          boolean optOutTrackingDefault, 
                          ReadableMap metadata, 
                          String serverURL, 
                          boolean useGzipCompression, 
                          Promise promise) throws JSONException {
        
        // Convert React Native types to native
        JSONObject mixpanelProperties = ReactNativeHelper.reactToJSON(metadata);
        
        // Initialize native SDK
        MixpanelAPI instance = MixpanelAPI.getInstance(this.mReactContext, 
                                                      token, 
                                                      optOutTrackingDefault, 
                                                      mixpanelProperties, 
                                                      null, 
                                                      trackAutomaticEvents);
        promise.resolve(null);
    }
}
```

**Bridge Patterns**:
- `@ReactMethod` annotation for method exposure
- Type conversion utilities (`ReactNativeHelper`)
- Thread-safe instance management
- Consistent Promise-based API

## 🔄 Fallback Strategy Implementation

### Implementation Router Pattern

```javascript
// index.js
export class Mixpanel {
  constructor(token, trackAutomaticEvents, useNative = true, storage) {
    this.token = token;
    this.trackAutomaticEvents = trackAutomaticEvents;

    // Try native implementation first
    if (useNative && MixpanelReactNative) {
      this.mixpanelImpl = MixpanelReactNative;
      return;
    } else if (useNative) {
      console.warn(
        "MixpanelReactNative is not available; using JavaScript mode..."
      );
    }

    // Fallback to JavaScript implementation
    this.mixpanelImpl = new MixpanelMain(token, trackAutomaticEvents, storage);
  }
}
```

**Fallback Benefits**:
- Graceful degradation when native modules unavailable
- Expo compatibility (no native modules allowed)
- Web support through React Native Web
- Development environment flexibility

## 📱 Platform-Specific Optimizations

### iOS Optimizations

```swift
// ios/MixpanelReactNative.swift
@objc
func setFlushOnBackground(_ token: String,
                         flushOnBackground: Bool,
                         resolver resolve: RCTPromiseResolveBlock,
                         rejecter reject: RCTPromiseRejectBlock) -> Void {
    let instance = MixpanelReactNative.getMixpanelInstance(token)
    instance?.flushOnBackground = flushOnBackground  // iOS-specific feature
    resolve(nil)
}
```

**iOS-Specific Features**:
- Background flushing support
- App lifecycle integration
- Memory management optimization
- Native SDK performance benefits

### Android Optimizations

```java
// android/.../MixpanelReactNativeModule.java
@ReactMethod
public void setFlushBatchSize(final String token, Integer flushBatchSize, Promise promise) {
    MixpanelAPI instance = MixpanelAPI.getInstance(this.mReactContext, token, true);
    if (instance == null) {
        promise.reject("Instance Error", "Failed to get Mixpanel instance");
        return;
    }
    synchronized (instance) {  // Thread-safe operations
        instance.setFlushBatchSize(flushBatchSize);
        promise.resolve(null);
    }
}
```

**Android-Specific Features**:
- Thread synchronization for safety
- Context-aware initialization
- Lifecycle-aware processing
- Memory-efficient batching

## 🛠️ Development & Build Configuration

### Metro Configuration (Standard)

```javascript
// Samples/SimpleMixpanel/metro.config.js
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');

const config = {};  // Use defaults

module.exports = mergeConfig(getDefaultConfig(__dirname), config);
```

**Build Strategy**:
- Standard React Native Metro bundler
- No custom transformations needed
- Works with standard RN build pipeline

### Babel Configuration (Standard)

```javascript
// Samples/SimpleMixpanel/babel.config.js
module.exports = {
  presets: ['module:@react-native/babel-preset'],
};
```

**Transpilation Strategy**:
- Standard React Native Babel preset
- No custom plugins required
- ES6+ feature support

## 🧪 Testing Integration

### Jest Configuration for React Native

```javascript
// package.json
"jest": {
  "modulePathIgnorePatterns": ["<rootDir>/Samples/"],
  "testMatch": ["<rootDir>/__tests__/*.test.js"],
  "setupFiles": ["<rootDir>/__tests__/jest_setup.js"],
  "verbose": true,
  "preset": "react-native"
}
```

**Testing Strategy**:
- React Native Jest preset
- Custom setup for mocking
- Isolated test environment
- Sample apps excluded from tests

### Native Module Mocking

```javascript
// __tests__/jest_setup.js
jest.doMock("react-native", () => {
  return Object.setPrototypeOf({
    NativeModules: {
      MixpanelReactNative: {
        initialize: jest.fn(),
        track: jest.fn(),
        // ... complete API mock
      },
    },
  }, ReactNative);
});
```

**Mocking Strategy**:
- Complete native module API mocking
- Consistent with actual native interface
- Enables testing without native dependencies

## 🚀 Performance Considerations

### Native vs JavaScript Mode

| Aspect | Native Mode | JavaScript Mode |
|--------|-------------|-----------------|
| **Initialization** | Native SDK optimized | Custom implementation |
| **Queue Management** | Native (60s flush) | JavaScript (10s flush) |
| **Storage** | Platform-optimized | AsyncStorage |
| **Network** | Native HTTP stack | Fetch API |
| **Memory** | SDK-managed | Manual management |

### Bundle Size Impact

```javascript
// The library is designed for minimal bundle impact:
// - Core native bridge code only
// - JavaScript fallback loaded conditionally
// - No heavy dependencies in main bundle
```

## 📋 Best Practices Discovered

### 1. Graceful Degradation
Always provide JavaScript fallback for native functionality

### 2. Promise-Based APIs
Consistent async patterns across platforms

### 3. Type Safety
Comprehensive input validation before native calls

### 4. Error Handling
Native errors properly propagated to JavaScript

### 5. Platform Detection
Runtime detection of capabilities rather than build-time

### 6. Memory Management
Proper cleanup and instance management

### 7. Thread Safety
Synchronization for shared resources

### 8. Configuration Flexibility
Runtime configuration over build-time constants