简体   繁体   English

如何实现使用flutter_secure_storage包读写数据的流程【with Provider包】

[英]How to implement a process that uses flutter_secure_storage package to read and write the data [with Provider package]

I'm new to Flutter and Dart.我是 Flutter 和 Dart 的新手。 I made a simple Todos app with Provider package and Consumer.我使用 Provider 包和 Consumer 制作了一个简单的 Todos 应用程序。 I'm trying to implement a process that uses flutter_secure_storage package to read and write the list data on the device.我正在尝试实现一个过程,该过程使用 flutter_secure_storage 包在设备上读取和写入列表数据。 But I don't know how to implement it.但我不知道如何实现它。

Checkbox widget requires a bool, while secure_storage requires the type of String.复选框小部件需要一个 bool,而 secure_storage 需要 String 类型。 Therefore, it is necessary to convert both types.因此,有必要对这两种类型进行转换。 This also confuses me a little.这也让我有点困惑。

The code is below.代码如下。 I would be happy if you could give me some advice.如果你能给我一些建议,我会很高兴。

main.dart main.dart

// Todos app example

import 'package:consumer_samp/list_model.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: ChangeNotifierProvider<ListModel>(
        create: (context) => ListModel(),
        child: MyHomePage('Todos app example'),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage(this.title);

  final String title;

  final TextEditingController eCtrl = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[
            Container(
              padding: EdgeInsets.all(10),
              child: Row(
                children: <Widget>[
                  Expanded(
                    child: TextField(
                      decoration: InputDecoration(
                        border: InputBorder.none,
                        hintText: 'Enter your ToDo item',
                      ),
                      controller: eCtrl,
                    ),
                  ),
                  Consumer<ListModel>(
                    builder: (_, listModel, __) => FlatButton(
                      child: Text('Add'),
                      onPressed: () {
                        if (eCtrl.text != '') {
                          Map<String, dynamic> item = {
                            'value': false,
                            'text': eCtrl.text
                          };
                          listModel.addItem(item);
                          eCtrl.clear();
                        }
                      },
                    ),
                  ),
                ],
              ),
            ),
            Center(
              child: Consumer<ListModel>(builder: (_, listModel, __) {
                var items = listModel.getItems;
                return Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Container(
                      height: 300,
                      child: ListView.builder(
                        itemCount: items.length,
                        itemBuilder: (BuildContext context, int idx) =>
                            Container(
                          padding: const EdgeInsets.all(5),
                          color: Colors.green,
                          child: Row(
                            children: <Widget>[
                              Checkbox(
                                  value: items[idx]['value'],
                                  onChanged: (val) {
                                    listModel.toggleValue(idx, val);
                                  }),
                              Text(
                                items[idx]['text'],
                                style: TextStyle(
                                    fontSize: 21, color: Colors.white),
                              ),
                            ],
                          ),
                        ),
                      ),
                    ),
                  ],
                );
              }),
            ),
          ],
        ),
      ),
    );
  }
}

list_model.dart list_model.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

class ListModel with ChangeNotifier {
  List<Map<String, dynamic>> _items = [];

  List<Map<String, dynamic>> get getItems => _items;

  void addItem(Map<String, dynamic> item) {
    _items.add(item);
    notifyListeners();
  }

  void toggleValue(int idx, bool val) {
    _items[idx]['value'] = val;
    notifyListeners();
  }
}

As mentioned in the readme files by the following link如以下链接的自述文件中所述

https://pub.dev/packages/flutter_secure_storage https://pub.dev/packages/flutter_secure_storage

The following code instantiate the storage, and the following code's must be in a async method as this returns a future.以下代码实例化存储,并且以下代码必须在async方法中,因为它返回未来。

final storage = new FlutterSecureStorage();

And you can pass the _items list as a value and you can set some key name您可以将_items列表作为值传递,您可以设置一些键名

await storage.write(key: key, value: _items);

And then you could get that value by using the key name (which is set while storing)然后您可以通过使用键名(在存储时设置)来获取该值

List<Map<String, dynamic>> _value = await storage.read(key: key);

And then you could map the _value you get from storage and you can store it in _items .然后您可以映射从存储中获得的_value并将其存储在_items And then you could do various operations and queries inside your app now with all data you have.然后,您现在可以使用您拥有的所有数据在您的应用程序中执行各种操作和查询。

Make a note!记录下来! I haven't tried this approach in my code base.我还没有在我的代码库中尝试过这种方法。 Just I said what I thought.我只是说出了我的想法。 Please try this in your code and comment me please.请在您的代码中尝试此操作并请评论我。

The following code executes correctly use this in model, for storing data:以下代码在模型中正确执行,用于存储数据:

Future<void> _storingData() async {
    final storage = new FlutterSecureStorage();

    for (int i = 0; i < _items.length; i++) {
        await storage
              .write(key: _items[i]['text'], value: "${_items[i]['value']}")
              .then((value) => print("success"));
    }
}

For retrieving data:用于检索数据:

Future<void> retrivingData() async {
    final storage = new FlutterSecureStorage();
    Map<String, String> allValues = await storage.readAll();

    print(allValues);

    allValues.forEach((key, value) {
        bool val = bool.fromEnvironment(value, defaultValue: false);
        Map<String, dynamic> item = {'value': val, 'text': key};
        addItem(item);
    });
}

and finally I stored all values again to a list.最后我再次将所有值存储到列表中。

You should do some changes in your code in main.dart according to the above methods based on your usage.您应该根据您的使用情况,按照上述方法对main.dart中的代码进行一些更改。

You can copy paste run full code below您可以在下面复制粘贴运行完整代码
You can use class TodoItem and save/load with JSON String您可以使用类TodoItem并使用 JSON 字符串保存/加载
Provider logic for secure storage is in full code, too long to describe detail安全存储的Provider逻辑是完整的代码,太长无法描述细节
code snippet代码片段

List<TodoItem> todoItemFromJson(String str) =>
    List<TodoItem>.from(json.decode(str).map((x) => TodoItem.fromJson(x)));

String todoItemToJson(List<TodoItem> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class TodoItem {
  TodoItem({
    this.item,
    this.checked,
  });

  String item;
  bool checked;

  factory TodoItem.fromJson(Map<String, dynamic> json) => TodoItem(
        item: json["item"],
        checked: json["checked"],
      );

  Map<String, dynamic> toJson() => {
        "item": item,
        "checked": checked,
      };
}

working demo工作演示

在此处输入图片说明

full code完整代码

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

import 'dart:convert';

List<TodoItem> todoItemFromJson(String str) =>
    List<TodoItem>.from(json.decode(str).map((x) => TodoItem.fromJson(x)));

String todoItemToJson(List<TodoItem> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class TodoItem {
  TodoItem({
    this.item,
    this.checked,
  });

  String item;
  bool checked;

  factory TodoItem.fromJson(Map<String, dynamic> json) => TodoItem(
        item: json["item"],
        checked: json["checked"],
      );

  Map<String, dynamic> toJson() => {
        "item": item,
        "checked": checked,
      };
}

class ListModel with ChangeNotifier {
  FlutterSecureStorage _storage;

  List<TodoItem> _items = [];

  List<TodoItem> get getItems => _items;

  initilaize() async {
    print("initialize");
    String jsonString = await _storage.read(key: "todo");
    if (jsonString != null) {
      _items = todoItemFromJson(jsonString);
      notifyListeners();
    }
  }

  ListModel.init(FlutterSecureStorage storage) {
    print("init");
    _storage = storage;
    initilaize();
  }

  void update(FlutterSecureStorage storage) {
    print("update");
    _storage = storage;
  }

  void addItem(TodoItem item) {
    _items.add(item);
    notifyListeners();
  }

  void toggleValue(int idx, bool val) {
    _items[idx].checked = val;
    notifyListeners();
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MultiProvider(
        providers: [
          Provider<FlutterSecureStorage>(create: (_) => FlutterSecureStorage()),
          ChangeNotifierProxyProvider<FlutterSecureStorage, ListModel>(
            create: (_) {
              return ListModel.init(
                  Provider.of<FlutterSecureStorage>(_, listen: false));
            },
            update: (_, storage, listModel) => listModel..update(storage),
          ),
        ],
        child: MyHomePage('Todos app example'),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage(this.title);

  final String title;

  final TextEditingController eCtrl = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
        actions: <Widget>[
          Consumer2<ListModel, FlutterSecureStorage>(
              builder: (_, listModel, storage, __) => IconButton(
                    icon: Icon(Icons.save),
                    onPressed: () async {
                      await storage.write(
                          key: "todo", value: todoItemToJson(listModel._items));
                      print("save done");
                    },
                  ))
        ],
      ),
      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[
            Container(
              padding: EdgeInsets.all(10),
              child: Row(
                children: <Widget>[
                  Expanded(
                    child: TextField(
                      decoration: InputDecoration(
                        border: InputBorder.none,
                        hintText: 'Enter your ToDo item',
                      ),
                      controller: eCtrl,
                    ),
                  ),
                  Consumer<ListModel>(
                    builder: (_, listModel, __) => FlatButton(
                      child: Text('Add'),
                      onPressed: () {
                        if (eCtrl.text != '') {
                          Map<String, dynamic> item = {
                            'value': false,
                            'text': eCtrl.text
                          };
                          listModel.addItem(
                              TodoItem(item: eCtrl.text, checked: false));
                          eCtrl.clear();
                        }
                      },
                    ),
                  ),
                ],
              ),
            ),
            Center(
              child: Consumer<ListModel>(builder: (_, listModel, __) {
                var items = listModel.getItems;
                return Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Container(
                      height: 300,
                      child: ListView.builder(
                        itemCount: items.length,
                        itemBuilder: (BuildContext context, int idx) =>
                            Container(
                          padding: const EdgeInsets.all(5),
                          color: Colors.green,
                          child: Row(
                            children: <Widget>[
                              Checkbox(
                                  value: items[idx].checked,
                                  onChanged: (val) {
                                    listModel.toggleValue(idx, val);
                                  }),
                              Text(
                                items[idx].item,
                                style: TextStyle(
                                    fontSize: 21, color: Colors.white),
                              ),
                            ],
                          ),
                        ),
                      ),
                    ),
                  ],
                );
              }),
            ),
          ],
        ),
      ),
    );
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在我的场景中,哪个包更好 flutter_secure_storage 或 getx ? - Which package is better flutter_secure_storage or getx in my scenario? flutter_secure_storage中可以存储多少数据? - How much data can store in flutter_secure_storage? Flutter 找不到所需的 package flutter_secure_storage/linux/CMakeLists.txt:14 - Flutter A required package was not found flutter_secure_storage/linux/CMakeLists.txt:14 使用 flutter_secure_storage package 为 ios 创建构建存档时出现问题 - Problem creating a build archive for ios using flutter_secure_storage package Flutter - 为什么/flutter_secure_storage 是安全的? - Flutter - Why/How is flutter_secure_storage secure? 使用 flutter_secure_storage 保存数据的列表文本......这可能吗? - Save List Texst of data using flutter_secure_storage ... is it possible? flutter_secure_storage 究竟是什么以及它是如何工作的? - What is flutter_secure_storage exactly and how it works? 未找到在通道插件上写入方法的实现。it_nomads.com/flutter_secure_storage - No implementation found for method write on channel plugins.it_nomads.com/flutter_secure_storage MissingPluginException(未找到在通道插件上读取的方法的实现。it_nomads.com/flutter_secure_storage) - MissingPluginException(No implementation found for method read on channel plugins.it_nomads.com/flutter_secure_storage) flutter 中的 flutter_secure_storage 和 shared_prefrences 有什么区别? 为什么 flutter_secure_storage 更安全? - What are the differences between flutter_secure_storage and shared_prefrences in flutter? Why is flutter_secure_storage more secure?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM