Flutter plugin: What is it and how to create it for iOS and Android?

flutter plugin

Flutter is an open-source UI software kit developed by Google in 2017. Even if it is relatively new, it offers lots of promising features for free. What’s more, it can perform on various platforms namely Android, iOS, Linux, Windows, etc. So why not be the first ones to utilize Flutter and Flutter plugin?

What is Flutter plugin?

Plugin, as the name suggests, is a software component. It adds a specific feature to an existing program. For example, you may have heard of Adobe Flash Player, Java SE, Quicktime,… they all add a particular function. There are thousands of plugins for you to choose from.

So now, it’s easier to understand what Flutter Plugin is. Firstly, if you wanna check out all the plugins from Flutter, go to its official site pub.dev. Unless the ones you need are available, you won’t have to create new ones. If you do want to, we do provide useful and quick ways to upload on iOS and Android later in this article!

Why Plugins?

Additives surely make the food more appetizing and tasty. Likewise, plugins serve an additional but essential. Because Flutter still lacks support in Geolocation, payment SDK,… we need plugins to implement those functions in your sites or apps. How to create one, you ask?

Create Flutter plugin 

Firstly, check out if that plugin exists on Flutter or not. Then, let’s start creating if there aren’t the ones you are looking for. 

#1. Flutter Environment.

The 2 main parts are Flutter SDK and an editor (Android Studio or IntelliJ or Visual Studio) which must have Dart extensions.

Read more about Visual Studio vs Android Studio NOW!

android studio

As Flutter continuously updates, you need to know which version you are using. The latest is now 1.20.2 that was released August 2020. Now, run this command to see your current version: $ flutter doctor

Then, change to the beta Flutter channel with this command: $ flutter channel beta

(the overall command to change channels is flutter channel <channel-name>)

#2. Plugin Template

Generating templates will make the Flutter plugin easy to get started because you can put a particular language you want to use. As default, if you use Android, Flutter sets it to Kotlin. On the other hand, if you use iOS, Flutter sets it to Swift. 

To achieve the best result, we highly recommend Objective-C and Java by the command below:

$ flutter create --template=plugin --ios-language=objc --android-language=java PluginCodelab

Then, it appears the code structure. Here are some notable files you need to remember:

  • pubspec.yaml: defines your Flutter plugin (name, dependencies, version, supported operating systems, etc). It is used on the pub.dev page.
  • CHANGELOG.md: indicates changes in the new version. It is used when you want to publish new versions. 
  • README.md: describe the Flutter plugin – what it is and how to use it?
  • lib/PluginCodelab.dart: implements the plugin’s frontend 
  • example/lib/main.dart: is the Dart code that exercises your plugin where you build the example UI.
Implement features
Androidandroid/src/main/java/com/example/PluginCodelab/PluginCodelabPlugin.javaios/Classes/PluginCodelabPlugin.m
iOSios/Classes/PluginCodelabPlugin.m
flutter plugin code

#3. Platform-specific Code

Using platform-specific codes creates a sync combination between pressing keys and sounds. As usual, you may have a defined API to work from.

In this step, add these files:

  • For iOS: ios/Classes/FLRSynth.h and ios/Classes/FLRSynth.c
  • For Android: android/src/main/java/com/example/PluginCodelab/Synth.java

Again, to explain the key points in synthesizer interface:

  • keyUp() and keyDown(): represent musical keyboard
  • Key: represent which key is pressed or released

#4. Plugin API

The next step is to design the plugin API.  API’s purpose is to interact a component with a system, so this is an essential step. This is an example in the Dart code:

flutter plugin api
Plugin API
import 'dart:async';
import 'package:flutter/services.dart';
class PluginCodelab {
  static const MethodChannel _channel =
      const MethodChannel('PluginCodelab');
  static Future<String> get platformVersion async {
    final String version = await _channel.invokeMethod('getPlatformVersion');
    return version;
  }
 
  static Future<int> onKeyDown(int key) async {
    final int numNotesOn = await _channel.invokeMethod('onKeyDown', [key]);
    return numNotesOn;
  }
 
  static Future<int> onKeyUp(int key) async {
    final int numNotesOn = await _channel.invokeMethod('onKeyUp', [key]);
    return numNotesOn;
  }
}

#5. Plugin Platform Code

Firstly, you need to modify the plugin and start a synthesizer. Then, you handle messages in the channel. For iOS:

@implementation PluginCodelabPlugin {
  int _numKeysDown;
  FLRSynthRef _synth;
}
- (instancetype)init {
  self = [super init];
  if (self) {
    _synth = FLRSynthCreate();
    FLRSynthStart(_synth);
  }
  return self;
}
 
- (void)dealloc {
  FLRSynthDestroy(_synth);
}
- (void)handleMethodCall:(FlutterMethodCall *)call
                  result:(FlutterResult)result {
  if ([@"getPlatformVersion" isEqualToString:call.method]) {
    result([@"iOS "
        stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
  } else if ([@"onKeyDown" isEqualToString:call.method]) {
    FLRSynthKeyDown(_synth, [call.arguments[0] intValue]);
    _numKeysDown += 1;
    result(@(_numKeysDown));
  } else if ([@"onKeyUp" isEqualToString:call.method]) {
    FLRSynthKeyUp(_synth, [call.arguments[0] intValue]);
    
    _numKeysDown -= 1;
    result(@(_numKeysDown));
  } else {
    result(FlutterMethodNotImplemented);
  }
}

For Android:

android/src/main/java/com/example/PluginCodelab/PluginCodelabPlugin.java
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
  if (call.method.equals("getPlatformVersion")) {
    result.success("Android " + android.os.Build.VERSION.RELEASE);
  } else if (call.method.equals("onKeyDown")) {
    try {
      ArrayList arguments = (ArrayList) call.arguments;
      int numKeysDown = synth.keyDown((Integer) arguments.get(0));
      result.success(numKeysDown);
    } catch (Exception ex) {
      result.error("1", ex.getMessage(), ex.getStackTrace());
    }
  } else if (call.method.equals("onKeyUp")) {
    try {
      ArrayList arguments = (ArrayList) call.arguments;
      int numKeysDown = synth.keyUp((Integer) arguments.get(0));
      result.success(numKeysDown);
    } catch (Exception ex) {
      result.error("1", ex.getMessage(), ex.getStackTrace());
    }
  } else {
    result.notImplemented();
  }
}

That’s all the ‘middle’ steps you need to take. Lastly, test and publish the Flutter plugins.

Test & Publish 

Test plugins

Firstly, go to a main.dart file to check this default code:

import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:flutter_gallery_plugin/flutter_gallery_plugin.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
 @override
 _MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
 String _platformVersion = 'Unknown';
@override
 void initState() {
   super.initState();
   initPlatformState();
 }
// Platform messages are asynchronous, so we initialize in an async method.
 Future<void> initPlatformState() async {
   String platformVersion;
   // Platform messages may fail, so we use a try/catch PlatformException.
   try {
     platformVersion = await FlutterGalleryPlugin.platformVersion;
   } on PlatformException {
     platformVersion = 'Failed to get platform version.';
   }
// If the widget was removed from the tree while the asynchronous platform
   // message was in flight, we want to discard the reply rather than calling
   // setState to update our non-existent appearance.
   if (!mounted) return;
setState(() {
     _platformVersion = platformVersion;
   });
 }
@override
 Widget build(BuildContext context) {
   return MaterialApp(
     home: Scaffold(
       appBar: AppBar(
         title: const Text('Plugin example app'),
       ),
       body: Center(
         child: Text('Running on: $_platformVersion\n'),
       ),
     ),
   );
 }
}

Then, change the file according to your demand.

Publish plugins

Final part, run these commands to publish plugins:

flutter packages pub publish--dry-run

flutter packages pub publish

That’s all! If you are worried because of too many codes, don’t worry! You can always hire experts for help.

Need help creating Flutter plugins? Contact us NOW!

Founded in 2007, ArrowHiTech has been working in the IT outsourcing field for more than 12 years. With over 10,000 projects completed for thousands of clients, we are confident that our experience and skilled developers can solve any problems for you.

arrowhitech

ArrowHiTech guarantees the best solutions and services! Integrity is what makes us unique. Our ultimate goal is to deliver the best solutions to any customers in need. Furthermore, we always offer affordable prices but high quality products. You can check out our Flutter app development services as there are many more to see!

Final Words

So, today we have learned about Flutter Plugin and how to create it. We hope that you have seen lots of new ideas today to make big changes to your app! As always, AHT wishes you the best of good luck and success! For more questions, feel free to contact Contact Form

Tags

Share