Flutter 如何在flatter/Dart中导入特定于平台的依赖项?(将Web与Android/iOS结合使用)
我在iOS和Android的Flitter应用程序中使用了Flutter 如何在flatter/Dart中导入特定于平台的依赖项?(将Web与Android/iOS结合使用),flutter,dart,flutter-web,Flutter,Dart,Flutter Web,我在iOS和Android的Flitter应用程序中使用了共享_首选项。在web上,我使用的是http:dart依赖项(window.localStorage)本身。由于Flatter for web被合并到Flatter repo中,我想创建一个跨平台的解决方案 这意味着我需要导入两个独立的API。这在Dart中似乎还没有得到很好的支持,但我就是这么做的: import 'package:some_project/stub/preference_utils_stub.dart' if
共享_首选项。在web上,我使用的是http:dart
依赖项(window.localStorage
)本身。由于Flatter for web被合并到Flatter repo中,我想创建一个跨平台的解决方案
这意味着我需要导入两个独立的API。这在Dart中似乎还没有得到很好的支持,但我就是这么做的:
import 'package:some_project/stub/preference_utils_stub.dart'
if (dart.library.html) 'dart:html'
if (dart.library.io) 'package:shared_preferences/shared_preferences.dart';
在我的preference\u utils\u stub.dart
文件中,我实现了编译时需要可见的所有类/变量:
Window window;
class SharedPreferences {
static Future<SharedPreferences> get getInstance async {}
setString(String key, String value) {}
getString(String key) {}
}
class Window {
Map<String, String> localStorage;
}
窗口;
类共享引用{
静态未来获取getInstance异步{}
setString(字符串键,字符串值){}
getString(字符串键){}
}
类窗口{
地图本地存储;
}
这将在编译之前消除所有错误。现在,我实现了一些方法来检查应用程序是否正在使用web:
static Future<String> getString(String key) async {
if (kIsWeb) {
return window.localStorage[key];
}
SharedPreferences preferences = await SharedPreferences.getInstance;
return preferences.getString(key);
}
static Future getString(字符串键)异步{
如果(kIsWeb){
返回窗口。localStorage[key];
}
SharedReferences首选项=等待SharedReferences.getInstance;
返回preferences.getString(键);
}
但是,这会产生大量错误:
lib/utils/preference_utils.dart:13:7: Error: Getter not found:
'window'.
window.localStorage[key] = value;
^^^^^^ lib/utils/preference_utils.dart:15:39: Error: A value of type 'Future<SharedPreferences> Function()' can't be assigned to a
variable of type 'SharedPreferences'.
- 'Future' is from 'dart:async'.
- 'SharedPreferences' is from 'package:shared_preferences/shared_preferences.dart'
('../../flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.4+3/lib/shared_preferences.dart').
SharedPreferences preferences = await SharedPreferences.getInstance;
^ lib/utils/preference_utils.dart:22:14: Error: Getter not found:
'window'.
return window.localStorage[key];
lib/utils/preference\u utils.dart:13:7:错误:找不到Getter:
“窗口”。
window.localStorage[key]=值;
^^^^^^lib/utils/preference_utils.dart:15:39:错误:无法将“Future Function()”类型的值分配给
类型为“SharedReferences”的变量。
-“Future”来自“dart:async”。
-“SharedPreferences”来自“package:shared_preferences/shared_preferences.dart”
(“../../flatter/.pub cache/hosted/pub.dartlang.org/shared_preferences-0.5.4+3/lib/shared_preferences.dart”)。
SharedReferences首选项=等待SharedReferences.getInstance;
^lib/utils/preference_utils.dart:22:14:错误:找不到Getter:
“窗口”。
返回窗口。localStorage[key];
等等。如何根据平台使用不同的方法/类而不出现这些错误?请注意,我以这种方式使用了更多的依赖项,而不仅仅是首选项。谢谢 以下是我对你的问题的看法。这是基于http
包中的实现,如中所示
其核心思想如下
创建一个抽象类来定义需要使用的方法
创建特定于扩展此抽象类的web
和android
依赖项的实现
创建一个存根,该存根公开一个方法来返回此抽象实现的实例。这只是为了让dart分析工具满意
在抽象类中,将此存根文件与特定于mobile
和web
的条件导入一起导入。然后在其工厂构造函数中返回特定实现的实例。如果写入正确,这将由条件导入自动处理
第1步和第4步:
import'key\u finder\u stub.dart'
//忽略:uri不存在
if(dart.library.io)'package:flatter\u conditional\u dependencies\u example/storage/shared\u pref\u key\u finder.dart'
//忽略:uri不存在
if(dart.library.html)'package:flatter\u conditional\u dependencies\u example/storage/web\u key\u finder.dart';
抽象类密钥查找器{
//要公开的一些通用方法。
///返回基于键的值
字符串getKeyValue(字符串键){
返回“我来自接口”;
}
///将键值对存储在相应的存储器中。
void setKeyValue(字符串键,字符串值){}
///工厂构造函数返回正确的实现。
factory KeyFinder()=>getKeyFinder();
}
步骤2.1:Web密钥查找器
导入'dart:html';
导入“package:flatter\u conditional\u dependencies\u example/storage/key\u finder\u interface.dart”;
窗口位置;
类WebKeyFinder实现KeyFinder{
WebKeyFinder(){
windowLoc=窗口;
打印(“Widnow已初始化”);
//最初存储某些内容只是为了确保其正常工作。:)
windowLoc.localStorage[“MyKey”]=“我来自web本地存储”;
}
字符串getKeyValue(字符串键){
返回windowLoc.localStorage[key];
}
void setKeyValue(字符串键,字符串值){
windowLoc.localStorage[key]=值;
}
}
KeyFinder getKeyFinder()=>WebKeyFinder();
步骤2.2:移动密钥查找器
import'package:flatter\u conditional\u dependencies\u example/storage/key\u finder\u interface.dart';
导入“package:shared_preferences/shared_preferences.dart”;
类SharedPrefKeyFinder实现KeyFinder{
SharedReferences\u实例;
SharedPrefKeyFinder(){
SharedReferences.getInstance()。然后((SharedReferences实例){
_实例=实例;
//只是初始化一些东西以便可以获取它。
_setString(“MyKey”,“我来自共享偏好”);
});
}
字符串getKeyValue(字符串键){
返回_实例?.getString(键)??
'共享首选项尚未初始化';
}
void setKeyValue(字符串键,字符串值){
_实例?.setString(键、值);
}
}
KeyFinder getKeyFinder()=>SharedPrefKeyFinder();
第三步:
导入“key\u finder\u interface.dart”;
KeyFinder getKeyFinder()=>抛出不支持错误(
'如果没有包dart:html或包:shared_首选项',则无法创建keyfinder';
然后在main.dart
中使用KeyFinder
抽象类,就好像它是一个通用实现一样。这有点像适配器模式
main.dart
导入“包装:颤振/材料.省道”;
导入“package:flatter\u conditional\u dependencies\u example/storage/key\u finder\u interface.dart”;
void main()=>runApp(MyApp());
类MyApp扩展了无状态小部件{
//这个wi