2024. 12. 2. 08:33ㆍ같이 공부합시다 - Flutter/Flutter로 To-Do 앱 만들기
이제 앱을 종료해도 데이터가 유지되도록
저장 기능을 추가해 봅시다 : )
한층 더 진짜 서비스 앱처럼 나아가고 있죠? (ㅎ)
할 일 목록입니다. 😆
3 . 화면에 할 일 리스트 표시.4 . 할 일 삭제 기능 추가
5 . 데이터 저장 추가
6 . 항목 완료 체크 기능 추가
7 . 완료/미완료 분리 표시 및 필터 기능 추가
8 . 할 일 목록 수정 기능 추가
9 . 완료된 항목을 자동으로 삭제하는 옵션 추가
…
<할 일 목록>

등록한 할 일이 이렇게나 많은데 !
지금은 앱을 끄면 정보가 삭제되죠. 후~~

아니 될 말입니다. 당장 저장 기능을 추가하죠 !
온라인 서버를 사용하는 것이 좋겠지만,
당장은 로컬 저장소를 이용하도록 하겠습니다.
( 추후에는 Firebase 를 사용해보죠. 😅 )
자, 로컬에 저장하도록 구성하려면,
‘shared_preferences 라이브러리’를 사용하면 됩니다.
Flutter팀이 제공하는 패키지이며,
로컬 저장소에 간단한 데이터를
저장하고 불러오기 위한 도구예요.
1) 라이브러리 추가
라이브러리를 추가하려면,
pubspec.yaml 파일에 추가하면 됩니다.
<의존성 정보 추가>

의존성 정보를 추가하고 저장하면
자동으로 관련 라이브러리가 다운받아지네요.
<라이브러리 자동 추가 결과>

만약 추가되지 않았다면,
터미널에서 flutter pub get 명령어를 입력해 봅시다.
라이브러리 추가가 완료되었다면,
이제 우리 main 에서 사용하겠다고
선언해 줘야겠죠 : )
다시 main.dart 로 돌아와서,
제일 위쪽에 라이브러리를 추가해 봅시다.
<라이브러리 추가>

이렇게 라이브러리를
추가해 보는 것은 처음이네요.
좋은 경험이예요 (ㅎ)
하나씩 직접 해봐야 느는 겁니다 : )
자, 라이브러리 추가 완료 !
다음 !
<세이브와 로드 이미지>

저장 기능의 기본은
저장(Save)과 불러오기(Load)죠.
게임을 시작하면 저장된 진행 정보를
우선 로드해서 사용하잖아요?
앱도 똑같죠 뭐. (ㅎ)
먼저 세이브는 어떻게 하는지 봅시다 !
2) 세이브 호출 위치 정하기
세이브는 어디에서 할까요?
따로 저장 버튼을 만들어 두는 것 보다는,
할 일 목록을 ‘추가’하거나 ‘삭제’할 때
자동으로 저장되면 편하겠죠?
좋은 생각입니다 !
그럼 할 일을 추가하는 곳과
삭제하는 곳에 두면 되겠네요.
<세이브 메서드 호출 위치 설정>
// 할 일 추가 메서드
void _addTodoItem(String task) {
setState(() {
_todoList.add(task);
});
_saveTodoList(); // 로컬 저장소에 저장
}
// 할 일 삭제 메서드
void _deleteTodoItem(int index) {
setState(() {
_todoList.removeAt(index);
});
_saveTodoList(); // 로컬 저장소에 저장
}
이제 실제 저장하는 함수를 만들면 되겠네요.
3) _saveTodoList 메서드 만들기
<세이브 메서드>
// 로컬 저장소에 데이터를 저장하는 메서드
Future<void> _saveTodoList() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setStringList('todoList', _todoList);
}
// 할 일 추가 메서드
void _addTodoItem(String task) {
setState(() {
_todoList.add(task);
});
_saveTodoList(); // 로컬 저장소에 저장
}
// 할 일 삭제 메서드
void _deleteTodoItem(int index) {
setState(() {
_todoList.removeAt(index);
});
_saveTodoList(); // 로컬 저장소에 저장
}
Future는 언제 저장될 지 모르기 때문이고,
SharedPreferences.getInstance(); 는
라이브러리에서 제공하는 저장 객체를 가져오고,
가져온 객체를 prefs 변수에 담습니다.
이 때부터는 prefs를 저장 객체로 쓸 수 있어요.
저장 객체는 key & value 로 이루어진 객체이며,
저장하고 가져오는 기능이 포함되어 있어요.
prefs.setStringList('todoList', _todoList); 로
현재 ‘할 일 목록’(리스트)를 로컬 정보인
todoList 에 저장할 겁니다.
await 와 async 는 사용자의 호출,
그러니까 할 일을 추가하거나 삭제할 때까지
기다렸다가(await) 싱크(async)를
맞춘다고 보면 되겠네요.
좋아요! 메서드 완성!
바로 테스트를 해보고 싶지만,
아직 중요한 처리를 안했어요.
저장한 정보를 로드해 보려면
상태 정보를 먼저 초기화 해야 합니닷 !
다음 !
4) state 초기화 설정하기
자, 기존의 데이터가 있는지 로드하려고 합니다.
그런데 여기서 꼭 살펴 볼 내용이 있어요.
기존 데이터와 불러오는 데이터가 충돌되면 어쩌죠?
<저장된 데이터와 로드된 데이터가 충돌되는 모습>

사설이지만, 어렸을 적 게임을 하다보면
이전 세이브를 로드하는데 문제가 생겨서
세이브 데이터가 날아간 적도 있죠 ㅠ^ㅠ
(다시 처음부터 키워야 했답니다..)
이런 상황을 개발자들도 겪었었던 것 같아요.
그래서 아마 플러터에서도
‘초기화’하는 부분을 넣었을 겁니다.
우리는 지금 StatefulWidget을 사용중입니다.
상태값, 그러니까 ‘할 일 목록’이라는 리스트에,
할 일이 추가되거나 삭제되면 setState()를 통해
바로바로 상태를 체크하여 화면에 뿌려주죠.
따라서, StatefulWidget 의 State 가 있는
_TodoListScreenState 에서 초기화를 할 겁니다.
<초기화 메서드>
class _TodoListScreenState extends State<TodoListScreen> {
final List<String> _todoList = []; // 할 일 목록
@override
void initState() {
super.initState();
_loadTodoList(); // 앱 시작 시 로컬 저장소에서 데이터 로드
}
super.initState 로 초기화를 합니다.
그리고 초기화 후에 바로 저장되어 있는
할 일 리스트를 로드해 두면 되는거죠.
음? 그런데 void initState() 는
따로 호출하지 않아도 되는건가요?
아주 좋은 질문입니다!
initState() 는 State 클래스에서
제공하는 ‘생명주기 메서드’입니다.
결론만 말하면 자동으로 실행되는거죠.
하나 더 배웠네요. 좋습니다!
다음!
4) _loadTodoList 메서드 만들기
초기화하고 로드하는 메서드 호출도 바로 했어요.
그럼 저장된 데이터를 로드하는 메서드를 작성해야겠죠.
바로 갑시다!
<로드 메서드>
class _TodoListScreenState extends State<TodoListScreen> {
final List<String> _todoList = []; // 할 일 목록
@override
void initState() {
super.initState();
_loadTodoList(); // 앱 시작 시 로컬 저장소에서 데이터 로드
}
// 로컬 저장소에서 데이터를 불러오는 메서드
Future<void> _loadTodoList() async {
final prefs = await SharedPreferences.getInstance();
final List<String>? loadedList = prefs.getStringList('todoList');
if (loadedList != null) {
setState(() {
_todoList.addAll(loadedList);
});
}
}
세이브랑 비슷하쥬? 그렇습니다.
로드할 때에도 담아둘 수 있는 저장 객체가
있어야 하는 것이 눈에 들어오시죠? 굿굿!
저장 메서드에서 봤던 ‘todoList’는
로컬에 저장된 키워드라고 보시면 됩니다.
여기에 할 일 리스트가 저장되어 있는 거죠.
그 리스트를 로드 메서드가 호출되는 순간
가져와서 _todoList <List> 에 모두 담습니다.
바로 _todoList.addAll(loadedList) 내용이죠.
5) 테스트
여기까지 잘 따라 오셨습니다.
좋아요!
이제 테스트를 합시다.
Ctrl + F5 !! 뙇 !!
……..?
맙소사.
저는 오류가 있네요.
오류가 없으시다면 짝짝짝!
축하드립니다. 끝 ! 하셔도 됩니다.
하지만 저와 같은 빌드 오류가 난다?
그럼 더 따라 오시죠 ㅎㅎ
Error: Building with plugins requires symlink support.
허얼.
확인해보니 Windows 앱으로 띄우려면
따로 권한이 필요하다고 하네요.
자! 따라 오시죠!
<개발자 모드 허용 설정 띄우는 명령어>

<개발자 모드 오픈>

<팝업 확인>

<다시 정상 실행 완료>


이제 드디어 끝났습니다.
고생하셨습니다!
끝!
'같이 공부합시다 - Flutter > Flutter로 To-Do 앱 만들기' 카테고리의 다른 글
To-Do List 앱 Step 7. 완료/미완료 분리 표시 및 필터 기능 추가 (0) | 2024.12.04 |
---|---|
To-Do List 앱 Step 6. 항목 완료 체크 기능 추가 (0) | 2024.12.03 |
To-Do List 앱 Step 4. 할 일 삭제 기능 추가 (0) | 2024.11.28 |
To-Do List 앱 Step 3. 할 일 목록 보여주기 (2) | 2024.11.27 |
To-Do List 앱 Step 2-3. 다이얼로그 > 추가 텍스트 버튼 추가 (5) | 2024.11.26 |