문제 해결 목적
가계부를 사용하면 반복적으로 사용 되는 지출들이 있습니다.
월세, 통신, 렌탈 등등 이러한 지출들을 매달 같은 날짜에 입력하는 건 번거로운 일입니다.
그래서 이 기능을 구현했습니다.
문제 해결 과정
1. Timer
Flutter에는 Timer 클래스가 있습니다. 시간을 측정해서 원하는 시간에, 또는 특정 시간동안 반복적인 작업을 가능하게 하는 클래스입니다. 문제는 앱이 작동 중일 때만 시간이 흐르고 , 또 단기적인 시간은 정확하지만, 하루, 또는 일주일이 넘어가는 시간은 정확하지 않은 이슈가 있습니다. 그래서 사용하지 않기로 했습니다.
2. Work manager
https://aakashpp.medium.com/running-background-tasks-in-flutter-with-workmanager-fdb81e8244b1
위 패키지는 앱이 작동하지 않는 동안에도 백그라운드에서 시간을 체크하고 그 체크한 부분을 앱에게 직접적으로 기능을 활성화 할 수 있는 패키지입니다. 하지만 안드로이드에서는 정확하게 작동하지만 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");
// 에러 처리 로직 추가
}
}
결과
잘 실행이 되었습니다. 이 방법의 큰 문제점은 해당 날짜에 앱을 켜야만 데이터가 등록이 된다는 점입니다.
하지만.. 뭐 월 고정 지출을 등록할 때 안내를 하면 큰 문제는 없을 것 같습니다!!!
'Flutter-플러터 > 플러터 공부' 카테고리의 다른 글
Flutter bloc 공부 3 - Todo 앱 (0) | 2024.03.17 |
---|---|
Flutter Bloc 공부 2 Todo 어플 만들기 (0) | 2024.03.16 |
Flutter 앱 버전 체크해서 알람 만들기 (0) | 2024.02.23 |
Flutter - supabase를 활용한 가계부 백업 기능 구현 (1) | 2024.02.20 |
Flutter supabase Apple login 구현 (0) | 2024.02.11 |