見出し画像

TWSNMP開発日誌:TWSNMPは「SNMP 猫」で検索する話とモバイル版の内部データの仕組みに悩む

今朝は3時半から開発開始です。
TwitterにTWSNMPの名前を忘れた時に
「SNMP 猫」
で検索するという書き込みを見つけて嬉しくなって試してみました。
確かにTWSNMP関連の記事が沢山でてきます。
助手の猫たちが「わしらのおかげ」と言ってそうです。
さて、今朝はモバイル版でノードのデータをFlutterアプリの内部で扱う方法の考えるところから開始です。
登録したノードのデータはアプリも終了しても保存しておきたいので、
保存する仕組みも必要です。
ソフトウェアデザインの記事などに書いてあった

のパッケージを使うのがよさそうです。しかしデータが単純な数値や文字列ではないので、サンプルに書いてある情報だけではできません。
いくつかの情報をもつリストデータを保存する仕組みを探しました。
ありました、

JSONという文字列のデータにして、文字列のリストとして保存するという方法です。このサイトのコードを写経して何とかできたのですが、この説明だと内部のデータはProviderという仕組みを使って管理しています。
ソフトウェアデザインではちょっと古い仕組みと書いてありました。
新しいのはRiverpodという仕組みを使うらしいので、どうやって変更するのか1時間ぐらい悩みました。見つけたのが

です。

も参考にして変更してみました。
VSCode表示されるエラーはなくなりましたが、ちゃんと動作するかは、まだわかりません。
テストコードを書きたいところですが、今朝は時間切れです。

テスト前のソースコードは

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
import 'package:hooks_riverpod/hooks_riverpod.dart';

class Node {
  String name;
  String ip;
  String snmpMode;
  String community;
  String user;
  String password;
  String icon;

  Node(
    {
    this.name ='',
    this.ip ='', 
    this.snmpMode = '',
    this.community = '',
    this.user = '',
    this.password = '',
    this.icon = '',
  });

  /// Map型に変換
  Map toMap() => {
        'name': name,
        'ip': ip,
        'snmpMode': snmpMode,
        'community': community,
        'user': user,
        'password': password,
        'icon': icon,
      };

  /// JSONオブジェクトを代入
  Node.fromJson(Map json)
      : name = json['name'],
        ip = json['ip'],
        snmpMode = json['snmpMode'],
        community = json['community'],
        user = json['user'],
        password = json['password'],
        icon = json['icon'];
}

final countViewModel = ChangeNotifierProvider((_) => NodesProvider());

class NodesProvider with ChangeNotifier {
  // ノードリスト
  List<Node> nodes = [];

  NodesProvider() {
    syncDataWithProvider();
  }

  void initNodes() {
    nodes = [
      Node(
          name: 'node 1',
          ip: '192.168.1.1',
          snmpMode: 'v2c',
          community: 'public',
          icon: 'node'),
      Node(
          name: 'node 2',
          ip: '192.168.1.210',
          snmpMode: 'v2c',
          community: 'public',
          icon: 'node'),
    ];
  }

  void setInitialSharedPrefrences() {
    // 設定初期化
    initNodes();
    // sharedPreferencesに保存
    updateSharedPrefrences();
  }

  /// SharedPrefrences保存
  Future updateSharedPrefrences() async {
    // ①Map型変換→②Json形式にエンコード→③リスト化
    List<String> myNodes = nodes.map((n) => json.encode(n.toMap())).toList();

    SharedPreferences prefs = await SharedPreferences.getInstance();
    // ④保存
    await prefs.setStringList('nodes', myNodes);

    print('updateSharedPrefrences: $myNodes');
  }
  /// SharedPrefrences読み出し
  Future syncDataWithProvider() async {
    print('syncDataWithProvider');

    SharedPreferences prefs = await SharedPreferences.getInstance();
    // ①読み出し
    var result = prefs.getStringList('nodes');

    print('result:$result');

    // 読み出し確認
    if (result != null) {
      // ②デコード→③MapオブジェクトをClockModelに代入→④リストに変換
      nodes = result.map((f) => Node.fromJson(json.decode(f))).toList();
    } else {
      // 必要に応じて初期化
    }
  }
}

これでよいかどうかは明日のお楽しみです。

あと、ログ分析ツールTWLogAIANのマニュアルをZennの本にしてみました。昨日の夜、公開しました。

明日に続く

開発のための諸経費(機材、Appleの開発者、サーバー運用)に利用します。 ソフトウェアのマニュアルをnoteの記事で提供しています。 サポートによりnoteの運営にも貢献できるのでよろしくお願います。