插件是Flutter开发中不可获取的一部分,它能为Flutter提供一些原生平台的功能,比如最常用的shared_preferences,废话不多说直接开始看一下怎么封装自己所需要的插件功能。
Demo在这里
本地插件
直接在项目中使用的简单插件
iOS部分
Flutter项目创建后,ios
项目中会有一个GeneratedPluginRegistrant
类,你所导入的pub库中的插件都会在此注册,因为是我们自己项目中单独的Plugin,可以考虑照葫芦画瓢,创建一个CustomPluginRegistrant
的类,用于注册自己封装的插件。
AppDelegate
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
CustomPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
CustomPluginRegistrant
class CustomPluginRegistrant {
static func register(with registry: FlutterPluginRegistry) {
SimplePlugin.register(with: registry.registrar(forPlugin: "SimplePlugin")!)
}
}
SimplePlugin
open class SimplePlugin: NSObject, FlutterPlugin {
public static let shared = SimplePlugin()
private var channel: FlutterMethodChannel?
private override init() {}
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "flutter_simple_channel", binaryMessenger: registrar.messenger())
shared.channel = channel
registrar.addMethodCallDelegate(shared, channel: channel)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "method":
result(method())
case "methodWithAruguments":
result(method(with: call.arguments))
case "closureMethod":
closureMethod { result($0) }
default:
print("other")
}
}
/// method
private func method() -> String {
return "method result"
}
/// methodWithAruguments
private func method(with arguments: Any) -> String {
/// 原生调用flutter
channel?.invokeMethod("print", arguments: arguments, result: { result **in**
print(result)
})
return "method with arguments result"
}
/// closureMethod
private func closureMethod(_ callback: @escaping (String) -> Void) {
return callback("closure method result")
}
}
Flutter部分
class SimplePlugin {
late MethodChannel _channel = MethodChannel('flutter_simple_channel');
static SimplePlugin instance = SimplePlugin._();
SimplePlugin._() {
_channel.setMethodCallHandler((call) async {
print(call.method);
print(call.arguments);
});
}
Future<String> method() async {
return _channel.invokeMethod('method').then((value) => value);
}
Future<String> methodWithAruguments(String arg) {
return _channel
.invokeMethod('methodWithAruguments', arg)
.then((value) => value);
}
Future<String> closureMethod() {
return _channel.invokeMethod('closureMethod').then((value) => value);
}
}
调用
SimplePlugin.instance.method().then((value) {
print(value);
});
SimplePlugin.instance.methodWithAruguments('flutter arg').then((value) {
print(value);
});
SimplePlugin.instance.closureMethod().then((value) {
print(value);
});
pub 插件
团队需要封装公用组件,或者你想开源封装的组件的时候可以参考, 方便起见直接在上方Demo中创建plugin。可以查看创建后的项目,已经为我们提供了相应的模板,可以查看一下 基本和上方代码差不多。
/// 创建plugin的命令 这里只是创建了ios
flutter create --org com.example --template=plugin --platforms=ios -i swift easy_permission
/// 开始之前我们现在demo的pubspec.yaml中添加
easy_permission:
path: ../easy_permission
执行pub get后其实你已经可以在flutter端调用模板中的方法了。
EasyPermission().getPlatformVersion().then((value) => print(value));
iOS部分
如果你熟悉ios开发,easy_promission/ios 其实就是一个单独的cocoapods库,和我们之前开发三方库的逻辑是一样的,你也可以在其中引入其他的ios三方库, 这里我直接使用我自己的开源库来演示了。
/// 在easy_permission.podspec中修改
...
s.dependency 'Flutter'
s.dependency 'EasyKits/EasyPermission/EasyCamera'
s.platform = :ios, '10.0'
...
/// 在引入的工程中,此处是plugin_demo的ios的Info.plist中添加相机权限
<key> NSCameraUsageDescription </key>
<string> 我想用用相机 </string>
修改SwiftEasyPermissionPlugin
中的代码
建议这里最好都先实现了ios库,之后再引入,当然如果你的库功能很简单,就直接在此处实现即可。
public class SwiftEasyPermissionPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "easy_permission", binaryMessenger: registrar.messenger())
let instance = SwiftEasyPermissionPlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "cameraStatus":
Permission.camera.status { status in
result(status.value)
}
case "requestCamera":
Permission.camera.request { status in
result(status.value)
}
case "accessCamera":
Permission.camera.access { status in
result(status.value)
}
default:
result(PermissionStatus.notSupported.value)
}
}
}
extension PermissionStatus {
var value: String {
return "\(self)"
}
}
Flutter部分
只粘贴部分代码
class MethodChannelEasyPermission extends EasyPermissionPlatform {
/// The method channel used to interact with the native platform.
@visibleForTesting
final methodChannel = const MethodChannel('easy_permission');
/// 只是查看权限
@override
Future<EasyPermissionStatus> cameraStatus() async {
final status = await methodChannel.invokeMethod<String>('cameraStatus');
return permisionStatusMap[status] ?? EasyPermissionStatus.notSupported;
}
/// 直接申请权限
@override
Future<EasyPermissionStatus> requestCamera() async {
final status = await methodChannel.invokeMethod<String>('requestCamera');
return permisionStatusMap[status] ?? EasyPermissionStatus.notSupported;
}
/// 访问相机权限,没有权限会申请权限
@override
Future<EasyPermissionStatus> accessCamera() async {
final status = await methodChannel.invokeMethod<String>('accessCamera');
return permisionStatusMap[status] ?? EasyPermissionStatus.notSupported;
}
}
使用部分
EasyPermission().cameraStatus().then((value) => print(value));
EasyPermission().requestCamera().then((value) => print(value));
EasyPermission().accessCamera().then((value) => print(value));```
最后就是插件的发布,可以自行搜索。