# Native Integrations

Native integrations are crucial when you need to access platform-specific features or APIs that are not covered by existing Flutter plugins. Let's delve into how you can achieve this in Flutter.

## 1. **Platform Channels**:

Platform channels are the bridge between Flutter (Dart) code and the native code (Swift for iOS, Kotlin/Java for Android). They allow you to communicate between these different environments.

### a. **MethodChannel**:

#### **Dart Side**:

```dart
final channel = MethodChannel('samples.flutter.dev/battery');

Future<void> getBatteryLevel() async {
  final int batteryLevel = await channel.invokeMethod('getBatteryLevel');
}
```

1. `final channel = MethodChannel('samples.flutter.dev/battery');` - Here, you're creating a new `MethodChannel` with a unique name `samples.flutter.dev/battery`.
2. `getBatteryLevel` is a function that will request the battery level from the native side.
3. `await channel.invokeMethod('getBatteryLevel');` - You're asking the native side to execute a method named `getBatteryLevel` and await its result.

#### **Swift Side**:

```swift
let channel = FlutterMethodChannel(name: "samples.flutter.dev/battery", binaryMessenger: controller.binaryMessenger)

channel.setMethodCallHandler {
  (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
  // Handle battery messages.
}
```

1. `let channel = FlutterMethodChannel(name: "samples.flutter.dev/battery", binaryMessenger: controller.binaryMessenger)` - This line creates a method channel on the native side with the same name as on the Dart side.
2. `channel.setMethodCallHandler { ... }` - This sets up a handler for method calls on this channel. When Dart asks for `getBatteryLevel`, this handler gets called.

### b. **EventChannel**:

Event channels are used for communication that flows from the native code to Dart.

#### **Dart Side**:

```dart
final channel = EventChannel('samples.flutter.dev/stream');
```

* Here, you're creating a new `EventChannel` with a unique name `samples.flutter.dev/stream`.

#### **Swift Side**:

```swift
let channel = FlutterEventChannel(name: "samples.flutter.dev/stream", binaryMessenger: controller.binaryMessenger)
```

* Similar to the `MethodChannel`, you create an `EventChannel` on the native side with the same name as on the Dart side.

***

## 2. **Creating Platform-Specific Implementations**:

Create a new project with platform-specific code using the following command:

```bash
flutter create --template=plugin -i swift -a kotlin my_plugin
```

This command specifies Swift for iOS and Kotlin for Android as the languages to be used for platform-specific code.

***

## 3. **Handling Platform-Specific Code**:

You can handle platform-specific code by creating separate directories for iOS and Android, and placing the respective native code within these directories.

```plaintext
lib/
  platform/
    android/
      android_plugin.dart
    ios/
      ios_plugin.dart
```

***

## 4. **Calling Platform-Specific Code**:

In your Dart code, you can conditionally call platform-specific code using `Platform.isIOS` or `Platform.isAndroid`.

```dart
if (Platform.isIOS) {
  // Call iOS code
} else if (Platform.isAndroid) {
  // Call Android code
}
```

***

## Assignments 📝

* [ ] Create a simple plugin that communicates between Flutter and native code.
* [ ] Experiment with MethodChannel and EventChannel to understand how data is passed between Dart and native code.
* [ ] Implement a feature in your app that requires platform-specific integration and test it on both iOS and Android.

***

## Further Reading 📚

* [Flutter Platform Channels](https://flutter.dev/docs/development/platform-integration/platform-channels)
* [Writing custom platform-specific code](https://flutter.dev/docs/development/platform-integration/platform-channels#example-project)

{% hint style="info" %}
By understanding and utilizing Flutter's platform channels and creating platform-specific implementations, you can extend your Flutter app with native functionalities and ensure a comprehensive and integrated user experience across both Android and iOS platforms.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://flutteruniversity.gitbook.io/docs/learn-flutter/professional/native-integrations.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
