I'm creating a new Flutter plugin
I named it my_flutter_plugin when I created it. But now I want to change the main class name.
Currently it is this:
// lib/my_flutter_plugin.dart
import 'dart:async';
import 'package:flutter/services.dart';
class MyFlutterPlugin {
static const MethodChannel _channel =
const MethodChannel('my_flutter_plugin');
static Future<String> get platformVersion async {
final String version = await _channel.invokeMethod('getPlatformVersion');
return version;
}
}
I'd like to change MyFlutterPlugin to AnotherName, but when I look in pubspec.dart it says:
# The following section is specific to Flutter.
flutter:
# This section identifies this Flutter project as a plugin project.
# The androidPackage and pluginClass identifiers should not ordinarily
# be modified. They are used by the tooling to maintain consistency when
# adding or updating assets for this project.
plugin:
androidPackage: com.example.my_flutter_plugin
pluginClass: MyFlutterPlugin
I want to keep the package name as my_flutter_plugin but this seems to indicate that I can't (or shouldn't) change the plugin class name.
How do I change the class name?
The pluginClass in pubspec.yaml is not the same as your class with the method channel. In fact, if you had named your project my_flutter instead of my_flutter_plugin, the pluginClass in pubspec.yaml would still say myFlutterPlugin but your lib class with the method channel would be MyFlutter.
How to change the class name
In your lib folder class (in this case lib/my_flutter_plugin.dart), just refactor the class name as you would normally rename any class. You can rename it to AnotherName. As long as you are refactoring using the IDE tools, this should also update the class name in the example and test folders.
How to change the method channel name
Just change the string name everywhere that it is used. In a new plugin project, this would be in the lib folder and the test folder. Rather than
static const MethodChannel _channel =
const MethodChannel('my_flutter_plugin');
You can give it a unique name like
static const MethodChannel _channel =
const MethodChannel('com.example.my_flutter_plugin/another_name');
Related
I am trying logging library in my flutter project. They have some good record messages (e.g. record.name, record.message, etc.) For my project, I want to extend by using dart extension methods this package to add some more record message (e.g. record.version, record.eventName, etc.). As a beginner in dart, I am not sure completely how to do that?
Here is an example that I tried but failed.
extension CustomLog on LogRecord {
String version(LogRecord version) => "1.0";
String eventName(LogRecord eventName) => "userNameChangedEvent";
}
Please provide me some suggestions/examples how can I extend any package and use it on my own.
Logging does not support extending (with extension) the LogRecord to add custom fields.
You can pass all your custom info as an class object in object param and retrieve it later.
Something like
class CustomLogAttributes {
final String version;
final String eventName;
CustomLogAttributes(this.version, this.eventName);
}
then
log.fine("example log message", object: CustomLogAttributes("1.1.0", "example_event");
I am trying to set up different firebase environments(for example :qa,prod) in a flutter project.
I created two projects in firebase, one for production, one for the qa. Then, in an iOS or Android project, I using separate google-services.json or GoogleServices-Info.plist files.
but,how to do it in Flutter web?
If you need this dynamic config in dart code, you can create an interface that represents your configs and create implementations for each environment, so you can change the implementation passing a parameter when run flutter app (using --dart-define).
Imagine the case that you have a prod and an homolog environment, you can create three files:
The first one is the contract of your configs, that all environments must have implemented.
abstract class AppConfig {
String get baseUrl;
}
And we create a class for each environment, with the implementation of the configs defined in AppConfig.
class ProdConfig implements AppConfig {
#override
String get baseUrl => 'https://my-prod-url.com';
}
class HomologConfig implements AppConfig {
#override
String get baseUrl => 'https://my-homolog-url.com';
}
When we need to get the config class, we instantiate based on parameter passed by --dart-define
AppConfig getConfig() {
const environmentParameter = String.fromEnvironment('ENV');
switch (environmentParameter) {
case 'prod': return ProdConfig();
case 'homolog': return HomologConfig();
default: throw Error(); // You can set a default environment
}
}
And when you run your app, you just need to pass this parameter, like the example below:
flutter run --dart-define ENV=prod
Or in homolog:
flutter run --dart-define ENV=homolog
BUT, if you need to set configs like firebase, you should check this answer
I have decided to use Isar database in my next project and I find it much helpful when dealing with local data.
I followed the quickstart guide in its website. I added dependencies. Annotated the contact class. Ran code generator. But at fourth step, I have problem creating schema while creating Isar instance.
initIsar() async {
final dir = await getApplicationSupportDirectory();
final isar = await Isar.open(
schemas: [ContactSchema],
directory: dir.path,
inspector: true,
);
}
The problem is where I typed ContactSchema, it says
Undefined name 'ContactSchema'.
Try correcting the name to one that is defined, or defining the name.
So question I have to ask is, I followed guide but I'm unable to create a schema. How can I create one to make Isar db work?
UPDATE:
import 'package:isar/isar.dart';
part 'contact.g.dart';
#Collection()
class Contact {
#Id()
int? id;
late String name;
}
After adding part 'contact.g.dart', type this command flutter pub run build_runner build and you are good to go.
For completeness of response:
Run (error? look at it, it likely say to remove isar from the first command)
flutter pub add isar isar_flutter_libs
flutter pub add -d isar_generator build_runner
flutter pub run build_runner build # Run every update of the collection
Example collection:
#Collection(accessor: "time")
class Timer {
final Id id = Isar.autoIncrement;
#Index(
unique: true,
replace: true,
)
late final bool isRunning;
late final DateTime dates = DateTime.now();
}
Suggestion: (tree -x output)
$ tree -x
.
├── main.dart
└── model
├── timer.dart
└── timer.g.dart
1 directory, 3 files
For how I'm using this:
void main() async {
// ignore: unused_local_variable
final isar = await Isar.open([TimerSchema]);
runApp(const MyApp());
}
Look at my timer app for help: pranitshah.cyou
I'll update my website for this.
After you run the build_runner command the schema class is generated in the MODEL_NAME.g.dart file. you need to import that file to get access to the schema class.
Hello Zahid If you want to add local db in your next flutter app there are various packgaes on https://pub.dev.
I would highly recomend you to go start with https://pub.dev/packages/floor it is easy to learn light weight to use..
Try this you would loved it.. and how to implement you can google it and here is a tutorial for how to use Floor in your flutter Mobile App.
https://www.youtube.com/watch?v=cQ7W7vpwTbk&t=1055s
I have a project which uses flutter_libserialport library on macOS.
I am modifying it to work on web however this library does not work on web.
I am building a web implementation using navigator.serial in javascript which works fine.
However when I attempt to build the project for web I get the following error
/opt/homebrew/Caskroom/flutter/2.2.3/flutter/.pub-cache/hosted/pub.dartlang.org/libserialport-0.2.0+3/lib/src/config.dart:25:8: Error: Not found: 'dart:ffi'
import 'dart:ffi' as ffi;
This makes sense since FFI is not available on web.
But I don't even need the libserialport library on web any way.
How can I get flutter to ignore it?
I tried this however it doesn't contain information on how to exclude a package.
It also does not contain information on how to ignore it specifically for web. It seems to just ignore it in general.
Maybe you should guard your usages of libserialport with the kIsWeb predicate like following:
if(!kIsWeb){
// libserialport code execution here
}
I searched a lot as well and didn't find a way you can do that, I think this should be handled by the package itself not the package's users like in path_provider for instance.
As a workaround I have created a dummy libserialport's SerialPort class for web only as follows:
dummy_serialport.dart:
class SerialPort {
final String name;
static List<String> availablePorts = ['dummy'];
static SerialPortError? lastError;
SerialPort(this.name);
bool openReadWrite() {
return false;
}
}
class SerialPortError {}
// add more properties and functions as needed
main.dart:
import 'package:libserialport/libserialport.dart'
if (dart.library.html) './dummy_serialport.dart'
if (dart.library.io) 'package:libserialport/libserialport.dart';
....
if (!kIsWeb) {
final name = SerialPort.availablePorts.first;
final port = SerialPort(name);
if (!port.openReadWrite()) {
print(SerialPort.lastError);
exit(-1);
}
}
....
....
It's bad, I know :( but it works! maybe you can contact the package author to get more insight and if opening a PR where the interfaces are separated from the FFI implementation so that importing the classes wouldn't break web or something.
I want to write an eclipse plugin to show the actual value of the message code. The values are to be loaded from the given resource bundle. Only classes of the resource bundle will be available. So I require to load the resource bundle class which is declared in the current file. These class files will be in the classes folder or in a jar file in the lib folder. Is there any way to load the classes dynamically from the eclipse plugin? Thanks in advance
An Example how to get a externalized string from a message.properties file
private static final String BUNDLE_NAME = "de.stackoverflow.package.messages"; //$NON-NLS-1$
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
RESOURCE_BUNDLE.getString(key);
Every plugin does have a bundle object where you can load the files of a plugin. The Bundle object should contain every information you want to use.
Have a look at the Bundle class. There is the following method:
public Class loadClass(String name) throws ClassNotFoundException;
To get the bundle from your plugin:
Activator.getDefault().getBundle()
Hope this help
Manu