Official Expo Config Plugin for integrating the Poilabs Analysis SDK into Expo (prebuild) projects.
🚀 Automatically links native dependencies and modifies required iOS/Android files.
When used with expo prebuild
, this plugin:
- ✅ Adds required Android permissions to
AndroidManifest.xml
- ✅ Adds
android:foregroundServiceType="location"
to theFOREGROUND_SERVICE
permission - ✅ Adds Poilabs SDK dependency to
android/app/build.gradle
- ✅ Adds JitPack repository to
android/build.gradle
- ✅ Adds
pod 'PoilabsAnalysis'
to the iOS Podfile - ✅ Adds
Info.plist
keys for Location and Bluetooth usage
Install the plugin to your Expo project:
npm install @poilabs-dev/analysis-sdk-plugin
# or
yarn add @poilabs-dev/analysis-sdk-plugin
Also install the required dependencies:
npx expo install expo-location expo-device
Add the plugin to your app.json
or app.config.js
:
{
"expo": {
"plugins": [
[
"@poilabs-dev/analysis-sdk-plugin",
{
"jitpackToken": "YOUR_JITPACK_TOKEN" // Get this from Poilabs
}
]
]
}
}
Then run the prebuild command:
npx expo prebuild
After running expo prebuild
, you need to perform these additional steps:
-
Open your project's
MainApplication.kt
file and add the following import:import com.anonymous.<APPNAME>.PoilabsPackage
-
Find the
getPackages()
method and add the PoilabsPackage:override fun getPackages(): List<ReactPackage> { val packages = PackageList(this).packages // add this line packages.add(PoilabsPackage()) return packages }
-
Clean and rebuild your Android project:
cd android ./gradlew clean cd .. npx expo run:android
- You should create local.properties to android root
- and you should add this => sdk.dir=/Users/USERNAME/Library/Android/sdk
For iOS, you need to ensure the plugin files are properly included in your Xcode project:
- Open your Xcode project
- In Xcode, verify that the PoilabsModule files are added to your project
- Check that the files appear in the "Build Phases > Compile Sources" section
- Find + button and click. Then you should "add other".
- If files are missing, you may need to manually add them from the iOS//PoilabsModule directory:
- PoilabsAnalysisModule.h
- PoilabsAnalysisModule.m
- cd ios
- pod deintegrate
- pod install --repo-update
Note: When developing for iOS, there's an important consideration regarding ARM64 architecture:
- If you're integrating into an existing project (which already has ARM64 support), you shouldn't encounter any issues.
- However, if you're creating a project from scratch, you need to remove the ARM64 reference from the Build Settings in Xcode. Otherwise, you might face compilation errors.
This setting is particularly important when developing on M series (Apple Silicon) Mac computers.
Then build and run your iOS project:
npx expo run:ios
After the prebuild process, you can use the SDK in your application:
import { Image } from "expo-image";
import { useEffect, useState } from "react";
import { StyleSheet, TouchableOpacity } from "react-native";
import { HelloWave } from "@/components/HelloWave";
import ParallaxScrollView from "@/components/ParallaxScrollView";
import { ThemedText } from "@/components/ThemedText";
import { ThemedView } from "@/components/ThemedView";
import {
startPoilabsAnalysis,
stopPoilabsAnalysis,
} from "@poilabs-dev/analysis-sdk-plugin";
export default function HomeScreen() {
const [sdkStatus, setSdkStatus] = useState("Initializing...");
useEffect(() => {
const initAnalysis = async () => {
try {
// Start Poilabs SDK
const success = await startPoilabsAnalysis({
applicationId: "YOUR_APPLICATION_ID", // Get from Poilabs
applicationSecret: "YOUR_APPLICATION_SECRET", // Get from Poilabs
uniqueId: "USER_UNIQUE_ID", // A unique identifier for the user
});
setSdkStatus(success ? "Running ✅" : "Failed to start ❌");
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : String(error);
setSdkStatus("Error: " + errorMessage);
}
};
initAnalysis();
}, []);
const handleStopSDK = () => {
try {
const result = stopPoilabsAnalysis();
setSdkStatus(result ? "Stopped ⛔" : "Failed to stop ❓");
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : String(error);
setSdkStatus("Stop Error: " + errorMessage);
}
};
return (
<ParallaxScrollView
headerBackgroundColor={{ light: "#A1CEDC", dark: "#1D3D47" }}
headerImage={
<Image
source={require("@/assets/images/partial-react-logo.png")}
style={styles.reactLogo}
/>
}
>
<ThemedView style={styles.titleContainer}>
<ThemedText type="title">Welcome!</ThemedText>
<HelloWave />
</ThemedView>
{/* SDK Status Indicator */}
<ThemedView style={styles.sdkStatusContainer}>
<ThemedText type="subtitle">Poilabs SDK: {sdkStatus}</ThemedText>
{/* Stop SDK Button */}
<TouchableOpacity style={styles.stopButton} onPress={handleStopSDK}>
<ThemedText style={styles.buttonText}>STOP SDK</ThemedText>
</TouchableOpacity>
</ThemedView>
</ParallaxScrollView>
);
}
const styles = StyleSheet.create({
titleContainer: {
flexDirection: "row",
alignItems: "center",
gap: 8,
},
reactLogo: {
height: 178,
width: 290,
bottom: 0,
left: 0,
position: "absolute",
},
sdkStatusContainer: {
marginVertical: 16,
padding: 10,
borderRadius: 8,
backgroundColor: "#f5f5f5",
alignItems: "center",
},
stopButton: {
marginTop: 10,
backgroundColor: "#FF3B30",
paddingVertical: 8,
paddingHorizontal: 16,
borderRadius: 6,
},
buttonText: {
color: "white",
fontWeight: "bold",
},
});
Starts the Poilabs Analysis SDK with the given configuration.
-
config
(Object):-
applicationId
(String): The application ID provided by Poilabs -
applicationSecret
(String): The application secret provided by Poilabs -
uniqueId
(String): A unique identifier for the user
-
-
Promise<boolean>
: Resolves totrue
if SDK was started successfully,false
otherwise
Stops the Poilabs Analysis SDK.
-
boolean
:true
if SDK was stopped successfully,false
otherwise
Updates the unique identifier in the SDK after initialization.
-
uniqueId
(String): New unique identifier for the user
-
Promise<boolean>
: Resolves totrue
if update was successful
Requests all the required permissions for the SDK to work properly.
-
Promise<boolean>
: Resolves totrue
if all required permissions are granted,false
otherwise
Checks if all required permissions are granted.
-
Promise<boolean>
:true
if all required permissions are granted,false
otherwise
Checks if Bluetooth permissions are granted (relevant for Android 12+).
-
Promise<boolean>
:true
if Bluetooth permissions are granted,false
otherwise
The plugin automatically adds these permissions:
-
INTERNET
- For network communication -
ACCESS_FINE_LOCATION
- For precise location -
ACCESS_COARSE_LOCATION
- For approximate location (Android 9 and below) -
ACCESS_BACKGROUND_LOCATION
- For background location tracking (Android 10+) -
BLUETOOTH_CONNECT
- For Bluetooth connectivity (Android 12+) -
BLUETOOTH_SCAN
- For Bluetooth scanning (Android 12+) -
FOREGROUND_SERVICE
withforegroundServiceType="location"
- For background operations
-
NSLocationWhenInUseUsageDescription
- Location permission when app is in use -
NSLocationAlwaysUsageDescription
- Location permission even when app is not in use -
NSBluetoothAlwaysUsageDescription
- Bluetooth permission
If you see PoilabsAnalysisModule
not found error:
- Make sure you have run
npx expo prebuild
- Verify you've completed the additional setup steps for Android/iOS
- Run
npx expo run:android
ornpx expo run:ios
to build and run the native project - For Expo Go, this plugin will not work because it requires native modules
If you're having issues with iOS integration:
- Make sure the Podfile is correctly updated with
pod 'PoilabsAnalysis'
- Verify that
use_frameworks! :linkage => :static
is in your Podfile - Check that the Swift files are properly added to your project
- Run
pod install --repo-update
from the ios directory
If the SDK is not working due to permission issues:
- Make sure you have requested all the necessary permissions
- For Android 10+, background location permission needs to be requested separately
If you encounter any issues, please contact Poilabs support or open an issue on GitHub.