Flutter: Хранение данных приложения

На этом месте должна была быть статья по работу Flutter с SQLite, но не сложилось. Не умеет Flutter без плясок с бубном работать с SQLite одновременно на всех целевых платформах сразу: WIndows/Android/IOS. Самый популярный пакет sqflite — работает только на Android/IOS, остальные, задекларированные как рабочие под Windows, по оной так запустить мне и не удалось, с учётом что у меня ограниченные права Windows. Потому, стал смотреть в сторону пакета Hive — работающего на всех целевых платформах, т.к. написан изначально на языке Dart.

Hive -это быстрая локальная база для Flutter, Dart работающая на основе ключ-значение.

Установка: добавить в зависимости pubsec.yaml:

dependencies:
  hive: ^2.2.3

Для удобства можно написать маленький класс для работы с ключами-значениями:

import 'dart:io';
import 'package:hive/hive.dart';

class THave {
  String bname="";
  void Init(String basename)  {
    var path = Directory.current.path;
    Hive.init(path);
    bname=basename;
  }
  void Add(String key,var value) async {
    var box = await Hive.openBox(bname);
    await box.put(key, value);
  }
  void Delete(String key) async {
    var box = await Hive.openBox(bname);
    await box.delete(key);
  }
  dynamic  Get(String key) async  {
    var box =  await Hive.openBox(bname);
    return (box.get(key));
  }
  Future <Iterable> GetKeys() async {
    var box = await Hive.openBox(bname);
    return await box.keys;
  }
}

И теперь например можно при новом запуске приложения «вспоминать» авторизацию:

main.dart:

void main() {
  THave have=THave();
  have.Init("auth");
  have.Get("UserId").then((UserId){
    if (UserId!=null){
      globals.UserId=UserId;
    };
    have.Get("UserName").then((UserName){
      if (UserId!=null){
        globals.UserName=UserName;
        globals.is_login=true;
      };
      runApp(const MyApp());
    });
  });
}

login.dart:

                      onPressed: (){
                        http.post(Uri.parse('https://erfwe.ru/1.php'),body: {'login':_controller1.text,'password':_controller2.text}).then((response) {
                          print("Response status: ${response.statusCode}");
                          print("Response body: ${response.body}");
                          Map<String, dynamic> user = jsonDecode(response.body);
                          setState(() {
                            globals.UserName = user["UserName"];
                            globals.is_login = true;
                            globals.UserId = user["UserId"];
                            THave have=THave();
                            have.Init("auth");
                            have.Add("UserName", globals.UserName);
                            have.Add("UserId", globals.UserId);
                          });
                        }).catchError((error){
                          print("Error: $error");
                        });
                      },

Причем нужно отметить свойства сохранения и извлечения ключ-значение: при сохранении мы не ждем результата записи. При чтении — соответственно необходимо дождаться.

Flutter: работа с json

В предыдущей статье мы получили по URL json данные. Теперь задача их обработать.

{
"UserId":10,
"UserName":"Vasya Pukin"
}

Для работы с json, необходимо импортировать библиотеку:

import 'dart:convert';

Далее загрузим данные в тип Map:

 Map<String, dynamic> user = jsonDecode(response.body);
                        print (user["UserName"]);

А что если это массив?

[
  {"UserId":10,"UserName":"Vasya Pukin 1"},
  {"UserId":10,"UserName":"Vasya Pukin 2"}
  ]

В этом случае загрузим JSON в объет List:

                        List users = jsonDecode(response.body);
                        for(int i=0; i < users.length; i++){
                          print(users[i]["UserName"]);
                        }

Обратная конвертация:

                        String json = jsonEncode(user);
                        print (json);

Flutter: сканирование штрихкода

1. Добавим в pubspec.yaml зависимость

dependencies:
  flutter_barcode_scanner: ^2.0.0

Добавим в код предыдущего проекта:

class _Page1State extends State<Page1> { // _ впереди класса, означает чтоб скрыть доступ из других файлов
...
....
  String _scanBarcode = 'Unknown';
  Future<void> startBarcodeScanStream() async {
      FlutterBarcodeScanner.getBarcodeStreamReceiver(
          '#ff6666', 'Cancel', true, ScanMode.BARCODE)!
          .listen((barcode) => print(barcode));
  }
  Future<void> scanBar() async {
    String barcodeScanRes;
    try {
      barcodeScanRes = await FlutterBarcodeScanner.scanBarcode('#ff6666', 'Отменить', false, ScanMode.BARCODE);
      Fluttertoast.showToast(
          msg: "Прочитано:"+barcodeScanRes,
          toastLength: Toast.LENGTH_SHORT,
          gravity: ToastGravity.CENTER,
          timeInSecForIosWeb: 1,
          backgroundColor: Colors.red,
          textColor: Colors.white,
          fontSize: 16.0
      );
    } on PlatformException {
      barcodeScanRes = 'Ошибка получения версии платформы';
    }
    if (!mounted) return;
    setState(() {
      _scanBarcode = barcodeScanRes;
    });
  }
....
....
....
   ListTile(
                onTap: (){
                  print(scanBar());
                },
                leading: Icon(
                  Icons.sick,
                ),

Следует отметить, что при запуске кода на Android/IOS приложение самостоятельно попросит доступ к камере, а потому еще одной проблемой — обработкой запросов доступа меньше.

Flutter: использование пакетов

Не все йогурты одинаково полезны (с)

Иногда стандартных библиотек поставляемых с Fllutter не хватает, а самому что-то писать затруднительно — выходом может служить использование уже написанного и опакеченого кода. Все пакеты Flutter находятся на pub.dev, для добавления любого из пакетов с этого сайта в проект, достаточно добавить в pubspec.ymal проекта зависимость. Например:

dependencies:
  fluttertoast: ^8.0.9

После чего Android Studio предложит обновить зависимости. Далее добавим в main.dart импортируемую библиотеку:

import 'package:fluttertoast/fluttertoast.dart';

Далее непосредственное использование:

 ListTile(
                onTap: (){
                  Fluttertoast.showToast(
                      msg: "Здраствуйте я ваша дядя..",
                      toastLength: Toast.LENGTH_SHORT,
                      gravity: ToastGravity.CENTER,
                      timeInSecForIosWeb: 1,
                      backgroundColor: Colors.red,
                      textColor: Colors.white,
                      fontSize: 16.0
                  );
                },
1 8 9 10 11 12 72