Sco*_*nts 6 ios dart swift flutter
我看过很多关于这个主题的类似问题,但没有一个解决方案对我有用。我正在 Flutter 中开发一个应用程序,但想从本机 iOS 项目中调用我的main.dart文件中的特定方法。AppDelegate.swift
为了删除所有其他变量,我已将问题提取到一个新的 dart 项目中。我试图setChannelText()从AppDelegate.swiftusing 中调用methodChannel.invokeMethod(),但没有成功。
有人知道我哪里出错了吗?我知道我没有对 中的“名称”参数进行操作methodChannel.invokeMethod(),但那是因为我只想调用该方法......
这是我的 main.dart 文件:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
MethodChannel channel =
new MethodChannel("com.example.channeltest/changetext");
String centerText;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.purple,
body: Center(
child: Text(
centerText,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 30.0,
),
),
),
),
);
}
@override
void initState() {
super.initState();
this.channel.setMethodCallHandler((call) async => await setChannelText());
this.centerText = "Hello World!";
}
Future setChannelText() async {
Future.delayed(Duration(milliseconds: 200));
setState(() => this.centerText = "Another Text.");
}
}Run Code Online (Sandbox Code Playgroud)
这是我的 AppDelegate.swift 文件:
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
var methodChannel: FlutterMethodChannel!
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions:
[UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let rootViewController : FlutterViewController = window?.rootViewController as! FlutterViewController
methodChannel = FlutterMethodChannel(name: "com.example.channeltest/changetext", binaryMessenger: rootViewController as! FlutterBinaryMessenger)
//This call would obviously be somewhere else in a real world example, but I'm just
//testing if I can invoke the method in my dart code at all..
methodChannel.invokeMethod("some_method_name", arguments: nil)
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}Run Code Online (Sandbox Code Playgroud)
最后,我试图让文本在启动后立即更改,但事实并非如此。
预先感谢您的任何帮助!
问题是您的平台端(在本例中为 iOS)在Flutter 准备好之前调用 Flutter 端的方法。没有办法从平台端检查,所以你的Flutter 应用程序必须告诉你的平台端。在 Android 上你也会遇到同样的问题。
为了克服这个问题,您必须告诉平台端应用程序已准备就绪(通过发送平台方法)并将其保存在布尔值中,或者实例化一个类并调用一个方法。然后平台方就可以开始发送消息了。
您应该真正阅读日志,它应该警告您以下内容:“没有任何内容在监听此内容,或者未连接 Flutter 引擎”。
import 'dart:async';
import 'package:flutter/src/services/platform_channel.dart';
class StringService {
final methodChannel =
const MethodChannel("com.example.app_name.method_channel.strings");
final StreamController<String> _stringStreamController =
StreamController<String>();
Stream<String> get stringStream => _stringStreamController.stream;
StringService() {
// Set method call handler before telling platform side we are ready to receive.
methodChannel.setMethodCallHandler((call) async {
print('Just received ${call.method} from platform');
if (call.method == "new_string") {
_stringStreamController.add(call.arguments as String);
} else {
print("Method not implemented: ${call.method}");
}
});
// Tell platform side we are ready!
methodChannel.invokeMethod("isReady");
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在reverse_platform_methods看到一个工作项目,特别是AppDelegate.swift. 我没有在 Android 上实现它,但你可以在MainActivity.kt.
大多数应用程序不希望代码首先从平台端调用。您的用例是什么?根据您的回答,我可能会提供更好的建议。我实现这个是为了处理发送到设备的推送通知,因此“事件”肯定是从平台端触发的。
另外,如果遇到错误和警告,您应该显示它们,例如No implementation found for method $method on channel $name'。
Roh*_*Das -3
颤振端代码:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class _MyHomePageState extends State<MyHomePage> {
static const platform = MethodChannel('samples.flutter.dev/battery');
// Get battery level.
String _batteryLevel = 'Unknown battery level.';
Future<void> _getBatteryLevel() async {
String batteryLevel;
try {
final int result = await platform.invokeMethod('getBatteryLevel');
batteryLevel = 'Battery level at $result % .';
} on PlatformException catch (e) {
batteryLevel = "Failed to get battery level: '${e.message}'.";
}
setState(() {
_batteryLevel = batteryLevel;
});
}
@override
Widget build(BuildContext context) {
return Material(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
child: Text('Get Battery Level'),
onPressed: _getBatteryLevel,
),
Text(_batteryLevel),
],
),
),
);
}
}Run Code Online (Sandbox Code Playgroud)
快速代码在这里:
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let batteryChannel = FlutterMethodChannel(name: "samples.flutter.dev/battery",
binaryMessenger: controller.binaryMessenger)
batteryChannel.setMethodCallHandler({
[weak self] (call: FlutterMethodCall, result: FlutterResult) -> Void in
// Note: this method is invoked on the UI thread.
guard call.method == "getBatteryLevel" else {
result(FlutterMethodNotImplemented)
return
}
self?.receiveBatteryLevel(result: result)
})
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}Run Code Online (Sandbox Code Playgroud)
或者参考这个链接: