[Flutter] shared_preferences 사용하기

저우웅·2025년 11월 2일

Flutter

목록 보기
4/8

안녕하세요!
오늘은 저번 블로그에서 예고한 대로 todo app에 shared preferences를 적용해보겠습니다.


SharedPreferences란?

Flutter에서 SharedPreferences란 앱 내 작은 데이터를 영구적으로 저장하고 불러오는 데에 쓰이는 로컬 스토리지입니다.



특징

  • key-value 쌍 형태로 데이터 저장
  • 앱 껐다 켜도 데이터가 유지됨
  • 간단한 데이터만 저장 가능(문자열, 숫자, boolean 등)


localStorage(Web)와의 차이점


localStorage와 SharedPreferences는 간단한 데이터를 (거의)영구적으로 저장한다는 면에서는 같은 역할을 수행합니다.

하지만 환경이 다르기 때문에 몇 가지 차이점이 있는데요, SharedPreferences와 localStorage의 가장 큰 차이점은 플랫폼 기반 vs 브라우저 기반이겠죠.

SharedPreferences는 앱 삭제시까지 데이터가 유지되고, localStorage는 캐시나 쿠키 초기화시 삭제될 수 있습니다.

또한, localStorage는 문자열만 저장 가능합니다.

localStorage.setItem('count', '5')

숫자, 객체 등 다른 타입은 문자열로 변환 후 저장해야 합니다.


SharedPreferences는 int, double, bool, String 등 비교적 다양한 자료형을 저장할 수 있습니다. .

prefs.setInt('count', 5)

추가적으로 접근 방법에도 차이가 있습니다.

localStorage의 데이터는 브라우저의 메모리에 저장되는 반면, SharedPreferences의 데이터는 기기의 디스크에 저장됩니다. 따아서 입출력 방식도 파일 I/O기 때문에 비교적 느릴 수 있죠.

따라서, localStorage의 데이터에 접근할 때는 동기로 처리됩니다. 하지만 SharedPreferences의 경우에는 디스크에 접근해야 하기 때문에, 비동기 처리가 필요합니다.


// Future<?>: 비동기 함수

Future<void> saveUserName(String name) async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.setString('username', name);
  print('✅ 이름 저장 완료!: $name');
}

위 코드처럼 Flutter에서는 파일을 열 때, 파일에 쓸 때 비동기 처리를 해줍니다.


function saveUserName(name) {
  localStorage.setItem('username', name);
  console.log('✅ 이름 저장 완료!:', name);
}

반면 JS에서는 비동기 처리가 따로 필요 없습니다.


사용 방법

패키지 설치

먼저 pubspec.yaml 파일에 들어가서 패키지를 설치해줍니다.

https://pub.dev/packages/shared_preferences

해당 링크에서 버전 등을 확인한 후 복사해준 뒤, dependencies에 추가해줍니다.

dependencies:
  // 기타 코드
  shared_preferences: ^2.5.3

해당 코드 추가 후, flutter pub get 해주면 설치는 끝납니다.


import

패키지를 사용하려는 파일에 import 해주면 됩니다.

import 'package:shared_preferences/shared_preferences.dart';
// 변환용
import 'dart:convert';

제 todo app에서는 todo item의 필드가 id(int), title(String), done(bool)로 이루어진 객체이기 때문에, Json으로 변환하는 과정이 필요했습니다. 따라서 변환을 위한 dart:convert도 import해주었습니다.


데이터 저장하기

Future<void> _saveItems() async {
  final prefs = await SharedPreferences.getInstance();
  final jsonList = _items.map((item) => item.toJson()).toList();
  await prefs.setString('todo_items', jsonEncode(jsonList));
}

데이터를 저장하는 saveItems입니다. 비동기 + 데이터 저장 역할이기 때문에 Future<void>로 써줍니다. 직접 만든 객체(todo item)는 저장이 안되기 때문에, JSON으로 바꿔주는 과정이 필요합니다.

데이터 불러오기

Future<void> _loadItems() async {
  final prefs = await SharedPreferences.getInstance();
  final jsonString = prefs.getString('todo_items');
  if (jsonString != null) {
    final List decoded = jsonDecode(jsonString);
    setState(() {
      _items.clear();
      _items.addAll(decoded.map((e) => TodoItem.fromJson(e)));
      _nextId = _items.isEmpty
          ? 0
          : _items.map((e) => e.id).reduce((a, b) => a > b ? a : b) + 1;
      });
  }
}

loadItems에서는 todo item이 있으면 불러오고, 해당 JSON을 리스트로 decode한 뒤 객체로 바꾸어 items에 넣어줍니다. 추가로 다음 item에 들어갈 nextId를 준비해줍니다.


기존 함수인 addItem, removeItem, toggleDone 등의 하단에 saveItem을 추가해주어 데이터 추가 및 삭제 후 해당 상태를 저장되도록 하였습니다.



정리


오늘은 이렇게 Flutter의 SharedPreferences를 사용해보았습니다!

localStorage와 같은 역할을 수행하면서도 다른 점이 있는 게 흥미로웠습니다. 특히 localStorage를 사용할 때와는 다르게 SharedPreferences에서는 비동기 처리를 해주는 점이 포인트였네요. JS를 배우면서 어렵게 느껴졌던 비동기처리를 다시 만나니 반가웠습니다(...)

또, 객체를 JSON 형태로 바꾸고 다시 불러오는 과정을 다뤄보는 것도 신기했습니다.

다음에는 조금 재미있는 결과물을 들고 와보겠습니다. 감사합니다😇

profile
ㅠㅠ

1개의 댓글

comment-user-thumbnail
2025년 11월 10일

이 글을 읽기 전까지는 SharedPreferences는 그냥 로컬에 저장할 수 있는 라이브러리로만 인식하고 있었는데 localStorage와 비교했을때 어떤 장단점이 있는지 파악한뒤 다시 바라보니 새롭네요! 점점 애플리케이션이 완성되는걸 보니 다음이 더 기대됩니다!

답글 달기