> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bit2connect.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Flutter SDK

> Integrate Bit2Connect dynamic links into your Flutter applications

## Installation

Add the Bit2Connect Flutter SDK to your `pubspec.yaml`:

```yaml theme={null}
dependencies:
  bit2connect_sdk: ^1.0.0
```

Then run:

```bash theme={null}
flutter pub get
```

## Setup

### 1. Initialize the SDK

Initialize the SDK in your app's main function:

```dart theme={null}
import 'package:bit2connect_sdk/bit2connect_sdk.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Initialize Bit2Connect SDK
    Bit2ConnectSDK.initialize(
      apiKey: 'b2co_your_api_key_here',
      projectId: 'your_project_id',
    );

    return MaterialApp(
      title: 'My App',
      home: HomePage(),
    );
  }
}
```

### 2. Configure Deep Link Handling

Add deep link handling to your app:

```dart theme={null}
class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  void initState() {
    super.initState();
    _handleInitialLink();
    _handleIncomingLinks();
  }

  // Handle app launch from dynamic link
  Future<void> _handleInitialLink() async {
    final initialLink = await Bit2ConnectSDK.getInitialLink();
    if (initialLink != null) {
      _processDynamicLink(initialLink);
    }
  }

  // Handle incoming links while app is running
  void _handleIncomingLinks() {
    Bit2ConnectSDK.onLinkReceived.listen((link) {
      _processDynamicLink(link);
    });
  }

  void _processDynamicLink(DynamicLinkData linkData) {
    // Handle the dynamic link data
    print('Received link: ${linkData.shortUrl}');
    print('Original URL: ${linkData.originalUrl}');

    // Navigate to appropriate screen based on link data
    if (linkData.payload != null) {
      _navigateToContent(linkData.payload!);
    }
  }

  void _navigateToContent(Map&lt;String, dynamic&gt; payload) {
    // Implement your navigation logic here
    // Example: Navigate to a specific product page
    if (payload.containsKey('productId')) {
      Navigator.pushNamed(context, '/product',
        arguments: payload['productId']);
    }
  }
}
```

## API Reference

### Bit2ConnectSDK

The main SDK class for handling dynamic links.

#### Methods

##### `initialize({required String apiKey, required String projectId})`

Initialize the Bit2Connect SDK with your API credentials.

**Parameters:**

* `apiKey` (String): Your Bit2Connect API key
* `projectId` (String): Your project ID

**Example:**

```dart theme={null}
Bit2ConnectSDK.initialize(
  apiKey: 'b2co_your_api_key_here',
  projectId: 'your_project_id',
);
```

##### `getInitialLink()`

Get the initial dynamic link that launched the app (if any).

**Returns:** `Future<DynamicLinkData?>`

**Example:**

```dart theme={null}
final initialLink = await Bit2ConnectSDK.getInitialLink();
if (initialLink != null) {
  // Process the initial link
}
```

##### `onLinkReceived`

Stream that emits dynamic link data when a new link is received.

**Type:** `Stream<DynamicLinkData>`

**Example:**

```dart theme={null}
Bit2ConnectSDK.onLinkReceived.listen((linkData) {
  // Handle incoming link
});
```

### DynamicLinkData

Represents the data from a dynamic link.

#### Properties

* `shortUrl` (String): The shortened Bit2Connect URL
* `originalUrl` (String): The original URL that was shortened
* `payload` (Map\<String, dynamic>?): Custom data associated with the link
* `createdAt` (DateTime): When the link was created
* `expiresAt` (DateTime?): When the link expires (if applicable)

## Platform Configuration

### Android Configuration

Add the following to your `android/app/src/main/AndroidManifest.xml`:

```xml theme={null}
<activity
    android:name=".MainActivity"
    android:exported="true"
    android:launchMode="singleTop"
    android:theme="@style/LaunchTheme">

    <!-- Existing intent filters -->

    <!-- Bit2Connect dynamic link intent filter -->
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="https"
              android:host="bit2.co" />
    </intent-filter>
</activity>
```

### iOS Configuration

Add the following to your `ios/Runner/Info.plist`:

```xml theme={null}
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>bit2connect</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>https</string>
        </array>
    </dict>
</array>
```

## Testing

### Test Dynamic Links

You can test your integration using the Bit2Connect dashboard or API:

```dart theme={null}
// Test with a sample dynamic link
final testLink = 'https://b2co.link/abc12345';
final linkData = await Bit2ConnectSDK.processLink(testLink);
```

### Debug Mode

Enable debug logging to troubleshoot issues:

```dart theme={null}
Bit2ConnectSDK.initialize(
  apiKey: 'b2co_your_api_key_here',
  projectId: 'your_project_id',
  debugMode: true, // Enable debug logging
);
```

## Best Practices

<CardGroup cols={2}>
  <Card title="Error Handling" icon="exclamation-triangle">
    Always handle potential errors when processing dynamic links
  </Card>

  <Card title="User Experience" icon="user">
    Provide fallback navigation for invalid or expired links
  </Card>

  <Card title="Security" icon="shield">
    Validate link data before processing to ensure security
  </Card>

  <Card title="Performance" icon="bolt">
    Cache link data when appropriate to improve app performance
  </Card>
</CardGroup>

## Troubleshooting

### Common Issues

<AccordionGroup>
  <Accordion title="Links not being received">
    **Solution:** Ensure your app is properly configured for deep linking and
    the SDK is initialized before handling links.
  </Accordion>

  <Accordion title="iOS links not working">
    **Solution:** Verify that your iOS app's URL scheme is correctly configured in
    Info.plist and that the app is properly signed.
  </Accordion>

  <Accordion title="Android links not working">
    **Solution:** Check that your Android manifest includes the correct intent
    filters and that your app is set as the default handler for Bit2Connect
    links.
  </Accordion>
</AccordionGroup>

### Debug Tips

1. Enable debug mode to see detailed logging
2. Test with the Bit2Connect dashboard link tester
3. Verify your app's deep link configuration
4. Check that your API key has the correct permissions

## Example App

For a complete working example, check out our [Flutter example repository](https://github.com/bit2connect/bit2connect-flutter-example):

```bash theme={null}
git clone https://github.com/bit2connect/bit2connect-flutter-example.git
cd bit2connect-flutter-example
flutter pub get
flutter run
```

The example app demonstrates:

* Complete SDK integration
* Deferred deep linking
* Dynamic link creation
* Error handling
* Cross-platform support

## Code Examples

### E-commerce App

```dart theme={null}
void _processDynamicLink(DynamicLinkData linkData) {
  final payload = linkData.payload;

  if (payload != null) {
    switch (payload['type']) {
      case 'product':
        Navigator.pushNamed(context, '/product',
          arguments: payload['productId']);
        break;
      case 'category':
        Navigator.pushNamed(context, '/category',
          arguments: payload['categoryId']);
        break;
      case 'promotion':
        Navigator.pushNamed(context, '/promotion',
          arguments: payload['promoCode']);
        break;
    }
  }
}
```

### Social Media App

```dart theme={null}
void _processDynamicLink(DynamicLinkData linkData) {
  final payload = linkData.payload;

  if (payload != null) {
    if (payload.containsKey('postId')) {
      Navigator.pushNamed(context, '/post',
        arguments: payload['postId']);
    } else if (payload.containsKey('userId')) {
      Navigator.pushNamed(context, '/profile',
        arguments: payload['userId']);
    }
  }
}
```
