npm package: @surveysensum/ssinapp-react-native
Description: SurveySensum In-App Survey SDK for React Native
Latest version: 1.0.12

# SsinApp React Native SDK

A React Native SDK for in-app surveys. This SDK allows you to easily integrate surveys into your React Native applications with the same API.

> **📦 Package:** `@surveysensum/ssinapp-react-native`  
> **📝 Version:** 1.0.0  
> **✅ Status:** Ready for production use

## 🚀 Features

- ✅ WebView Integration - Built-in WebViewLauncherScreen component
- ✅ Token Management - Secure token handling with encoding
- ✅ Contact Data - User information management
- ✅ Metadata Support - Custom metadata for surveys
- ✅ Multiple Layouts - Full screen, popup, and embed modes
- ✅ Image Picker - Camera and gallery integration
- ✅ Error Handling - Comprehensive error management
- ✅ TypeScript Support - Full TypeScript definitions
- ✅ SurveyModalManager - Automatic survey presentation handling

## 📦 Installation

### Install the Package

```bash
npm install @surveysensum/ssinapp-react-native
```

Or with yarn:

```bash
yarn add @surveysensum/ssinapp-react-native
```

### Peer Dependencies

This package requires the following peer dependencies. Install them if they're not already in your project:

```bash
npm install react-native-webview @react-native-async-storage/async-storage react-native-image-picker react-native-toast-message
```

Or with yarn:

```bash
yarn add react-native-webview @react-native-async-storage/async-storage react-native-image-picker react-native-toast-message
```

**Note:** The package automatically includes these as dependencies, but you may need to install them separately if you encounter peer dependency warnings.

### Android Setup

#### Add Permissions in AndroidManifest.xml

Add the following permissions to `android/app/src/main/AndroidManifest.xml`:

```xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
```

#### Sync Gradle

After adding permissions, sync your Android project:

```bash
cd android && ./gradlew clean
```

### iOS Setup

#### Install Pods

```bash
cd ios && pod install
```

#### Add to ios/YourApp/Info.plist

Add the following configuration to your `Info.plist`:

```xml
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>surveysensum.com</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSExceptionMinimumTLSVersion</key>
            <string>TLSv1.0</string>
        </dict>
    </dict>
</dict>
<key>NSCameraUsageDescription</key>
<string>This app needs access to camera to take photos for surveys</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs access to photo library to select images for surveys</string>
```

## 🎉 Getting Started

### 1. Install Dependencies

Follow the installation steps above to install all required packages.

### 2. Configure Platform Settings

Set up Android permissions and iOS Info.plist as described in the setup sections.

### 3. Basic Integration

Import and configure the SDK in your app:

```typescript
import Ssinappreactnative, {
  BaseUrlManager,
  ContactManager,
  MetaDataManager,
  SurveyModalManager,
  TokenManager,
  SurveyCallbacks,
} from '@surveysensum/ssinapp-react-native';
```

### 4. Configure Subdomain, Token, etc

```typescript
// Set your SurveySensum subdomain
BaseUrlManager.setSubdomain('your-subdomain');

// Set your survey tokens
TokenManager.setTokens(['your-token-here']);

// Set user contact data (optional)
const userData = new Map<string, string>();
userData.set('email', 'user@example.com');
userData.set('name', 'John Doe');
ContactManager.setContactDataFromMap(userData);

// Set metadata (optional)
const metadata = new Map<string, string>();
metadata.set('appVersion', '1.0.0');
metadata.set('platform', 'react-native');
MetaDataManager.setMetadataFromMap(metadata);
```

### 5. Add SurveyModalManager to Your App

Add the `SurveyModalManager` component to your root component:

```typescript
import React from 'react';
import { View } from 'react-native';
import { SurveyModalManager } from '@surveysensum/ssinapp-react-native';

const App = () => {
  return (
    <View style={{ flex: 1 }}>
      {/* Your app content */}
      <SurveyModalManager />
    </View>
  );
};
```

### 6. Open Survey

```typescript
const callbacks: SurveyCallbacks = {
  onRespond: (message) => {
    console.log('User responded to question:', message);
  },
  onComment: (message) => {
    console.log('User added comment:', message);
  },
  onShow: () => {
    console.log('Survey is now visible to user');
  },
  onHide: () => {
    console.log('Survey is now hidden from user');
  },
};

await Ssinappreactnative.openWebView('https://fallback-url.com', {
  urlMatcher: 'trigger-value',
  callbacks,
});
```

## 📝 Complete Example

```typescript
import React, { useState } from 'react';
import {
  SafeAreaView,
  ScrollView,
  StyleSheet,
  Text,
  TextInput,
  TouchableOpacity,
  View,
} from 'react-native';

import Ssinappreactnative, {
  BaseUrlManager,
  ContactManager,
  MetaDataManager,
  SurveyModalManager,
  TokenManager,
  SurveyCallbacks,
} from '@surveysensum/ssinapp-react-native';

const SurveyScreen = () => {
  const [subdomain, setSubdomain] = useState('your-subdomain');
  const [token, setToken] = useState('your-token-here');
  const [triggerUrl, setTriggerUrl] = useState('https://fallback-url.com');
  const [triggerValue, setTriggerValue] = useState('trigger-value');
  const [email, setEmail] = useState('demo@example.com');
  const [name, setName] = useState('John Doe');

  const callbacks: SurveyCallbacks = {
    onRespond: (message) => {
      console.log('User responded to question:', message);
    },
    onComment: (message) => {
      console.log('User added comment:', message);
    },
    onShow: () => {
      console.log('Survey is now visible to user');
    },
    onHide: () => {
      console.log('Survey is now hidden from user');
    },
  };

  const handleOpenSurvey = async (): Promise<void> => {
    // Configure base URL
    BaseUrlManager.setSubdomain(subdomain);
    
    // Set tokens
    TokenManager.setTokens([token]);

    // Set user contact data
    const userData = new Map<string, string>();
    userData.set('email', email);
    userData.set('name', name);
    ContactManager.setContactDataFromMap(userData);

    // Set metadata
    const metadata = new Map<string, string>();
    metadata.set('appVersion', '1.0.0');
    metadata.set('platform', 'react-native');
    MetaDataManager.setMetadataFromMap(metadata);

    // Open survey
    await Ssinappreactnative.openWebView(triggerUrl, {
      urlMatcher: triggerValue,
      callbacks,
    });
  };

  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.container}>
        <ScrollView contentContainerStyle={styles.content}>
          <Text style={styles.title}>Survey Configuration</Text>

          <Text style={styles.label}>Subdomain</Text>
          <TextInput
            style={styles.input}
            value={subdomain}
            onChangeText={setSubdomain}
          />

          <Text style={styles.label}>Token</Text>
          <TextInput
            style={styles.input}
            value={token}
            onChangeText={setToken}
          />

          <Text style={styles.label}>Trigger URL</Text>
          <TextInput
            style={styles.input}
            value={triggerUrl}
            onChangeText={setTriggerUrl}
          />

          <Text style={styles.label}>Trigger Value</Text>
          <TextInput
            style={styles.input}
            value={triggerValue}
            onChangeText={setTriggerValue}
          />

          <Text style={styles.label}>Email</Text>
          <TextInput
            style={styles.input}
            value={email}
            onChangeText={setEmail}
          />

          <Text style={styles.label}>Name</Text>
          <TextInput
            style={styles.input}
            value={name}
            onChangeText={setName}
          />

          <TouchableOpacity style={styles.button} onPress={handleOpenSurvey}>
            <Text style={styles.buttonText}>Open Survey</Text>
          </TouchableOpacity>
        </ScrollView>
      </View>
      
      {/* SurveyModalManager handles survey presentation */}
      <SurveyModalManager />
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f5f5f5',
  },
  content: {
    padding: 20,
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 10,
    color: '#333',
    textAlign: 'center',
  },
  label: {
    alignSelf: 'flex-start',
    fontSize: 14,
    marginBottom: 5,
    color: '#444',
    fontWeight: '600',
  },
  input: {
    width: '100%',
    height: 45,
    borderWidth: 1,
    borderColor: '#ccc',
    borderRadius: 8,
    paddingHorizontal: 10,
    marginBottom: 15,
    backgroundColor: '#fff',
  },
  button: {
    marginTop: 20,
    backgroundColor: '#007AFF',
    paddingVertical: 12,
    borderRadius: 8,
    alignItems: 'center',
  },
  buttonText: {
    color: '#fff',
    fontSize: 16,
    fontWeight: '600',
  },
});

export default SurveyScreen;
```

## 🔧 Configuration

### Required Configuration

- **Subdomain**: Your SurveySensum subdomain
- **Token**: Survey token(s) for authentication
- **Trigger Value**: Value to match and trigger the survey

### Optional Configuration

- **Contact Data**: User information (email, name, etc.)
- **Metadata**: Custom metadata for surveys (appVersion, platform, etc.)
- **Fallback URL**: URL to use if survey cannot be loaded
- **Callbacks**: Event handlers for survey events

### Configuration Example

```typescript
// Required
BaseUrlManager.setSubdomain('your-subdomain');
TokenManager.setTokens(['your-token-here']);

// Optional - Contact Data
const userData = new Map<string, string>();
userData.set('email', 'user@example.com');
userData.set('name', 'John Doe');
ContactManager.setContactDataFromMap(userData);

// Optional - Metadata
const metadata = new Map<string, string>();
metadata.set('appVersion', '1.0.0');
metadata.set('platform', 'react-native');
MetaDataManager.setMetadataFromMap(metadata);
```

## 📚 API Reference

### Ssinappreactnative

Main class for opening surveys.

#### Methods

##### `openWebView(fallbackUrl: string, options?: OpenWebViewOptions): Promise<void>`

Opens a survey with the specified configuration.

**Parameters:**

- `fallbackUrl` (string): Fallback URL to use if survey cannot be loaded
- `options` (OpenWebViewOptions, optional): Configuration options object containing:
  - `urlMatcher` (string, optional): Trigger value to match surveys
  - `customBuilder` (CustomWebViewBuilder, optional): Custom WebView builder function
  - `callbacks` (SurveyCallbacks, optional): Event callbacks

##### `setWebViewCallback(callback?: (surveyData: SurveyData) => void): void`

Sets a callback to receive survey data. This is typically handled automatically by `SurveyModalManager`.

##### `getSurveyData(): SurveyData | null`

Gets the current survey data if available.

### Manager Classes

#### BaseUrlManager

Manage base URL configuration.

**Methods:**

- `setSubdomain(subdomain: string): void` - Sets the SurveySensum subdomain
- `getBaseUrl(): string` - Gets the configured base URL

#### TokenManager

Manage tokens.

**Methods:**

- `setTokens(tokens: string[]): void` - Sets the survey tokens
- `addToken(token: string): void` - Adds a token to the list
- `removeToken(token: string): void` - Removes a token from the list
- `getTokens(): string[]` - Gets all tokens
- `clearTokens(): void` - Clears all tokens

#### ContactManager

Manage user contact data.

**Methods:**

- `setContactData(key: string, value: string): void` - Sets a single contact data field
- `setContactDataFromMap(dataMap: Map<string, string>): void` - Sets contact data from a Map
- `getData(key: string): string | undefined` - Gets a contact data field
- `getAllData(): Map<string, string>` - Gets all contact data
- `isDataAbsent(): boolean` - Checks if contact data is absent

#### MetaDataManager

Manage metadata.

**Methods:**

- `setMetadata(key: string, value: string): void` - Sets a single metadata field
- `setMetadataFromMap(dataMap: Map<string, string>): void` - Sets metadata from a Map
- `getMetadata(key: string): string | undefined` - Gets a metadata field
- `getAllMetadata(): Map<string, string>` - Gets all metadata

### WebViewLauncherScreen

Displays the survey in a WebView.

**Props:**

- `url` (string): Survey URL
- `layout` (number, optional): Layout type (1 = Full Screen, 2 = Popup, 3 = Sidebar, 4 = Embedded)
- `popupSize` (object, optional): Popup size configuration
- `token` (string): Survey token
- `inApp` (object): In-app configuration
- `onClose` (function, optional): Callback when survey is closed
- `hideCloseButton` (boolean, optional): Hide the close button
- `customBuilder` (function, optional): Custom WebView builder
- `callbacks` (SurveyCallbacks, optional): Event callbacks

### SurveyModalManager

React component that automatically handles survey presentation. Mount this component in your app to enable survey modals.

### SurveyCallbacks

Interface for survey event callbacks.

```typescript
interface SurveyCallbacks {
  onRespond?: (message: any) => void;
  onComment?: (message: any) => void;
  onShow?: () => void;
  onHide?: () => void;
}
```

### TypeScript Types

The package includes full TypeScript definitions. All types are exported and available:

- `OpenWebViewOptions` - Options for opening a survey
- `SurveyData` - Survey data structure
- `CustomWebViewBuilder` - Type for custom WebView builder function
- `SurveyCallbacks` - Event callbacks interface

## 📱 Survey Layouts

The SDK supports multiple survey layouts:

- **Full Screen** (Layout 1): Survey takes the full screen
- **Popup** (Layout 2): Survey appears as a popup modal
- **Sidebar** (Layout 3): Survey appears as a sidebar button that opens a popup
- **Embedded** (Layout 4): Survey is embedded within a view

## 🐛 Troubleshooting

### Network Request Failed

**Problem:** Network requests are failing.

**Solutions:**

- Check that Android permissions are added in `AndroidManifest.xml`
- Verify iOS `Info.plist` configuration for `NSAppTransportSecurity`
- Ensure internet permission is granted on the device
- Check network connectivity

### Survey Not Displaying

**Problem:** Survey is not showing up.

**Solutions:**

- Ensure `SurveyModalManager` is mounted in your app
- Verify that `Ssinappreactnative.openWebView()` is being called
- Check that the WebView callback is set (handled automatically by `SurveyModalManager`)
- Verify subdomain and token are correctly configured
- Check console logs for error messages

### Token Issues

**Problem:** Token-related errors.

**Solutions:**

- Ensure token is correct and properly encoded
- Verify token is set using `TokenManager.setTokens()`
- Check that token matches the subdomain configuration
- Verify token format is correct

### iOS Build Issues

**Problem:** iOS build fails after installation.

**Solutions:**

- Run `cd ios && pod install` after installing dependencies
- Clean build folder: `cd ios && xcodebuild clean`
- Verify `Info.plist` configuration is correct
- Check that all dependencies are properly linked

### Android Build Issues

**Problem:** Android build fails.

**Solutions:**

- Sync Gradle: `cd android && ./gradlew clean`
- Verify permissions in `AndroidManifest.xml`
- Check that all dependencies are properly installed
- Ensure minSdkVersion is compatible (minimum Android 5.0)

## 📱 Platform Support

- ✅ **Android** - Full support (Android 5.0+)
- ✅ **iOS** - Full support (iOS 10.0+)
- ✅ **TypeScript** - Full TypeScript definitions included with complete type safety
- ✅ **React Native 0.60+** - Compatible with React Native 0.60 and above
- ✅ **React 16.8+** - Requires React 16.8.0 or higher (hooks support)

## 📄 License

MIT

## 📦 Package Information

- **Package Name:** `@surveysensum/ssinapp-react-native`
- **Version:** 1.0.0
- **Main Entry:** `lib/index.js`
- **TypeScript Definitions:** `lib/index.d.ts`
- **Repository:** [Add your repository URL here]

## 🔄 Version History

### 1.0.0 (Current)
- Initial release
- Full TypeScript support with complete type definitions
- Complete API implementation
- Android and iOS support
- SurveyModalManager component for automatic survey presentation
- All manager classes (BaseUrlManager, TokenManager, ContactManager, MetaDataManager)
- WebViewLauncherScreen component
- Complete event callbacks support
- Image picker integration
- Multiple survey layouts (Full Screen, Popup, Sidebar, Embedded)

## 💬 Support

For issues and questions, please contact SurveySensum support.