TIL

이건선·2023년 7월 26일
0

Flutter

목록 보기
20/30
  1. Builder 로직을 ‘AddressBookBuilder()’로 분리

// 변경 후
body: AddressBookBuilder()

// 변경 전
        // FutureBuilder(
        //     future: controller.getAddressData(),
        //     builder: (context, snapshot) {
        //       if (snapshot.hasData) {
        //         controller.wallet.addressBookList.value = snapshot.data as List<AddressBookModel>;
        //         controller.refreshShowList();
        //         return Obx(() => controller.showAddressList());
        //       } else {
        //         return showLoadingFullPage(context);
        //       }
        //     },
        //   ),
          ,
  1. firebase와 연동 되어있는 future를 변경 ⇒ StorageManager.readData('userAddressBook')를 보게 함
...

    return FutureBuilder(

      // controller를 통해서 로컬 저장소의 데이터를 스냅샷으로 가져온다.
      future: controller.getAddressData(),

...
Future<List<AddressBookModel>> getAddressData() async {
    return await StorageManager.readData('userAddressBook') as Future<List<AddressBookModel>>;
  }
  1. 가져온 ‘snapshot’의 데이터를 보여준다는 것은 변하지 않았으므로 코드를 변경하지 않고 기존의 로직을 동일하게 사용 함
if (snapshot.hasData) {

          // settingAddressBookController의 addressBookList를 현재 snapshot.data로 변경한다.
          settingAddressBookController.wallet.addressBookList.value = snapshot.data as List<AddressBookModel>;

          // addressBookList의 데이터가 null이 아닌지 검증하고 비어있지 않다면 showList라는 빈 리스트에 item을 하나씩 채워넣는다. 그리고 새로고침한다.
          settingAddressBookController.refreshShowList();

          // showAddressList을 확인하고 ...List<Widget>.from(showList)을 통해 위젯으로 표시한다. 만약 showList가 비워져 있다면 비어있는 페이지를 표시한다.
          return Obx(() => settingAddressBookController.showAddressList());
        } else {

          // 그렇지 않다면 로딩 페이지를 반환한다.
          return showLoadingFullPage(context);
        }
  1. 데이터를 로컬에 저장하기 위해서 confirm 버튼의 로직을 변경

  2. confirm 버튼의 로직을 변경에 따른 문제점

    1. AddressBookModel id필드 문제
      AddressBookModel의 id필드는 firebase doc()의 아이디를 사용한다. ⇒ Uuid().v4()로 변경해서 해결함

    StorageManager

    class StorageManager {
      static saveData(String key, dynamic value) async {
        final prefs = await SharedPreferences.getInstance();
        if (value is int) {
          prefs.setInt(key, value);
        } else if (value is String) {
          prefs.setString(key, value);
        } else if (value is bool) {
          prefs.setBool(key, value);
        } else if (value is List<String>) {
          prefs.setStringList(key, value);
        } else {
          print("--> StorageManager error : Invalid Type");
          return false;
        }
        return true;
      }
    }
    • StorageManager 기능 설명 : 다양한 타입의 value를 받아서 올바른 저장 메서드를 사용가능하게 한다.

    저장소 변경에 따른 return 값 변경 문제

    기존 
    //AddressBookModel 객체
    ‘confirmNewAddress’ => return AddressBookModel.fromJson(result);
    
    변경 
    //bool
    StorageManager.saveData ⇒ return true

    이렇게 되므로써 하위 .then((result) {…} 로직 처리가 불가능 해짐

.then메서드를 사용하기 위해서 .saveData()메서드 내부에서 return을 변경해야함

  • StorageManager의 의존성을 낮추기 위해 StorageManager 실행 이전에 직렬화한다면…
    String toitemInfo = jsonEncode(itemInfo.toJson());
    • 실행 이전에 직렬화 함에 따라서 saveData메서드에 들어가는 인자값이 String으로 타입이 변환되며, AddressBookModel의 메서드를 실행시키지 못하게 됨.

    • 역직렬화해서 문제를 해결

    • String의 if문 분기로 빠진 후에 return값으로 AddressBookModel을 반환하게 함

      ...
      else if (value is String) {
            prefs.setString(key, value);
            var jsonMap = jsonDecode(value);
            AddressBookModel model = AddressBookModel.fromJson(jsonMap);
            print('String으로 타입이 빠지는지 확인합니다');
            print('model을 확인합니다. $model');
            return model;
      ...

      생각의 오류

      socket 통신처럼 하나의 키값에 여러개의 value가 들어있는것으로 생각함 ⇒ 그런데 그게 아니라 일반적인 key value의 방식이었다.


      해결 해야 할 문제들

    • futuer에서 StorageManager의 값을 감시하지 못한다.

    • StorageManager의 값을 리스트에 할당해야 한다.

profile
멋지게 기록하자

0개의 댓글