pnlight_sdk 0.7.0
pnlight_sdk: ^0.7.0 copied to clipboard
Flutter wrapper for PNLight iOS SDK.
PNLight SDK - Flutter Plugin #
A Flutter plugin that provides iOS integration with the PNLight SDK.
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
pnlight_sdk: ^0.1.0
Then run:
flutter pub get
Requirements #
- Flutter: >=3.3.0
- Dart: >=2.17.0 <4.0.0
- iOS: 12.0+
This package is iOS-only. Android is not supported.
iOS Setup #
DivKit Pod Source #
If you use RemoteUiView, add the DivKit CocoaPods source to your app's ios/Podfile before the default CocoaPods source:
source 'https://github.com/divkit/divkit-ios.git'
source 'https://cdn.cocoapods.org/'
Then run:
cd ios
pod install
Required Frameworks #
Make sure the host iOS app links the frameworks required by PNLight:
- StoreKit.framework
- CoreMotion.framework
- AdSupport.framework
- AppTrackingTransparency.framework
For apps that need IDFA tracking, add NSUserTrackingUsageDescription to Info.plist:
<key>NSUserTrackingUsageDescription</key>
<string>This app uses device tracking to provide analytics and improve user experience.</string>
Usage #
Initialization #
Initialize PNLight before using analytics, attribution, or Remote UI:
import 'package:flutter/widgets.dart';
import 'package:pnlight_sdk/pnlight_sdk.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await PNLightSDK.initialize('your-api-key');
runApp(MyApp());
}
Event Logging #
import 'package:pnlight_sdk/pnlight_sdk.dart';
await PNLightSDK.logEvent('purchase_completed', {
'product_id': 'premium_subscription',
'amount': 9.99,
'currency': 'USD',
});
Attribution #
Send attribution data from external providers before requesting UI config.
import 'package:pnlight_sdk/pnlight_sdk.dart';
final success = await PNLightSDK.addAttribution(
provider: 'appsFlyer',
data: {'af_status': 'Non-organic'},
identifier: 'your-appsflyer-id',
);
AppsFlyer Integration Example
import 'package:appsflyer_sdk/appsflyer_sdk.dart';
import 'package:pnlight_sdk/pnlight_sdk.dart';
final appsFlyerOptions = AppsFlyerOptions(
afDevKey: 'your-appsflyer-dev-key',
appId: 'your-ios-app-id',
showDebug: false,
);
final appsFlyerSdk = AppsflyerSdk(appsFlyerOptions);
appsFlyerSdk.onInstallConversionData((conversionData) async {
final appsFlyerId = await appsFlyerSdk.getAppsFlyerUID();
final payload = conversionData['payload'] ?? conversionData;
await PNLightSDK.addAttribution(
provider: 'appsFlyer',
data: Map<String, dynamic>.from(payload as Map),
identifier: appsFlyerId,
);
});
await appsFlyerSdk.initSdk(
registerConversionDataCallback: true,
registerOnAppOpenAttributionCallback: false,
registerOnDeepLinkingCallback: false,
);
Supported providers:
appsFlyerfirebasefacebook
User Identity #
import 'package:pnlight_sdk/pnlight_sdk.dart';
final userId = await PNLightSDK.getUserId();
RemoteUiView - Server-driven UI #
RemoteUiView fetches and renders a server-driven layout from PNLight for a given placement. It calls getUIConfig(placement) internally, renders the native view, and emits action events to Dart.
When using external attribution providers such as AppsFlyer, send attribution first and request UI config only after the attribution callback is processed. In production, it is recommended to wait 3-5 seconds before requesting config so provider data has time to become available.
import 'package:flutter/widgets.dart';
import 'package:pnlight_sdk/pnlight_sdk.dart';
class PaywallScreen extends StatelessWidget {
const PaywallScreen({super.key});
void _handleAction(RemoteUiActionEvent event) {
if (event.logId == 'purchase_button') {
final productId = event.params['id'];
// Start purchase flow for productId
} else if (event.logId == 'close_button') {
// Close the screen
}
}
@override
Widget build(BuildContext context) {
return RemoteUiView(
placement: 'paywall',
onAction: _handleAction,
);
}
}
Manual Config Fetching #
Use getUIConfig if you need to fetch the placement configuration yourself. When attribution is required, call it after sending attribution and preferably after a 3-5 second delay:
import 'package:pnlight_sdk/pnlight_sdk.dart';
await Future<void>.delayed(const Duration(seconds: 3));
final config = await PNLightSDK.getUIConfig('paywall');
final configWithoutAttributionWait = await PNLightSDK.getUIConfig(
'paywall',
attributionRequired: false,
);
API Reference #
PNLightSDK #
| Method | Description |
|---|---|
initialize(apiKey, baseDomain?) |
Initialize the SDK with your API key and optional base domain |
logEvent(eventName, eventArgs?) |
Log a custom event with optional arguments |
addAttribution(provider, data?, identifier?) |
Send attribution data from AppsFlyer, Firebase, or Facebook |
getUserId() |
Get or create a stable user identifier |
prefetchUIConfig(placement) |
Prefetch a UI config into the in-memory cache |
getUIConfig(placement, attributionRequired?) |
Fetch a UI config; waits for attribution by default |
RemoteUiView #
| Parameter | Type | Description |
|---|---|---|
placement |
String |
PNLight placement identifier |
cardId |
String? |
Card identifier; defaults to pnlight_<placement> |
secure |
bool |
Deprecated. Secure rendering is controlled by the backend response. |
preventRecording |
bool |
Deprecated. Capture blocking is controlled by the backend. |
onAction |
void Function(RemoteUiActionEvent)? |
Called when a custom action is triggered |
RemoteUiActionEvent #
| Property | Type | Description |
|---|---|---|
url |
String |
Full URL string of the triggered action |
scheme |
String |
URL scheme |
path |
String |
URL path component |
params |
Map<String, String> |
Query parameters extracted from the URL |
logId |
String? |
Log ID for the triggered action |
action |
String? |
Raw action value when provided by the native view |
UIConfig #
| Property | Type | Description |
|---|---|---|
config |
String? |
Remote UI JSON config |
parameters |
Map<String, dynamic>? |
Placement parameters returned by PNLight |
debug |
bool? |
Debug flag returned by PNLight |
Support #
For support and questions, visit docs.pnlight.app.