본문 바로가기

Flutter-플러터/플러터 공부

Flutter - 가계부 월 고정 지출 반복적으로 입력 구현

반응형

 

 

문제 해결 목적 

 

 

가계부를 사용하면 반복적으로 사용 되는 지출들이 있습니다. 

 

월세, 통신, 렌탈 등등 이러한 지출들을 매달 같은 날짜에 입력하는 건 번거로운 일입니다. 

그래서 이 기능을 구현했습니다. 

 

문제 해결 과정

 

1. Timer 

 

Flutter에는 Timer 클래스가 있습니다. 시간을 측정해서 원하는 시간에, 또는 특정 시간동안 반복적인 작업을 가능하게 하는 클래스입니다. 문제는 앱이 작동 중일 때만 시간이 흐르고 , 또 단기적인 시간은 정확하지만, 하루, 또는 일주일이 넘어가는 시간은 정확하지 않은 이슈가 있습니다. 그래서 사용하지 않기로 했습니다. 

 

 

2. Work manager

https://aakashpp.medium.com/running-background-tasks-in-flutter-with-workmanager-fdb81e8244b1

 

Running Background Tasks in Flutter with WorkManager

In today’s fast-paced world, mobile applications have become an integral part of our daily lives. Whether it’s checking emails, social…

aakashpp.medium.com

 위 패키지는 앱이 작동하지 않는 동안에도 백그라운드에서 시간을 체크하고 그 체크한 부분을 앱에게 직접적으로 기능을 활성화 할 수 있는 패키지입니다. 하지만 안드로이드에서는 정확하게 작동하지만 IOS에서는 이러한 백그라운드 활동을 제한적으로 막아놨습니다. 

즉 매월 고정 지출이 안드로이드에서는 정확한 날짜에 반복적으로 이루어지지만 IOS에서는 정확한 날짜가 아닌 그 주 언젠가로 작동하게 됩니다. 이러한 부분은 유저에게 좋은 경험은 아니다라는 생각에 사용하지 않기로 했습니다. 

 

 

3. 반복문

 

그러면 어떻게 월 고정비용을 지출을 만들 수 있을지 고민을 해보았고, 다음과 같이 진행했습니다. 

 

1. 월고정 지출 클래스를, 기존의 클래스와 똑같이 만든다. 

2. 유저가 지출을 저장 할 때 월 고정 지출 저장 버튼을 누른다. 

3. 유저의 지출 데이터는 기존 지출 클래스로 저장, 그리고 월고정 지출 클래스로도 같이 저장이된다. 

4. 월 고정 지출 클래스에서는 스케쥴 함수를 만든다. 

  - 매일  월 고정 지출이 저장 된 시점의 day와 오늘 날짜의 day를 비교한다. 

  - 월 고정 지출이 저장 된 day가 5, 오늘 날짜가 5가 되었을 때 월 고정 지출의 db에 있는 데이터가 기존 지출 db로 들어간다. 

  - 어제 날짜와 비교해서 오늘 실행이 된 적이 있으면 더이상 실행 되지 않게 한다. 

 

 void scheduleMonthlyRepeatExpense() async {
    final box = GetStorage();
    try {
      // GetStorage에서 마지막 실행 날짜를 가져옴
      DateTime? lastExecutionDateString = box.read('lastExecutionDate') != null
          ? DateFormat("yyyy-MM-dd").parse(box.read('lastExecutionDate'))
          : null;

      DateTime? lastExecutionDate = lastExecutionDateString != null
          ? DateTime(
              lastExecutionDateString.year,
              lastExecutionDateString.month,
              lastExecutionDateString.day,
            )
          : null;

      // 현재 날짜를 가져옴
      DateTime currentDate =
          DateFormat("yyyy-MM-dd").parse(DateTime.now().toString());

      // GetStorage에 저장된 날짜가 없거나, 이전에 저장된 날짜와 현재 날짜가 다음 월인 경우에만 실행
      if (lastExecutionDate == null ||
          lastExecutionDate.day != currentDate.day) {
        // 데이터베이스에서 RepeatExpense 초기값 불러오기
        var repeatExpenses = await databaseHelper.getRepeatExpenses();

        // RepeatExpense 반복 처리
        for (var repeatExpense in repeatExpenses) {
          // repeatExpense의 createdTime을 DateTime으로 파싱
          DateTime createdTime =
              DateFormat('yyyy-MM-dd').parse(repeatExpense.createdTime);
          print("저장 된 월 고정비용 시간${createdTime}");

          // 오늘과 등록된 날짜의 년, 월, 일 값 비교
          if (currentDate.day == createdTime.day) {
            // RepeatExpense 정보를 ExpenseRecord로 옮기기
            ExpenseRecordItem expenseRecord = ExpenseRecordItem(
              id: const Uuid().v4(), // UUID 생성
              name: repeatExpense.name,
              incomeType: repeatExpense.incomeType,
              money: repeatExpense.money,
              createdTime: currentDate.toString(), // 현재 날짜 사용
              content: repeatExpense.content,
            );

            // 데이터 입력 함수 호출
            expenseRecords.add(expenseRecord);
            await databaseHelper.insertExpense(expenseRecord);

            print("반복데이터 가계부 데이터에 입력 완료");
            update();
          } else {
            print("반복 날짜와 다릅니다.");

            print("${currentDate.day}: ${createdTime.day}");
            print(" 저장 된 날 짜${lastExecutionDate}");
          }
        }

        // GetStorage에 현재 일 저장
        box.write('lastExecutionDate', currentDate.toString());
      } else {
        print("오늘 이미 실행되었습니다.");
      }
    } catch (e) {
      print("Error scheduling monthly repeat expenses: $e");
      // 에러 처리 로직 추가
    }
  }

 

 

 

결과

 

잘 실행이 되었습니다. 이 방법의 큰 문제점은 해당 날짜에 앱을 켜야만 데이터가 등록이 된다는 점입니다. 

하지만.. 뭐 월 고정 지출을 등록할 때 안내를 하면 큰 문제는 없을 것 같습니다!!!

 

728x90
반응형