在 Flutter 中使用特定于平台的包
Using Platform-Specific packages in Flutter
我不确定这是否是合适的堆栈交换站点,但我认为它比我能想到的其他站点更适合这里。无论如何,我在一个移动应用程序开发团队工作,我们正在考虑使用 Flutter 来开发我们未来的移动应用程序,因为它减少了为 iOS 和 Android 开发时所需的工作量(我们'我们只是一个小团队)。
我通读了一些关于 Flutter 的内容并检查了可用的包和 Dart/Flutter Pub 并且有一些包对于我们用于 Android 和 [= 的 Flutter 尚不可用34=]。以 MSAL(Microsoft 身份验证库)为例。阅读完文档后,我了解了平台通道以及如何 运行 一些 KT/Swift 等特定代码,并通过 Kotlin 中的 MethodChannel
之类的东西 return 它,但是示例来自 Flutter 文档的示例显示了仅 returning 特定数据类型或简单值的示例。如果我想使用 MSAL 对用户进行身份验证怎么办?这将涉及一些 UI 在 Flutter 中不会发生的工作,因为它依赖于浏览器或 webview(取决于您的 MSAL 配置)
我的问题可能主要有两点:
- 如果您有一个依赖于 iOS 或 Android 的 UI 的软件包,但不会占用您应用程序的全部功能,如何在仍然使用特定于平台的程序包的同时仍然使用 Flutter 来开发您的其余应用程序?
- 是否可以让超过 1 个 Activity 或 ViewController 执行此操作,然后再转到 Flutter 部分?因为我认为这是前一个问题的一种可能解决方案。
注:
我知道 Dart Pub 中有用于身份验证的包,但我只是以 MSAL 为例,我们还使用其他依赖于显示自定义视图来对用户进行身份验证的包。
我使用平台渠道让它工作。回答我的具体问题:
- 这个还是可以通过平台渠道处理的。例如,我将 MSAL 与 webview 一起使用,在对我的用户进行身份验证后,它仍然 returns 到原始
FlutterActivity
。
- 我对此不是 100% 确定,因为我自己没有创建
Activity
但该包能够打开自己的 webview,所以它应该可以工作
MainActivity
private val LOGIN_CHANNEL = "flutter.android/msal"
private val scopes = arrayOf("https://graph.microsoft.com/User.Read", "https://graph.microsoft.com/User.ReadBasic.All")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GeneratedPluginRegistrant.registerWith(this)
MyLibrary.setupClientApp(applicationContext, R.raw.auth_config, scopes)
MethodChannel(flutterView, LOGIN_CHANNEL).setMethodCallHandler { call, result ->
if (call.method == "login") {
login{
result.success(it)
}
}
}
}
private fun login(callback: (String?) -> Unit) {
MyLibrary.instance!!.acquireToken(
this,
scopes,
MyLibrary.getAuthInteractiveCallback {
callback(MyLibrary.getUser()?.displayName)
}
)
}
我的主页(州)
class _MyHomePageState extends State<MyHomePage> {
String _responseFromNativeCode = "";
static const platform = const MethodChannel('flutter.android/msal');
Future _login() async {
String response = "";
try {
response = await platform.invokeMethod('login');
} on PlatformException catch (e) {
response = "Failed to Invoke: '${e.message}'.";
}
setState(() {
_responseFromNativeCode = response;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'Hi $_responseFromNativeCode',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _login,
tooltip: 'Login',
child: Icon(Icons.lock),
),
);
}
}
我不确定这是否是合适的堆栈交换站点,但我认为它比我能想到的其他站点更适合这里。无论如何,我在一个移动应用程序开发团队工作,我们正在考虑使用 Flutter 来开发我们未来的移动应用程序,因为它减少了为 iOS 和 Android 开发时所需的工作量(我们'我们只是一个小团队)。
我通读了一些关于 Flutter 的内容并检查了可用的包和 Dart/Flutter Pub 并且有一些包对于我们用于 Android 和 [= 的 Flutter 尚不可用34=]。以 MSAL(Microsoft 身份验证库)为例。阅读完文档后,我了解了平台通道以及如何 运行 一些 KT/Swift 等特定代码,并通过 Kotlin 中的 MethodChannel
之类的东西 return 它,但是示例来自 Flutter 文档的示例显示了仅 returning 特定数据类型或简单值的示例。如果我想使用 MSAL 对用户进行身份验证怎么办?这将涉及一些 UI 在 Flutter 中不会发生的工作,因为它依赖于浏览器或 webview(取决于您的 MSAL 配置)
我的问题可能主要有两点:
- 如果您有一个依赖于 iOS 或 Android 的 UI 的软件包,但不会占用您应用程序的全部功能,如何在仍然使用特定于平台的程序包的同时仍然使用 Flutter 来开发您的其余应用程序?
- 是否可以让超过 1 个 Activity 或 ViewController 执行此操作,然后再转到 Flutter 部分?因为我认为这是前一个问题的一种可能解决方案。
注:
我知道 Dart Pub 中有用于身份验证的包,但我只是以 MSAL 为例,我们还使用其他依赖于显示自定义视图来对用户进行身份验证的包。
我使用平台渠道让它工作。回答我的具体问题:
- 这个还是可以通过平台渠道处理的。例如,我将 MSAL 与 webview 一起使用,在对我的用户进行身份验证后,它仍然 returns 到原始
FlutterActivity
。 - 我对此不是 100% 确定,因为我自己没有创建
Activity
但该包能够打开自己的 webview,所以它应该可以工作
MainActivity
private val LOGIN_CHANNEL = "flutter.android/msal"
private val scopes = arrayOf("https://graph.microsoft.com/User.Read", "https://graph.microsoft.com/User.ReadBasic.All")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GeneratedPluginRegistrant.registerWith(this)
MyLibrary.setupClientApp(applicationContext, R.raw.auth_config, scopes)
MethodChannel(flutterView, LOGIN_CHANNEL).setMethodCallHandler { call, result ->
if (call.method == "login") {
login{
result.success(it)
}
}
}
}
private fun login(callback: (String?) -> Unit) {
MyLibrary.instance!!.acquireToken(
this,
scopes,
MyLibrary.getAuthInteractiveCallback {
callback(MyLibrary.getUser()?.displayName)
}
)
}
我的主页(州)
class _MyHomePageState extends State<MyHomePage> {
String _responseFromNativeCode = "";
static const platform = const MethodChannel('flutter.android/msal');
Future _login() async {
String response = "";
try {
response = await platform.invokeMethod('login');
} on PlatformException catch (e) {
response = "Failed to Invoke: '${e.message}'.";
}
setState(() {
_responseFromNativeCode = response;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'Hi $_responseFromNativeCode',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _login,
tooltip: 'Login',
child: Icon(Icons.lock),
),
);
}
}