gpt4 book ai didi

flutter - 如何在 Flutter/Dart 中导入特定于平台的依赖项? (结合网络与Android/iOS)

转载 作者:行者123 更新时间:2023-12-03 02:38:42 26 4
gpt4 key购买 nike

我正在使用 shared_preferences在我的适用于 iOS 和 Android 的 Flutter 应用程序中。在网络上,我使用的是 http:dart依赖 ( window.localStorage ) 本身。由于 Flutter for web 被合并到 Flutter 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_utils_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;
}


这在编译之前消除了所有错误。现在我实现了一些检查应用程序是否正在使用网络的方法:
static Future<String> getString(String key) async {
if (kIsWeb) {
return window.localStorage[key];
}
SharedPreferences preferences = await SharedPreferences.getInstance;
return preferences.getString(key);
}

但是,这会产生大量错误:
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];

等等。如何在没有这些错误的情况下根据平台使用不同的方法/类?请注意,我以这种方式使用了更多依赖项,而不仅仅是首选项。谢谢!

最佳答案

这是我对您的问题的处理方法。这是基于 http 的实现包装如 here .

核心思想如下。

  • 创建一个抽象类来定义您需要使用的方法。
  • 创建特定于 web 的实现和 android扩展此抽象类的依赖项。
  • 创建一个 stub ,它公开一个方法来返回这个抽象实现的实例。这只是为了让 dart 分析工具满意。
  • 在抽象类中导入此 stub 文件以及特定于 mobile 的条件导入。和 web .然后在其工厂构造函数中返回具体实现的实例。如果写入正确,这将通过条件导入自动处理。

  • 第 1 步和第 4 步:

    import 'key_finder_stub.dart'
    // ignore: uri_does_not_exist
    if (dart.library.io) 'package:flutter_conditional_dependencies_example/storage/shared_pref_key_finder.dart'
    // ignore: uri_does_not_exist
    if (dart.library.html) 'package:flutter_conditional_dependencies_example/storage/web_key_finder.dart';

    abstract class KeyFinder {

    // some generic methods to be exposed.

    /// returns a value based on the key
    String getKeyValue(String key) {
    return "I am from the interface";
    }

    /// stores a key value pair in the respective storage.
    void setKeyValue(String key, String value) {}

    /// factory constructor to return the correct implementation.
    factory KeyFinder() => getKeyFinder();
    }

    步骤 2.1:Web key 查找器

    import 'dart:html';

    import 'package:flutter_conditional_dependencies_example/storage/key_finder_interface.dart';

    Window windowLoc;

    class WebKeyFinder implements KeyFinder {

    WebKeyFinder() {
    windowLoc = window;
    print("Widnow is initialized");
    // storing something initially just to make sure it works. :)
    windowLoc.localStorage["MyKey"] = "I am from web local storage";
    }

    String getKeyValue(String key) {
    return windowLoc.localStorage[key];
    }

    void setKeyValue(String key, String value) {
    windowLoc.localStorage[key] = value;
    }
    }

    KeyFinder getKeyFinder() => WebKeyFinder();

    步骤 2.2:移动 key 查找器

    import 'package:flutter_conditional_dependencies_example/storage/key_finder_interface.dart';
    import 'package:shared_preferences/shared_preferences.dart';

    class SharedPrefKeyFinder implements KeyFinder {
    SharedPreferences _instance;

    SharedPrefKeyFinder() {
    SharedPreferences.getInstance().then((SharedPreferences instance) {
    _instance = instance;
    // Just initializing something so that it can be fetched.
    _instance.setString("MyKey", "I am from Shared Preference");
    });
    }

    String getKeyValue(String key) {
    return _instance?.getString(key) ??
    'shared preference is not yet initialized';
    }

    void setKeyValue(String key, String value) {
    _instance?.setString(key, value);
    }

    }

    KeyFinder getKeyFinder() => SharedPrefKeyFinder();

    第 3 步:

    import 'key_finder_interface.dart';

    KeyFinder getKeyFinder() => throw UnsupportedError(
    'Cannot create a keyfinder without the packages dart:html or package:shared_preferences');

    然后在您的 main.dart使用 KeyFinder抽象类就好像它是一个通用实现一样。这有点像 适配器模式 .

    main.dart

    import 'package:flutter/material.dart';
    import 'package:flutter_conditional_dependencies_example/storage/key_finder_interface.dart';

    void main() => runApp(MyApp());

    class MyApp extends StatelessWidget {
    // This widget is the root of your application.
    @override
    Widget build(BuildContext context) {
    KeyFinder keyFinder = KeyFinder();
    return MaterialApp(
    title: 'Flutter Demo',
    theme: ThemeData(
    primarySwatch: Colors.blue,
    ),
    home: SafeArea(
    child: KeyValueWidget(
    keyFinder: keyFinder,
    ),
    ),
    );
    }
    }

    class KeyValueWidget extends StatefulWidget {
    final KeyFinder keyFinder;

    KeyValueWidget({this.keyFinder});
    @override
    _KeyValueWidgetState createState() => _KeyValueWidgetState();
    }

    class _KeyValueWidgetState extends State<KeyValueWidget> {
    String key = "MyKey";
    TextEditingController _keyTextController = TextEditingController();
    TextEditingController _valueTextController = TextEditingController();
    @override
    Widget build(BuildContext context) {
    return Material(
    child: Container(
    width: 200.0,
    child: Column(
    children: <Widget>[
    Expanded(
    child: Text(
    '$key / ${widget.keyFinder.getKeyValue(key)}',
    style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
    ),
    ),
    Expanded(
    child: TextFormField(
    decoration: InputDecoration(
    labelText: "Key",
    border: OutlineInputBorder(),
    ),
    controller: _keyTextController,
    ),
    ),
    Expanded(
    child: TextFormField(
    decoration: InputDecoration(
    labelText: "Value",
    border: OutlineInputBorder(),
    ),
    controller: _valueTextController,
    ),
    ),
    RaisedButton(
    child: Text('Save new Key/Value Pair'),
    onPressed: () {
    widget.keyFinder.setKeyValue(
    _keyTextController.text,
    _valueTextController.text,
    );
    setState(() {
    key = _keyTextController.text;
    });
    },
    )
    ],
    ),
    ),
    );
    }
    }


    一些屏幕截图

    网站
    enter image description here
    enter image description here

    手机
    enter image description here

    关于flutter - 如何在 Flutter/Dart 中导入特定于平台的依赖项? (结合网络与Android/iOS),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58710226/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com