Skip to content
Draft
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
80 changes: 73 additions & 7 deletions example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,81 @@

Demonstrates how to use the mparticle_flutter_sdk plugin.

## Getting Started
## Prerequisites

This project is a starting point for a Flutter application.
- Flutter SDK (stable channel)
- Xcode 16.4 or later (for iOS development)
- CocoaPods
- iOS 13.0+ (minimum deployment target)

A few resources to get you started if this is your first Flutter project:
## Setup

### 1. Install Flutter

If Flutter is not installed, follow these steps:

```bash
# Clone Flutter SDK to your home directory
cd ~
git clone https://github.com/flutter/flutter.git -b stable

# Add Flutter to your PATH in ~/.zshrc
echo 'export PATH="$HOME/flutter/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc

# Verify installation
flutter doctor
```

### 2. Install Dependencies

```bash
# From the example directory
cd example

# Get Flutter packages
flutter pub get

# Precache iOS artifacts (first time only)
flutter precache --ios
```

### 3. Install iOS Dependencies

```bash
# Install CocoaPods dependencies
cd ios
pod install
cd ..
```

**Note:** The Podfile has been configured with iOS 13.0 as the minimum deployment target to ensure compatibility with Flutter and mParticle dependencies.

## Running the App

### iOS Simulator

```bash
# List available devices
flutter devices

# Run on iOS simulator
flutter run -d <device-id>

# Or simply
flutter run
```

### iOS Device

```bash
# Connect your iOS device and ensure it's in Developer Mode
flutter run -d <your-device-name>
```

## Resources

- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)

For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
- [Flutter Documentation](https://flutter.dev/docs)
- [mParticle Documentation](https://docs.mparticle.com/)
2 changes: 1 addition & 1 deletion example/ios/Flutter/AppFrameworkInfo.plist
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>12.0</string>
<string>13.0</string>
</dict>
</plist>
2 changes: 1 addition & 1 deletion example/ios/Podfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
platform :ios, '12.0'
platform :ios, '13.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
Expand Down
6 changes: 3 additions & 3 deletions example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
Expand Down Expand Up @@ -421,7 +421,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
Expand Down Expand Up @@ -471,7 +471,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
Expand All @@ -43,11 +44,13 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
Expand Down
54 changes: 51 additions & 3 deletions example/ios/Runner/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,66 @@ import UIKit
import Flutter
import mParticle_Apple_SDK

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
@main
@objc class AppDelegate: FlutterAppDelegate, FlutterStreamHandler {
private var eventSink: FlutterEventSink?

var isInitialized = false

override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)

// Set up EventChannel for mParticle initialization notifications
let controller = window?.rootViewController as! FlutterViewController
let initializationEventChannel = FlutterEventChannel(
name: "com.example.mparticle_initialization",
binaryMessenger: controller.binaryMessenger
)
initializationEventChannel.setStreamHandler(self)

// Subscribe to mParticle initialization notification
NotificationCenter.default.addObserver(
self,
selector: #selector(handleMParticleInitialized),
name: NSNotification.Name(rawValue: "mParticleDidFinishInitializing"),
object: nil
)

let options = MParticleOptions(key: "api-key", secret: "secret")
let options = MParticleOptions(key: "", secret: "")
options.logLevel = MPILogLevel.verbose
MParticle.sharedInstance().start(with: options)

return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

// MARK: - FlutterStreamHandler

func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
self.eventSink = events
if isInitialized {
events(["initialized": true])
}
return nil
}

func onCancel(withArguments arguments: Any?) -> FlutterError? {
self.eventSink = nil
return nil
}

// MARK: - mParticle Initialization

@objc private func handleMParticleInitialized(notification: Notification) {
isInitialized = true
if let eventSink = self.eventSink {
eventSink(["initialized": true])
}
}

deinit {
NotificationCenter.default.removeObserver(self)
}
}
38 changes: 34 additions & 4 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:mparticle_flutter_sdk/mparticle_flutter_sdk.dart';
import 'package:mparticle_flutter_sdk/events/event_type.dart';
import 'package:mparticle_flutter_sdk/events/commerce_event.dart';
Expand Down Expand Up @@ -35,6 +37,11 @@ final myController = TextEditingController();

class _MyAppState extends State<MyApp> {
bool _isInitialized = false;
StreamSubscription? _initializationSubscription;

// EventChannel for receiving mParticle initialization notifications
static const EventChannel _initializationEventChannel =
EventChannel('com.example.mparticle_initialization');

TextButton buildButton(text, onPressedFunction) {
return TextButton(
Expand All @@ -60,15 +67,38 @@ class _MyAppState extends State<MyApp> {
initMparticle();
}

@override
void dispose() {
_initializationSubscription?.cancel();
super.dispose();
}

MparticleFlutterSdk? mpInstance;

// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initMparticle() async {
mpInstance = await MparticleFlutterSdk.getInstance();
if (mpInstance != null) {
setState(() {
_isInitialized = true;
if (Platform.isIOS) {
// iOS: Subscribe to mParticle initialization events from native code
_initializationSubscription = _initializationEventChannel
.receiveBroadcastStream()
.listen((event) async {
if (event is Map && event['initialized'] == true) {
print("mParticle initialized from native layer");
mpInstance = await MparticleFlutterSdk.getInstance();
setState(() {
_isInitialized = true;
});
}
});
} else {
// Android and other platforms: Use original initialization
mpInstance = await MparticleFlutterSdk.getInstance();

if (mpInstance != null) {
setState(() {
_isInitialized = true;
});
}
}
}

Expand Down
Loading
Loading