-
Notifications
You must be signed in to change notification settings - Fork 281
Implement a plugin
Flutter uses a flexible system that allows you to call platform-specific APIs, make sure to be familiar with the way Flutter handles platform calls on Android or iOS before going further. A great tutorial is available on flutter.dev.
The following code demonstrates the matching Go implementation described in the official Flutter platform-channels docs
The goal is to retrieve the current battery level of the device via a single platform message, getBatteryLevel
.
Matching step in the official Flutter docs
We use a MethodChannel with a single platform method that returns the battery level.
// File: lib/main_desktop.dart
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
// The client and host sides of a channel are connected through
// a channel name passed in the channel constructor.
const platform = const MethodChannel('samples.flutter.dev/battery');
void main() {
test('Test Battery Plugin result', () async {
// Invoke a method on the method channel, specifying the concrete
// method to call via the String identifier.
final int result = await platform.invokeMethod('getBatteryLevel');
expect(result, 55);
final String batteryLevel = 'Battery level at $result % .';
print(batteryLevel);
SystemNavigator.pop(); // close the app
});
}
The following code implementation the Golang platform channels.
The package name chosen is flutterGuide
, making the Plugin available by accessing
&flutterGuide.MyBatteryPlugin{}
// File: main.go
package flutterGuide
import (
flutter "github.com/go-flutter-desktop/go-flutter"
"github.com/go-flutter-desktop/go-flutter/plugin"
)
const channelName = "samples.flutter.dev/battery"
// MyBatteryPlugin demonstrates how to call a platform-specific API to retrieve
// the current battery level.
//
// This example matches the guide example available on:
// https://flutter.dev/docs/development/platform-integration/platform-channels
type MyBatteryPlugin struct{}
var _ flutter.Plugin = &MyBatteryPlugin{} // compile-time type check
// InitPlugin creates a MethodChannel and set a HandleFunc to the
// MethodChannel through the HandleFunc method.
// https://godoc.org/github.com/go-flutter-desktop/go-flutter/plugin#MethodChannel
//
// The plugin is using a MethodChannel through the StandardMethodCodec.
// You can also use the more basic BasicMessageChannel, which supports basic,
// asynchronous message passing using a custom message codec. You can also use
// the specialized BinaryCodec, StringCodec, and JSONMessageCodec struct, or
// create your own codec.
//
// The JSONMessageCodec was deliberately left out because in Go its better to
// decode directly to known structs.
func (p *MyBatteryPlugin) InitPlugin(messenger plugin.BinaryMessenger) error {
channel := plugin.NewMethodChannel(messenger, channelName, plugin.StandardMethodCodec{})
channel.HandleFunc("getBatteryLevel", handleGetBatteryLevel)
return nil // no error
}
// handleGetBatteryLevel is called when the method getBatteryLevel is invoked by
// the dart code.
// The function returns a fake battery level, without raising an error.
//
// Supported return types are described in a table:
// https://godoc.org/github.com/go-flutter-desktop/go-flutter/plugin#StandardMessageCodec
func handleGetBatteryLevel(arguments interface{}) (reply interface{}, err error) {
batteryLevel := int32(55) // Your platform-specific API
return batteryLevel, nil
}
Before adding this plugin to go-flutter, we need to setup few requirements:
- go-flutter uses Go modules. Make sure your go version is updated.
- A
go.mod
andgo.sum
file.
Next to the above main.go
file, generate the go.mod
and go.sum
files
using:
export GO111MODULE=on # enable go modules
go mod init github.com/go-flutter-desktop/plugins/flutterGuide # creating the go.mod
go mod tidy # adds missing modules
Outputs:
// File: Generated go.mod
module github.com/go-flutter-desktop/plugins/flutterGuide
go 1.12
require github.com/go-flutter-desktop/go-flutter vX.XX.X
Your plugin is DONE!
First, read the Plugin info wiki section.
Assuming you are using hover
, and you have initialized hover
in your Flutter project, edit the option.go file and add your local plugin.
Our option.go file is looking like this:
// File: desktop/cmd/options.go
package main
import (
"github.com/go-flutter-desktop/go-flutter"
"github.com/go-flutter-desktop/plugins/flutterGuide" // <- url set in `go mod init 'url'`
)
var options = []flutter.Option{
flutter.AddPlugin(&flutterGuide.MyBatteryPlugin{}), // our plugin
flutter.WindowInitialDimensions(200, 200),
flutter.PopBehavior(flutter.PopBehaviorClose), // on SystemNavigator.pop() closes the app
}
To fetch the dependency, hover
uses the go.mod
located under the desktop/
directory of your Flutter project.
Since there is no go module available at the github.com/go-flutter-desktop/plugins/flutterGuide url.
Our build will fail.
$ hover run
go: github.com/go-flutter-desktop/plugins/[email protected]: unknown revision flutterGuide/v0.1.0
go: error loading module requirements
Go get -u github.com/go-flutter-desktop/go-flutter failed: exit status 1
To test before publishing, we can use the replace
directive in /desktop/go.mod
.
Our go.mod
file now looks something like this:
// File ./desktop/go.mod
module github.com/go-flutter-desktop/examples/pointer_demo/desktop
go 1.12
require (
github.com/go-flutter-desktop/go-flutter vX.XX.X
github.com/go-flutter-desktop/plugins/flutterGuide v0.1.0
)
replace github.com/go-flutter-desktop/plugins/flutterGuide => /home/drakirus/lab/go/src/lab/flutterGuide
Go wont try to fetch MyBatteryPlugin at the github.com/go-flutter-desktop/plugins/flutterGuide VCS url, instead it will use one located on your file filesystem.
The new import path from the replace directive is used without needing to update the import paths in the actual source code.
$ hover run
flutter: Observatory listening on http://127.0.0.1:50300/GAkYtsSwdYU=/
flutter: 00:00 +0: Test Battery Plugin result
flutter: Battery level at 55 % .
flutter: 00:00 +1: All tests passed!
go-flutter: closing application
app 'guide_plugin' exited.
- You can read existing implementations, path_provider is a good example.
- For more informations, read the our docs about Plugin: here and here.