티스토리 뷰
Flutter 앱 개발 중 사용자 설정이나 간단한 데이터를 로컬에 저장하고 싶을 때, Key-Value 저장 방식은 매우 간단하면서도 효과적인 솔루션입니다. 이 블로그에서는 Flutter에서 SharedPreferences를 사용해 Key-Value 데이터를 저장하고 불러오는 방법과 활용 사례를 소개합니다.
참고. Store key-value data on disk
Key-Value 저장이란?
Key-Value 저장은 데이터를 키와 값의 쌍으로 관리하는 간단한 방식입니다. 예를 들어, 사용자의 설정값을 저장할 때 "themeMode: dark"와 같은 구조로 데이터를 보관합니다. 이러한 방식은 다음과 같은 장점을 제공합니다:
- 빠른 데이터 접근: 데이터베이스보다 간단하고 빠른 액세스 가능.
- 가벼운 저장소: 소량의 데이터 저장에 적합.
- 구현의 간편성: 복잡한 데이터 구조 없이 간단히 구현 가능.
SharedPreferences란?
Flutter에서 Key-Value 저장을 구현하려면 SharedPreferences 패키지를 사용합니다. 이 패키지는 데이터를 간단히 로컬에 저장하고 다시 불러올 수 있는 인터페이스를 제공합니다.
SharedPreferences 설정
1. 패키지 추가
Flutter 프로젝트에 SharedPreferences를 사용하려면 pubspec.yaml에 의존성을 추가해야 합니다.
dependencies:
shared_preferences: ^2.0.15
그런 다음, 아래 명령어로 패키지를 설치합니다:
flutter pub get
SharedPreferences 사용 방법
1. 데이터 저장
SharedPreferences에 데이터를 저장하는 것은 매우 간단합니다. 예를 들어, themeMode
라는 키에 값을 저장하려면 다음과 같이 작성합니다:
import 'package:shared_preferences/shared_preferences.dart';
Future<void> saveThemeMode(String themeMode) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('themeMode', themeMode);
}
2. 데이터 읽기
저장된 데이터를 불러오려면 아래와 같이 구현합니다:
Future<String?> getThemeMode() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString('themeMode');
}
3. 데이터 삭제
특정 키에 해당하는 데이터를 삭제하거나 전체 데이터를 초기화할 수도 있습니다.
Future<void> removeThemeMode() async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove('themeMode');
}
Flutter 앱에서 SharedPreferences 활용하기
예제: 다크모드 저장 및 적용
간단한 테마 변경 기능을 구현해 보겠습니다. 사용자가 선택한 테마 모드를 저장하고, 앱 재실행 시 적용되는 예제입니다.
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ThemeSwitcher(),
);
}
}
class ThemeSwitcher extends StatefulWidget {
@override
_ThemeSwitcherState createState() => _ThemeSwitcherState();
}
class _ThemeSwitcherState extends State<ThemeSwitcher> {
bool isDarkMode = false;
@override
void initState() {
super.initState();
loadThemeMode();
}
Future<void> loadThemeMode() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
isDarkMode = prefs.getBool('isDarkMode') ?? false;
});
}
Future<void> toggleThemeMode() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
isDarkMode = !isDarkMode;
prefs.setBool('isDarkMode', isDarkMode);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('SharedPreferences 예제')),
body: Center(
child: Switch(
value: isDarkMode,
onChanged: (value) => toggleThemeMode(),
),
),
backgroundColor: isDarkMode ? Colors.black : Colors.white,
);
}
}
주요 사용 사례
- 사용자 설정 저장:
- 테마 모드, 언어 설정, 알림 옵션 등.
- 세션 관리:
- 로그인 상태, 사용자 토큰 등.
- 앱 상태 유지:
- 사용자가 앱을 닫았다가 다시 열 때 마지막 상태를 기억.
SharedPreferences 사용 시 주의사항
- 데이터 크기 제한: SharedPreferences는 소량의 데이터를 저장하는 데 적합하며, 대량 데이터는 데이터베이스를 사용하는 것이 좋습니다.
- 암호화 필요: 민감한 정보는 암호화를 통해 저장해야 보안이 강화됩니다.
- 비동기 처리: 모든 작업이 비동기로 처리되므로 적절한 에러 처리가 필요합니다.
결론
Flutter에서 Key-Value 저장 방식은 사용자 설정이나 간단한 데이터 저장에 매우 유용합니다. SharedPreferences는 이러한 작업을 쉽고 빠르게 구현할 수 있는 도구를 제공합니다. 위의 가이드를 참고하여 Flutter 앱에서 로컬 데이터를 효율적으로 관리해 보세요!
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Shared preferences demo',
home: MyHomePage(title: 'Shared preferences demo'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
@override
void initState() {
super.initState();
_loadCounter();
}
/// Load the initial counter value from persistent storage on start,
/// or fallback to 0 if it doesn't exist.
Future<void> _loadCounter() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
_counter = prefs.getInt('counter') ?? 0;
});
}
/// After a click, increment the counter state and
/// asynchronously save it to persistent storage.
Future<void> _incrementCounter() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
_counter = (prefs.getInt('counter') ?? 0) + 1;
prefs.setInt('counter', _counter);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'You have pushed the button this many times: ',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
'Flutter Cookbook' 카테고리의 다른 글
Flutter에서 Google Mobile Ads 통합하기: 광고 수익화의 모든 것 (2) | 2024.12.12 |
---|---|
Flutter에서 동영상 재생 기능 구현: `video_player` 플러그인을 활용한 완벽 가이드 (1) | 2024.12.11 |
Flutter로 파일 읽기 및 쓰기: 완벽 가이드 (0) | 2024.12.09 |
Flutter에서 SQLite 사용하여 데이터 영구 저장 구현하기 (1) | 2024.12.08 |
Flutter에서 백그라운드 데이터 파싱 구현하기: 효율적인 데이터 처리 방법 (0) | 2024.12.07 |